1. 概述
我们都知道Docker的流行程度,以及它对于Java开发者将Spring Boot应用容器化的重要性。然而,如何在Docker化的Spring Boot应用中设置环境变量可能对一些开发者来说是个问题。
在这篇教程中,我们将解释如何在Docker容器中的Spring Boot应用中启动带有配置项的实例。
2. 基本Dockerfile
通常,将Spring Boot应用Docker化,我们只需提供一个Dockerfile
。
让我们看看我们Spring Boot应用的最小Dockerfile
示例:
FROM openjdk:17-jdk-alpine
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"
配置启动:
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. 在Dockerfile中设置配置项
为我们的Docker化应用设置配置项的一种方法是使用Spring Boot的命令行参数"-Dspring.profiles.active"
。
因此,为了设置配置项为"test"
,我们需要在Dockerfile
的ENTRYPOINT
行中添加新的参数"-Dspring.profiles.active=test"
:
//...
ENTRYPOINT ["java", "-Dspring.profiles.active=test", "-jar", "/app.jar"]
为了观察配置项的变化,我们再次使用相同的命令运行容器:
docker run docker-with-spring-profile:latest
相应地,我们可以看到"test"
配置被成功应用于我们的应用:
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. 使用环境变量设置配置项
有时,在Dockerfile
中硬编码配置项并不方便。如果我们需要多个配置,每次运行容器时选择其中一个可能会变得繁琐。
然而,有一个更好的选择。在启动时,Spring Boot会查找一个特殊的环境变量SPRING_PROFILES_ACTIVE
。
因此,实际上,我们可以利用docker run
命令在启动时设置Spring配置项:
docker run -e "SPRING_PROFILES_ACTIVE=test" docker-with-spring-profile:latest
此外,根据我们的应用场景,我们可以通过逗号分隔的字符串一次设置多个配置项:
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
设置的配置项被考虑在内:
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. 在Docker Compose文件中设置配置项
作为另一种方法,我们也可以在docker-compose
文件中提供环境变量。
此外,为了更好地利用docker run
操作,我们可以为每个配置创建一个docker-compose
文件。
让我们为"test"
配置创建一个docker-compose-test.yml
文件:
version: "3.5"
services:
docker-with-spring-profile:
image: docker-with-spring-profile:latest
environment:
- "SPRING_PROFILES_ACTIVE=test"
同样,我们为"prod"
配置创建另一个文件docker-compose-prod.yml
——第二个文件的区别在于第二个文件中包含"prod"
配置:
//...
environment:
- "SPRING_PROFILES_ACTIVE=prod"
因此,我们可以通过两个不同的docker-compose
文件运行我们的容器:
# 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. 总结
在这篇教程中,我们描述了在Docker化的Spring Boot应用中设置配置项的不同方法,并展示了使用Docker和Docker Compose的一些示例。
一如既往,本文中的所有代码示例都可在GitHub上找到。