如何在 docker run 命令中将 Java 选项/变量传递给 Spring Boot 应用程序
Posted
技术标签:
【中文标题】如何在 docker run 命令中将 Java 选项/变量传递给 Spring Boot 应用程序【英文标题】:How to pass Java options/variables to Springboot app in docker run command 【发布时间】:2019-11-10 20:30:48 【问题描述】:我有一个 Spring Boot 应用程序,它使用配置文件在不同的环境中进行配置。我想将此配置文件信息作为参数传递给我的docker run
命令。我该怎么做?
这是我的 dockerfile
FROM openjdk:8-jdk-alpine
ARG JAR_FILE=target/demo-app-1.0-SNAPSHOT.jar
COPY $JAR_FILE /opt/lib/demo-app.jar
EXPOSE 80
# ENTRYPOINT ["java","-Dspring.profiles.active=dockerdev","-jar","/opt/lib/demo-app.jar"]
# Above line works, but not desired as profile will change in diff envs
ENTRYPOINT ["java","-jar","/opt/lib/demo-app.jar"]
我尝试了以下方法,但没有一个有效
docker run -p 8000:80 demo-app -Dspring.profiles.active=dockerdev
docker run -p 8000:80 demo-app --rm -e JAVA_OPTS='-Dspring.profiles.active=dockerdev'
请帮忙。
澄清:我正在使用多个配置文件。因此,我不希望在应用程序或 docker 文件中提及活动配置文件。相反,我想使用相同的应用程序和 docker 文件并在不同的环境中运行它,并传递要在 docker run 命令中使用的活动配置文件。如果以上任何内容没有澄清这一点,我们深表歉意。
【问题讨论】:
你试过使用环境变量SPRING_PROFILES_ACTIVE
吗?
【参考方案1】:
您必须在 docker 文件中提供 JAVA_OPTS,下面是 docker 文件的示例。
FROM env "DOCKER_REGISTRY" /asdf/osX-jre8: env "BASE_IMAGE_VERSION"
ADD target/yourapp.jar /app.jar
#Environment vars
ENV NO_PREFIX true
ENV APP_NAME "xxx"
ENV APP_UUID "81b35e09-2a10-48c3-a091-xxxxxxxxx"
ENV HEALTH_CHECK_URL http://localhost:9000/health
ENV SERVICE_PORT 8080
ENV JAVA_OPTS "-Dsun.net.client.defaultConnectTimeout=2000 -Dsun.net.client.defaultReadTimeout=20000 -XX:+PrintGC -XX:+PrintGCTimeStamps -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/alloc/logs"
【讨论】:
对不起,如上所述,我不想在 docker 文件中提及这一点。否则,我需要为每个运行它的环境创建一个单独的 docker 文件【参考方案2】:解决方案 1
您可以使用 -e
选项将配置中的任何属性传递给 docker 容器,从而覆盖任何属性。如Externalized configuration
中所述,环境变量名称应大写并使用下划线分隔。因此,例如要传递spring.profiles.active
属性,您可以在容器运行期间使用SPRING_PROFILES_ACTIVE
环境变量:
docker run -p 8000:80 -e SPRING_PROFILES_ACTIVE=dockerdev demo-app
这个变量应该由 Spring 从环境中自动选取。
解决方案 2
将 Dockerfile 更改为:
FROM openjdk:8-jdk-alpine
ARG JAR_FILE=target/demo-app-1.0-SNAPSHOT.jar
# environment variable with default value
ENV SPRING_PROFILE=dev
COPY $JAR_FILE /opt/lib/demo-app.jar
EXPOSE 80
#run with environment variable
ENTRYPOINT ["java","-Dspring.profiles.active=$SPRING_PROFILE","-jar","/opt/lib/demo-app.jar"]
然后通过环境变量运行容器:
docker run -p 8000:80 --rm -e SPRING_PROFILE=dockerdev demo-app
【讨论】:
谢谢,michalk 和@Chrylis。 SPRING_PROFILES_ACTIVE 解决方案确实有效。但是,解决方案 #1,设置 $JAVA_OPTS 不起作用。我更新了你提到的 docker 文件,然后使用了以下命令:docker run -p 8000:80 demo-app --rm -e JAVA_OPTS='-Dspring.profiles.active=dockerdev'
,但它无法获取 JAVA_OPTS。我哪里错了?
解决方案 1 看起来很干净,可以轻松更新为动态
@TechiRik 您应该接受答案或指出是否需要更多帮助。
ENTRYPOINT ["java","-Dspring.profiles.active=$SPRING_PROFILE","-jar","/opt/lib/demo-app.jar"] 不起作用对我来说,在我摆脱 [] 之前,它不会扩展 $SPRING_PROFILE【参考方案3】:
在 springboot 中使用application.properties 来覆盖来自外部的任何变量。我们在生产环境中大量使用它。
你需要:
将您的ENTRYPOINT
更改为:
ENTRYPOINT ["java","-jar","/opt/lib/demo-app.jar","--spring.config.additional-location=/application.properties"]
创建包含内容的application.properties
文件:
spring.profiles.active=dockerdev
您还可以使用 application.properties
覆盖 springboot 代码中使用的任何变量,还可以覆盖 here 中提到的 springboot 特定变量。
docker run
命令更改为:
docker run -itd -v /path/to/application.properties:/application.properties image-name
这样您主机的application.properties
就会被挂载
在您的 docker 容器内。
注意:如果--spring.config.additional-location
不起作用,请尝试--spring.config.location
选项。
希望这会有所帮助。
【讨论】:
【参考方案4】:您应该将环境变量 JAVA_OPTS 添加到您的 Dockerfile 中
FROM tomcat:8.5.47-jdk8-openjdk
LABEL build_date="2020-07-14" \
name="Ousama EL IDRISSI" \
version="1.0" \
description="Docker Image made by la7ya"
EXPOSE 8080
COPY ./target/la7yaman-0.0.1-SNAPSHOT.war /usr/local/tomcat/webapps/ROOT.war
ENV JAVA_OPTS="-Dspring.profiles.active=docker-demo"
CMD ["catalina.sh", "run"]
【讨论】:
【参考方案5】:寻找非 Spring(纯 Java 应用程序)答案的人
这是发送系统属性/参数的方法:将 Dockerfile 更改为
FROM openjdk:8-jdk-alpine
COPY target/demo-app-1.0-SNAPSHOT.jar demo-app.jar
EXPOSE 8080
ENTRYPOINT java -jar demo-app.jar
构建镜像:
docker build -t demo-app .
然后使用以下命令运行 docker 容器:
docker run -e "JAVA_TOOL_OPTIONS=-Xms1024m -Xmx2048m -Dspring.profiles.active=dockerdev" -p 8080:8080 demo-app
【讨论】:
【参考方案6】:JAVA_TOOL_OPTIONS 可能是正确的答案。
docker run -p 8000:80 -e JAVA_TOOL_OPTIONS='-Dspring.profiles.active=dockerdev' demo-app
【讨论】:
以上是关于如何在 docker run 命令中将 Java 选项/变量传递给 Spring Boot 应用程序的主要内容,如果未能解决你的问题,请参考以下文章
如何从 Docker 'run' 命令设置 Spring Boot 属性
在 GitLab CI/CD 作业中将环境变量传递给 docker run 返回无效的参考格式?
如何在 circleci 作业中执行“docker run”命令