在 Docker 中设置 Spring Boot Profile
1、简介
在容器化大行其道的今天,越来越多人选择把 Spring Boot 应用部署到 Docker 中。
本文将带你了解在 Docker 容器中启动 Spring Boot 应用时,如何设置其 Profile。
2、基本的 Dockerfile
一般来说,要容器化 Spring Boot 应用,只需提供一个 Dockerfile
。
Spring Boot 应用的最小 Dockerfile,如下:
FROM openjdk:11
COPY target/*.jar app.jar
ENTRYPOINT ["java", "-jar", "/app.jar"]
然后,可以通过 docker build 来构建 Docker 镜像:
docker build --tag=docker-with-spring-profile:latest .
接着,我们就可以通过 docker-with-spring-profile
镜像运行应用了:
docker run docker-with-spring-profile:latest
你可以注意到,Spring Boot 应用以 “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、在 Dockerfile 中设置 Profile
设置 Profile 的一种方法是使用 Spring Boot 的命令行参数:-Dspring.profiles.active
。
在 Dockerfile
的 ENTRYPOINT
行中添加了一个新参数 -Dspring.profiles.active=test
",将 Profile 设置为 test
:
//...
ENTRYPOINT ["java", "-Dspring.profiles.active=test", "-jar", "/app.jar"]
使用相同命令,再次运行容器:
docker run docker-with-spring-profile:latest
如你所见,Profile 为 test
,设置生效:
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、通过环境变量设置 Profile
在 Dockerfile
中使用硬编码的 Profile 并不灵活。如果我们有多个 Profile,在运行容器时需要选择其中一个,这就很麻烦。
有一个更好的方式,Spring Boot 在启动过程中会查找一个特殊的环境变量 SPRING_PROFILES_ACTIVE
。
因此,我们可以利用 docker run
命令在启动时设置 Spring Profile:
docker run -e "SPRING_PROFILES_ACTIVE=test" docker-with-spring-profile:latest
而且,还可以一次设置多个 Profile,通过逗号分隔:
docker run -e "SPRING_PROFILES_ACTIVE=test1,test2,test3" docker-with-spring-profile:latest
不过,需要注意,Spring Boot 的属性之间有 特定的顺序。命令行参数优先于环境变量。因此,为了让 SPRING_PROFILES_ACTIVE
生效,我们需要修改 Dockerfile
。
从 Dockerfile
的 ENTRYPOINT
行中删除 -Dspring.profiles.active=test
参数:
//...
ENTRYPOINT ["java", "-jar", "/app.jar"]
最后,我们可以看到通过 SPRING_PROFILES_ACTIVE
变量设置的 Profile 已经生效:
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、在 Docker Compose 文件中设置 Profile
另一种方法是在 docker-compose
文件中提供环境变量。
此外,为了更好地利用 docker run
操作,可以为每个 Profile 创建一个 docker-compose
文件。
为 test
Profile 创建一个 docker-compose-test.yml
文件:
version: "3.5"
services:
docker-with-spring-profile:
image: docker-with-spring-profile:latest
environment:
- "SPRING_PROFILES_ACTIVE=test"
同样,为 prod
Profile 创建另一个文件 docker-compose-prod.yml
,唯一不同的是第二个文件中的 Profile
为 prod
:
//...
environment:
- "SPRING_PROFILES_ACTIVE=prod"
现在,可以通过两个不同的 docker-compose
文件来运行容器:
# 'test' Profile
docker-compose -f docker-compose-test.yml up
# 'prod' Profile
docker-compose -f docker-compose-prod.yml up
6、总结
本文介绍了在以 docker 容器运行的 Spring Boot 应用中设置 Profile 的不同方法,并展示了使用 Docker 和 Docker Compose 的一些示例。
参考:https://www.baeldung.com/spring-boot-docker-start-with-profile