Mea*_*ell 22 docker spring-boot dockerfile spring-boot-configuration
在我的Spring Boot应用程序中,我想要将属性外部化以在Docker容器中运行.首次部署时,my-server/src/main/resources/application.yml应用程序按预期加载和使用当前所属的属性.一切正常.
但是,我的问题是我需要这些属性可以根据需要更新,所以我需要application.yml在Docker容器上访问一次该文件.但此时,它build/docker/在运行buildDocker任务之前未包含在目录中,因此在首次部署后不会复制或访问.
所以,我试过的是将Yaml文件复制到docker/构建目录,将其复制到可访问的目录(/opt/meanwhileinhell/myapp/conf),并使用该spring.config.location属性将配置的位置传递给我的Dockerfile中的Jar:
ENTRYPOINT ["java",\
...
"-jar", "/app.jar",\
"--spring.config.location=classpath:${configDirectory}"]
Run Code Online (Sandbox Code Playgroud)
看看在Docker容器上运行的Command我可以看到这是预期的:
/app.jar --spring.config.location=classpath:/opt/meanwhileinhell/myapp/conf]
Run Code Online (Sandbox Code Playgroud)
但是,当我更新此文件中的属性并重新启动Docker容器时,它没有获取更改.文件权限是:
-rw-r--r-- 1 root root 618 Sep 5 13:59 application.yml
Run Code Online (Sandbox Code Playgroud)
该文件规定:
配置自定义配置位置时,除默认位置外,还会使用它们.在默认位置之前搜索自定义位置.
我似乎无法弄清楚我做错了什么或错误解释,但更重要的是,这是将这种类型的Docker场景的配置外部化的正确方法吗?
Xtr*_*ica 30
DOCKER IMAGE CONFIGURATION
如果你看一下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"]
Run Code Online (Sandbox Code Playgroud)
这意味着您的图像扩展了openjdk,您的容器也有自己的环境.如果您正在这样做,那么声明要覆盖的内容作为环境属性并且Spring Boot将获取它们就足够了,因为环境变量优先于yml文件.
环境变量也可以在docker命令中传递,以使用所需的配置启动容器.如果要为JVM内存设置一些限制,请参阅下面的链接.
DOCKER COMPOSE SAMPLE
这里有一个示例,说明如何使用docker compose启动简单的应用程序环境.如您所见,我将此spring.datasource.url属性声明为环境变量,因此它会覆盖您application.yml文件中的所有内容.
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
Run Code Online (Sandbox Code Playgroud)
也可以看看:
Raf*_*den 19
我个人会考虑两种选择:
每个配置使用一个环境变量
app:
image: my-app:latest
ports:
- "8080:8080"
environment:
SPRING_DATASOURCE_URL=jdbc:mysql://db:3306/table
Run Code Online (Sandbox Code Playgroud)使用 SPRING_APPLICATION_JSON
app:
image: my-app:latest
ports:
- "8080:8080"
environment:
SPRING_APPLICATION_JSON: '{
"spring.datasource.url": "jdbc:mysql://db:3306/table",
}'
Run Code Online (Sandbox Code Playgroud)Xtreme Biker答案的变体,这次是将 Spring Boot War 部署到 dockerized TomCat 中……
我建议application.yml在您的应用程序中包含一个标称值,但使用 Docker 环境变量来覆盖任何需要特定于环境的变化的单个键。
我推荐这种方法(使用 Docker 环境变量)的原因是:
Spring Boot 的外部化配置文档解释了两种通过命令行提供环境的方法:
SPRING_DATASOURCE_USERNAME=helloworld)-Dspring.datasource.username=helloworld)我更喜欢 Java 选项,因为它们表达了一个明确的意图:“这用于以下 Java 进程,并且仅用于该 Java 进程”。
最后:我将使用 TomCatCATALINA_OPTS作为传递这些 Java 选项的机制。文档来自catalina.sh:
(可选)执行“开始”、“运行”或“调试”命令时使用的 Java 运行时选项。包括在这里而不是在 JAVA_OPTS 中的所有选项,这些选项应该只由 Tomcat 本身使用,而不是由停止进程、版本命令等使用。示例是堆大小、GC 日志记录、JMX 端口等。
因为CATALINA_OPTS比让 Docker 镜像负责创建一个setenv.sh并将适当的 Docker env 声明传递给它更容易。
.war像这样构建你的人工制品:
./gradlew war
Run Code Online (Sandbox Code Playgroud)
我们期望.warGradle 将人工制品输出到build/libs/api-0.0.1-SNAPSHOT.war.
使用这样的 Dockerfile:
FROM tomcat:8.5.16-jre8-alpine
EXPOSE 8080
COPY build/libs/api-0.0.1-SNAPSHOT.war /usr/local/tomcat/webapps/v1.war
CMD ["catalina.sh", "run"]
Run Code Online (Sandbox Code Playgroud)
像这样构建你的 Docker 镜像:
FROM tomcat:8.5.16-jre8-alpine
EXPOSE 8080
COPY build/libs/api-0.0.1-SNAPSHOT.war /usr/local/tomcat/webapps/v1.war
CMD ["catalina.sh", "run"]
Run Code Online (Sandbox Code Playgroud)
CATALINA_OPTS像这样传递给你的容器:
docker build . --tag=my-api
Run Code Online (Sandbox Code Playgroud)
docker-compose 变体如下所示:
docker run -it \
-p 8080:8080 \
-e CATALINA_OPTS="\
-Dspring.datasource.url='jdbc:mysql://mydatabase.stackoverflow.com:3306' \
-Dspring.datasource.username=myuser \
" \
my-api
Run Code Online (Sandbox Code Playgroud)
就个人而言,我会使用Spring Cloud Config Server而不是尝试在整个地方设置属性文件.
tl; dr它允许您在集中位置的每个环境/配置文件级别保存git中的属性(允许版本控制,分支等),然后由REST提供.Spring Boot完全支持它; 实际上它只是另一个属性源,最终在您的环境中.
https://spring.io/guides/gs/centralized-configuration/
所以我设法让它工作。而不是将类路径传递到我的 DockerFile 中的目录:
"--spring.config.location=classpath:${configDirectory}"]
Run Code Online (Sandbox Code Playgroud)
我改为尝试传递文件的完整位置:
"--spring.config.location=file:${configDirectory}/application.yml"]
Run Code Online (Sandbox Code Playgroud)
现在,这会在 Docker 容器重新启动时更新。
您的方法绝对是一个可行的解决方案,但不推荐这样做,因为它使您的图像无法在不同的生产和开发环境之间移植。容器应该是不可变的,并且所有环境配置都应该被外部化。
对于 spring boot,有一个非常强大的项目,可以让你外部化配置。它叫做Spring Cloud Config。配置服务器允许您将特定于环境的配置保存在 git 存储库中,并将配置提供给需要它的应用程序。您基本上只需在 git 中保存相同的 application.yml 并将配置服务器指向存储库位置。
按照这种方法,您可以为不同的环境定义多个配置文件,并使您的 docker 容器保持不变。
| 归档时间: |
|
| 查看次数: |
37330 次 |
| 最近记录: |