基于 docker 环境变量切换 spring 配置文件不起作用

Posted

技术标签:

【中文标题】基于 docker 环境变量切换 spring 配置文件不起作用【英文标题】:Switching spring profile based on docker environment variable does not work 【发布时间】:2019-06-11 23:21:12 【问题描述】:

docker-compose.yml:

services:
  server:
    image: server:latest
    environment:
    - SPRING_PROFILES_ACTIVE=dev
    ports:
    - 8080:8080
    - 18080:18080

Dockerfile:

FROM openjdk:8-jre-alpine

ENV SPRING_OUTPUT_ANSI_ENABLED=ALWAYS \
    SLEEP=0 \
    JAVA_OPTS="" \

RUN adduser -D -s /bin/sh server
WORKDIR /home/server

ADD entrypoint.sh entrypoint.sh
RUN chmod 755 entrypoint.sh && chown server:server entrypoint.sh
USER server

ENTRYPOINT ["./entrypoint.sh"]
# expose server ports
EXPOSE 8080 18080

ADD *.jar server.jar

entrypoint.sh:

#!/bin/sh

echo "The application will start in $SLEEPs..." && sleep $SLEEP
exec java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar "$HOME/server.jar" "$@"

我有 3 个 application.yml:application.ymlapplication-dev.ymlapplication-prod.yml,它们与数据库地址不同。

但是当我运行docker-compose up 时,服务器总是使用默认设置,即使我在 docker-compose.yml 中提到活动配置文件是 dev。

我想知道如何在 docker-compose 文件中启用不同的配置文件。 谢谢。

编辑: server.jar 文件是使用 gradle 的assemble 构建的。

【问题讨论】:

如果你在入口点回显环境变量,它会显示出来吗? 不,我什至无法启动我的应用程序,因为默认配置不提供数据库地址,这会在启动过程中引发异常。 entrypoint.sh 的第 3 行在您的 java 添加 $SPRING_PROFILE_ACTIVE 到 sh echo 的输出之前是否打印? 【参考方案1】:

添加命令:命名空间如下:

services:
  server:
    image: server:latest
    environment:
    - SPRING_PROFILES_ACTIVE=dev
    ports:
    - 8080:8080
    - 18080:18080
    command: --spring.profiles.active=prod

在您的容器运行后,这将被附加到您的入口点,并且 Spring Boot 将获取此配置文件。它将像这样执行:

Java -jar yourJar.jar --spring.profiles.active = prod.

如果您想在公司的各种环境中运行您的项目应用程序,并且为各种环境配置了不同的 kubernetes 集群,那么请在不同的 kubernetes 环境中为您的应用程序配置不同的设置。意味着在 qa environmner qa Kubernetes 集群中运行 docker 映像时将通过 --spring.profiles.active = qa 以及类似的 staging 和 Prod 集群。

即使你想使用你正在使用的环境变量,也要使用

exec java $JAVA_OPTS
-Dspring.profiles.active=your envronment variable name describe in docker compose -Djava.security.egd=file:/dev/./urandom -jar "$HOME/server.jar" "$@"

在 github 上查看: https://github.com/vaneetkataria/MicroService_Architecture/blob/master/docker-compose.yml

【讨论】:

谢谢。我从 JHipster 项目中复制了配置,所以我认为我可以构建项目而无需手动修改配置文件。 我尝试在撰写文件中添加command: --spring.profiles.active=dev,它在启动期间显示Unrecognized option: --spring.profiles.active=dev。如果我在撰写文件中仅使用环境- SPRING_PROFILES_ACTIVE=dev,则弹簧日志显示正确的配置文件名称,但不是正确的配置。它仍然使用application.yml文件中的默认数据库地址而不是application-dev.yml 您是否将 entrypoint.sh 脚本更改为 -Dspring.profiles.active=$SPRING_PROFILES_ACTIVE 在 -Djava.security.edg 之前?当您的容器入口点将执行时,它将选择此环境变量,其值将作为 syatem 属性在 java -jar 命令中传递。 附加 --spring.profiles.active=$SPRING_PROFILES_ACTIVE 在 entrypoint.sh 中的 java -jar 命令中也可以。因为在运行此启动应用程序时,这将作为运行时的属性。通过在 docker 容器控制台中发出 echo $SPRING_PROFILES_ACTIVE 确保您的环境变量在 docker 容器中正确设置。 好东西。谢谢【参考方案2】:

.yaml 文件的处理方式与 .properties 文件不同。

属性将查找名称中包含活动配置文件的文件: 应用程序-dev.properties 应用程序-prod.properties ...

yaml 文件,但是您将所有配置文件存储在由“---”分隔的单个文件中。

示例 [使用您现有的 docker-compose.yaml]:

application.yaml:

spring:    
  application:    
    your-application-name
  [other global application settings]    
  ...   

---
spring:
    profiles: dev    
[other settings which apply only to dev environment]


---
spring:
    profiles: prod
[all production settings (will overwrite other values if present]

【讨论】:

这不是真的,如果您愿意,您可以按照与属性相同的约定来分隔 yaml 文件。 谢谢达伦。我不知道。我无法让它为我工作,所以我按照我上面列出的方式进行了工作,它奏效了。我认为这正是 yaml 版本的工作方式。

以上是关于基于 docker 环境变量切换 spring 配置文件不起作用的主要内容,如果未能解决你的问题,请参考以下文章

基于 SAML 响应在 Grails 中分配 Spring 安全角色

Spring从docker添加环境变量

docker中,jdk用镜像 怎么配置环境变量

docker中,jdk用镜像 怎么配置环境变量

spring切换环境变量——@Profile注解的使用

使用 Docker 将环境变量传递给 Spring Boot 应用程序不起作用