一、背景
SpringBoot工程Docker多环境中使用同一个Jar包解决方案
二、原因
- bootstrap.yml配置如下,通过勾选profiles选定环境
spring:
profiles:
profiles: @activeEnv@ # 固定的,和profiles里面的标签一致
---
# 本地开发环境,每个环境复制一份
spring:
application:
name: svr-job-mgt # 服务名,改成自己的
#其他配置信息
config:
activate:
on-profile: dev # 环境标识,照抄
- pom.xml配置如下,可以发现打包后会把resources下所有资源打进jar包
<resources>
<resource>
<!-- 指定配置文件的位置 -->
<directory>src/main/resources</directory>
<includes>
<include>**/*</include>
</includes>
<!-- 开启替换标签,比如我们的'@env'就是通过这个替换的 -->
<filtering>true</filtering>
</resource>
</resources>
<!--环境-->
<profiles>
<profile>
<id>dev</id>
<properties>
<activeEnv>dev</activeEnv>
</properties>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<profile>
<id>prod</id>
<properties>
<activeEnv>prod</activeEnv>
</properties>
</profile>
</profiles>
- 我们使用的打包命令为:
mvn package -Dmaven.test.skip=true -Pdev
-D表示跳过单元测试的运行,-P指定打包环境
这就会导致一个问题,当我们从dev环境增加prod环境时,我们就得需要从新build我们的jar包,但是我们发现所有的jar包下配置文件是一样,唯一不一样的参数为
spring.profiles.profiles变成了我们当前的环境参数。
二、思考
- spring.profiles.profiles参数如何匹配到各种环境
- 项目docker容器化部署,我们能不能通过环境变量传参数
- resource下的配置文件如何获取到我们的docker环境变量
三、解决
- 更改spring.profiles.profiles的值。key-value可自定义
spring:
profiles:
profiles: ${ACTIVE_ENV}
- k8s或者docker增加环境变量
env:
- name: ACTIVE_ENV
value: prod
后续,通过测试发现,无需1和2操作,直接增加环境变量即可
env:
- name: spring.profiles.active
value: prod
- 打包时候无需指定环境:
mvn package -Dmaven.test.skip=true
4、其他可优化的部分
- 由于现在账号密码都放在配置文件下,导致账号密码都在代码中(不安全),后续可参考如上设置配置到启动环境中。
- 现在还面临的一个问题是当前环境配置文件被修改,还需要从新打包。
解决问题2:我们可以利用springboot读取配置文件的优先级:jar包所在目录 > resource。其他路径可自行查阅。暂时想到两种解决方案,采用方案一。
方案一:将宿主机上的任意位置文件或者目录挂载到容器中
方案二:也可以利用docker cp命令把本地文件传入到运行的容器中,然后docker commit生成新的镜像
方案一示例:将本地目录/data下配置文件挂载到我们的容器中/app目录下,app目录为app.jar所在目录
docker run ... -v /data/application-pore.yml:/app/application-prod.yml ...