部署到 Docker 时外部化 Spring Boot 属性 [英] Externalising Spring Boot properties when deploying to Docker

查看:39
本文介绍了部署到 Docker 时外部化 Spring Boot 属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的 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:

这篇关于部署到 Docker 时外部化 Spring Boot 属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆