Partner – Bellsoft – NPI (cat = Spring Boot/Docker)
announcement - icon

Just published a new writeup on how to run a standard Java/Boot application as a Docker container, using the Liberica JDK on top of Alpaquita Linux:

>> Spring Boot Application on Liberica Runtime Container.

Course – LS – All

Get started with Spring and Spring Boot, through the Learn Spring course:

>> CHECK OUT THE COURSE

1. Introduction

We all know how popular Docker is and how fashionable for Java developers it is to containerize their Spring Boot applications. However, how we set profiles in a dockerized Spring Boot application can be a question for some developers.

In this tutorial, we will explain how to start a Spring Boot application with profiles when it’s in a Docker container.

2. Basic Dockerfile

Generally, to dockerize a Spring Boot application, we simply provide a Dockerfile.

Let’s have a look at a minimal Dockerfile for our Spring Boot application:

FROM openjdk:17-jdk-alpine
COPY target/*.jar app.jar
ENTRYPOINT ["java", "-jar", "/app.jar"]

Surely, we can build our Docker image via docker build:

docker build --tag=docker-with-spring-profile:latest .

Thus, we can run our application from the image docker-with-spring-profile:

docker run docker-with-spring-profile:latest

As we notice, our Spring Boot application starts with the “default” profile:

2024-02-29 22:34:25.268 INFO 1 --- [main] c.b.docker.spring.DemoApplication: Starting DemoApplication using Java 17-ea with PID 1 (/app.jar started by root in /)
2024-02-29 22:34:25.270 INFO 1 --- [main] c.b.docker.spring.DemoApplication: No active profile set, falling back to 1 default profile: "default"
//...

3. Setting Profile in Dockerfile

One way to set a profile for our dockerized application is using Spring Boot’s command-line argument “-Dspring.profiles.active”.

So, to set the profile as “test”, we add a new argument, “-Dspring.profiles.active=test”, to our Dockerfile’s ENTRYPOINT line:

//...
ENTRYPOINT ["java", "-Dspring.profiles.active=test", "-jar", "/app.jar"]

To see the profile change, let’s run our container again with the same command:

docker run docker-with-spring-profile:latest

Accordingly, we can see the profile “test” is successfully picked up by our application:

2024-02-29 22:39:33.210 INFO 1 --- [main] c.b.docker.spring.DemoApplication: Starting DemoApplication using Java 17-ea with PID 1 (/app.jar started by root in /)
2024-02-29 22:39:33.212 INFO 1 --- [main] c.b.docker.spring.DemoApplication: The following 1 profile is active: "test"
//...

4. Setting Profile Using Environment Variables

Sometimes, it’s not convenient to use a hard-coded profile in our Dockerfile. If we need more than one profile, picking one of them could be cumbersome when we run our container.

Nevertheless, there’s a better alternative. During startup, Spring Boot looks for a special environment variable, SPRING_PROFILES_ACTIVE.

So, we can practically utilize this with the docker run command to set Spring profiles at startup:

docker run -e "SPRING_PROFILES_ACTIVE=test" docker-with-spring-profile:latest

Additionally, depending on our use case, we can set more than one profile at once via comma-separated strings:

docker run -e "SPRING_PROFILES_ACTIVE=test1,test2,test3" docker-with-spring-profile:latest

However, we should pay attention that Spring Boot has a particular order between properties. Command-line arguments have precedence over environment variables. For this reason, in order to make SPRING_PROFILES_ACTIVE work, we need to revert our Dockerfile.

Consequently, we remove the “-Dspring.profiles.active=test” argument from our Dockerfile’s ENTRYPOINT line:

//...
ENTRYPOINT ["java", "-jar", "/app.jar"]

Finally, we can see that the profiles we set via SPRING_PROFILES_ACTIVE are taken into account:

2024-02-29 22:50:28.924 INFO 1 --- [main] c.b.docker.spring.DemoApplication: Starting DemoApplication using Java 17-ea with PID 1 (/app.jar started by root in /)
2024-02-29T22:50:28.926562249Z 2022-04-22 22:50:28.926 INFO 1 --- [main] c.b.docker.spring.DemoApplication: The following 3 profiles are active: "test1", "test2", "test3"
//..

5. Setting Profile in Docker Compose File

As an alternative approach, environment variables can also be provided in a docker-compose file.

Additionally, to utilize our docker run operations in a better way, we can create a docker-compose file for each profile.

Let’s create a docker-compose-test.yml file for the “test” profile:

version: "3.5"
services:
  docker-with-spring-profile:
    image: docker-with-spring-profile:latest
    environment:
      - "SPRING_PROFILES_ACTIVE=test"

Similarly, we create another file, docker-compose-prod.yml, for the “prod” profile — the only difference is the profile “prod” in the second file:

//...
environment:
  - "SPRING_PROFILES_ACTIVE=prod"

Therefore, we can run our container via two different docker-compose files:

# for the profile 'test'
docker-compose -f docker-compose-test.yml up

# for the profile 'prod'
docker-compose -f docker-compose-prod.yml up

6. Conclusion

In this tutorial, we described different ways to set profiles in a dockerized Spring Boot application and also showed some examples both with Docker and Docker Compose.

Like always, all the code samples shown in this tutorial are available over on GitHub.

Course – LS – All

Get started with Spring and Spring Boot, through the Learn Spring course:

>> CHECK OUT THE COURSE
res – REST with Spring (eBook) (everywhere)
Comments are open for 30 days after publishing a post. For any issues past this date, use the Contact form on the site.