在我的Spring Boot应用程序中,我想外部化属性以在Docker容器中运行。首次部署时,my- server/src/main/resources/application.yml应用程序将按预期加载和使用当前所在的属性。一切正常。
my- server/src/main/resources/application.yml
但是,我的问题是我需要根据需要更新这些属性,因此我需要application.yml在Docker容器上访问一次文件。但是在这一点上,它build/docker/在运行buildDocker任务之前未包含在目录中,因此在第一次部署后将不会被复制或访问。
application.yml
build/docker/
buildDocker
因此,我尝试将Yaml文件复制到docker/build目录,将其复制到可访问目录(/opt/meanwhileinhell/myapp/conf),然后使用该spring.config.location属性将配置的位置传递给Dockerfile中的Jar:
docker/
/opt/meanwhileinhell/myapp/conf
spring.config.location
ENTRYPOINT ["java",\ ... "-jar", "/app.jar",\ "--spring.config.location=classpath:${configDirectory}"]
查看在Docker容器上运行的命令,我可以看到这与预期的一样:
/app.jar --spring.config.location=classpath:/opt/meanwhileinhell/myapp/conf]
但是,当我更新此文件中的属性并重新启动Docker容器时,它并没有接受更改。文件权限为:
-rw-r--r-- 1 root root 618 Sep 5 13:59 application.yml
该文档指出:
配置自定义配置位置后,除默认位置外还将使用它们。在默认位置之前搜索自定义位置。
我似乎无法弄清楚自己在做什么错或误解,但更重要的是,这是将这种Docker场景的配置外部化的正确方法吗?
DOCKER图像配置
如果您查看Spring建议启动由Spring Boot驱动的Docker容器的方式,那么您会发现:
FROM openjdk:8-jdk-alpine VOLUME /tmp ARG JAR_FILE COPY ${JAR_FILE} app.jar ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
这意味着您的映像扩展了openjdk,并且容器具有自己的环境。如果这样做的话,就足以声明要覆盖的内容,因为 环境属性 和Spring Boot会获取它们,因为环境变量优先于yml文件。
也可以在docker命令中传递环境变量,以使用所需的配置启动容器。如果要为JVM内存设置一些限制,请参见下面的链接。
DOCKER组成样本
这里有一个示例,说明了如何使用docker compose启动一个简单的应用程序环境。如您所见,我在spring.datasource.url此处将属性声明为环境变量,因此它将覆盖application.yml文件中的所有内容。
spring.datasource.url
version: '2' services: myapp: image: mycompany/myapp:1.0.0 container_name: myapp depends_on: - mysql environment: - SPRING_DATASOURCE_URL=jdbc:mysql://mysql:3306/myapp?useUnicode=true&characterEncoding=utf8&useSSL=false ports: - 8080:8080 mysql: image: mysql:5.7.19 container_name: mysql volumes: - /home/docker/volumes/myapp/mysql/:/var/lib/mysql/ environment: - MYSQL_USER=root - MYSQL_ALLOW_EMPTY_PASSWORD=yes - MYSQL_DATABASE=myapp command: mysqld --lower_case_table_names=1 --skip-ssl --character_set_server=utf8