部署到 Docker 时外部化 Spring Boot 属性 [英] Externalising Spring Boot properties when deploying to Docker
问题描述
在我的 Spring Boot 应用程序中,我想将属性外部化以在 Docker 容器中运行.首次部署时,当前位于 my-server/src/main/resources/application.yml
中的属性将按预期加载并由应用程序使用.一切正常.
但是,我的问题是我需要根据需要更新这些属性,因此我需要在 Docker 容器上访问一次 application.yml
文件.但是此时,在运行buildDocker
任务之前,它并没有包含在build/docker/
目录中,所以在第一次部署后不会被复制或访问.>
所以,我尝试的是将 Yaml 文件复制到 docker/
构建目录中,将其复制到一个可访问的目录 (/opt/meanwhileinhell/myapp/conf
),并使用 spring.config.location
属性将配置的位置传递到我的 Dockerfile 中的 Jar:
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 IMAGE CONFIGURATION
如果您希望 Spring 推荐的方式来启动 Spring Boot动力码头集装箱,这就是你发现的:
FROM openjdk:8-jdk-alpine音量/tmpARG JAR_FILE复制 ${JAR_FILE} app.jar入口点 ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
这意味着您的图像扩展了 openjdk,并且您的容器有自己的环境.如果您这样做,只需将要覆盖的内容声明为 环境属性 就足够了,Spring Boot 将获取它们,因为 环境变量优先于 yml 文件.
环境变量也可以在您的 docker 命令中传递,以使用您想要的配置启动容器.如果您想为 JVM 内存设置一些限制,请参阅下面的链接.
<小时>DOCKER 组合样本
这里有一个示例,说明我如何使用 docker compose 启动一个简单的应用程序环境.如您所见,我在此处将 spring.datasource.url
属性声明为环境变量,因此它会覆盖您在 application.yml
文件中的所有内容.>
版本:'2'服务:我的应用程序:图片:我的公司/我的应用程序:1.0.0容器名称:myapp取决于:- mysql环境:- SPRING_DATASOURCE_URL=jdbc:mysql://mysql:3306/myapp?useUnicode=true&characterEncoding=utf8&useSSL=false端口:- 8080:8080mysql:图像:mysql:5.7.19容器名称:mysql卷:-/home/docker/volumes/myapp/mysql/:/var/lib/mysql/环境:- MYSQL_USER=root- MYSQL_ALLOW_EMPTY_PASSWORD=是- MYSQL_DATABASE=我的应用程序命令:mysqld --lower_case_table_names=1 --skip-ssl --character_set_server=utf8
另见:
In my Spring Boot app I want to externalise the properties to run in a Docker container. When first deployed, the properties that are currently in my-server/src/main/resources/application.yml
are loaded and used by the application as expected. All works fine.
However, my problem is that I need these properties to be updatable as needed, so I need access to the application.yml
file once on the Docker container. But at this point, it's not included in the build/docker/
directory before running the buildDocker
task, so won't be copied over or accessible after first deployment.
So, what I have tried is to copy the Yaml file into the docker/
build directory, copy it to an accessible directory (/opt/meanwhileinhell/myapp/conf
), and use the spring.config.location
property to pass a location of the config to the Jar in my Dockerfile:
ENTRYPOINT ["java",
...
"-jar", "/app.jar",
"--spring.config.location=classpath:${configDirectory}"]
Looking at the Command running on the Docker container I can see that this is as expected:
/app.jar --spring.config.location=classpath:/opt/meanwhileinhell/myapp/conf]
However, when I update a property in this file and restart the Docker container, it isn't picking up the changes. File permissions are:
-rw-r--r-- 1 root root 618 Sep 5 13:59 application.yml
The documentation states:
When custom config locations are configured, they are used in addition to the default locations. Custom locations are searched before the default locations.
I can't seem to figure out what I'm doing wrong or misinterpreting, but probably more importantly, is this the correct way to externalise the config for this type of Docker scenario?
DOCKER IMAGE CONFIGURATION
If you look to the way Spring recommends to launch a Spring Boot powered docker container, that's what you find:
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"]
That means your image extends openjdk and your container has its own environment. If you're doing like that, it would be enough to declare what you want to override as environment properties and Spring Boot will fetch them, since environment variables take precedence over the yml files.
Environment variables can be passed in your docker command too, to launch the container with your desired configuration. If you want to set some limit for the JVM memory, see the link below.
DOCKER COMPOSE SAMPLE
Here you have an example of how I launch a simple app environment with docker compose. As you see, I declare the spring.datasource.url
property here as an environment variable, so it overrides whatever you've got in your application.yml
file.
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
See also:
- How do I pass environment variables to Docker containers?
- Limit JVM memory consumption in a Docker container
这篇关于部署到 Docker 时外部化 Spring Boot 属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!