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:11
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:
2022-04-22 22:34:25.268 INFO 1 --- [main] c.b.docker.spring.DemoApplication: Starting DemoApplication using Java 11.0.14.1 on ea8851bea75f with PID 1 (/app.jar started by root in /)
2022-04-22 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:
2022-04-22 22:39:33.210 INFO 1 --- [main] c.b.docker.spring.DemoApplication: Starting DemoApplication using Java 11.0.14.1 on 227974fa84b2 with PID 1 (/app.jar started by root in /)
2022-04-22 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:
2022-04-22 22:50:28.924 INFO 1 --- [main] c.b.docker.spring.DemoApplication: Starting DemoApplication using Java 11.0.14.1 on 18eacb6362f8 with PID 1 (/app.jar started by root in /)
2022-04-22T22: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.