Spring从docker添加环境变量
Posted
技术标签:
【中文标题】Spring从docker添加环境变量【英文标题】:Spring add enviornment variable from docker 【发布时间】:2020-04-04 11:21:18 【问题描述】:我是 Spring 和 Docker 的新手。
我使用 Gitlab 提供的默认模板创建了一个项目。
它带有一个预定义的 Dockerfile,我想在上面添加一些额外的环境变量,以便在我的 application.properties
中使用。
到目前为止,我所做的是在 DockerFile 中添加 MY_PROP
ENV 值,如下所示:
FROM maven:3-jdk-8-alpine
WORKDIR /usr/src/app
COPY . /usr/src/app
RUN mvn package
ENV PORT 5000
ENV MY_PROP testpropertyfromdocker
EXPOSE $PORT
CMD [ "sh", "-c", "mvn -Dserver.port=$PORT spring-boot:run" ]
像这样设置我的application.properties
:
test.prop=$MY_PROP
并尝试在基本的RestControntroller
中使用它:
@SpringBootApplication
@RestController
public class DemoApplication
@Value("$test.prop")
private String testProp;
@GetMapping("/")
String home()
return "My prop from docker: " + testProp;
public static void main(String[] args)
SpringApplication.run(DemoApplication.class, args);
但如果我尝试使用
构建我的 Docker 映像docker build -t demo .
失败了
java.lang.IllegalArgumentException: Could not resolve placeholder 'MY_PROP' in value "$MY_PROP"
我也尝试过直接在 IntelliJ 中运行项目而不构建 Docker 映像,但即使添加 .env
文件也会出现相同的错误。
如何将我的环境变量传递给我的 Spring 应用程序?
在 IDE 中调试时是否可以使用 .env
文件或类似文件,或者我是否必须构建映像才能运行项目?
PS:我不认为这是 Externalising Spring Boot properties when deploying to Docker 的重复,或者至少答案应该更完整,因为我没有设法让我的配置按预期工作。
编辑
我更新了我的pom.xml
以包含以下内容:
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.2.2.RELEASE</version>
<configuration>
<environmentVariables>
<MY_PROP>testfromappprops</MY_PROP>
</environmentVariables>
</configuration>
</plugin>
</plugins>
</build>
我创建了一个干净、构建和重新同步的 maven 项目,但即使通过 IDE 运行它仍然失败。
编辑 2 我更新 dmy DockerFile 以使用 java -jar:
FROM openjdk:8-jdk-alpine
VOLUME /tmp
ARG JAR_FILE
COPY $JAR_FILE app.jar
ENV MY_PROP testpropertyfromdocker
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
docker build -t demo .
命令行正在运行,但 docker run demo
给出以下输出:
Error: Invalid or corrupt jarfile /app.jar
另外,当从 IDE 运行时(“运行”按钮),我仍然有关于未找到环境变量的相同错误。
谢谢。
【问题讨论】:
【参考方案1】:我认为这与您运行应用程序的方式有关。
由于您是 Spring Boot 新手,让我们消除错误/确认代码的某些部分:
@Value("$test.prop")
好的
test.prop=$MY_PROP
in application.properties
OK,只要文件放在src/main/resources
或src/main/resources/config
ENV MY_PROP testpropertyfromdocker
in Dockerfile
也可以
现在,您的配置中的可疑之处在于您实际运行项目的方式。通常 mvn 包应该创建一个 docker 应用程序的 JAR(你应该为此使用 spring-boot-maven-plugin
)。但是当它这样做时,您应该使用以下命令运行工件:
java -jar <YOUR_ARTIFACT.JAR>
相反,您选择使用 maven 直接运行已编译的代码库。但是如果你想在 maven 插件中传播 env.variables 或系统属性,你应该指示插件这样做:
Here 是关于环境变量的部分
Here 是关于系统属性的部分
一般来说,这种方式更适合调试开发中的应用程序,而不是运行现成的工件(我更喜欢上面描述的带有java -jar
的选项)。
所以我怀疑无论它在什么环境中运行(使用 docker 或不使用 IDE)只要你以这种方式启动应用程序,env.变量不是“可用”的,所以 spring boot 只是看不到它们。
更新 1
要验证这一点,请确保此 env.即使没有弹簧,变量也无法真正访问:
转到带有@SpringBootApplication
注释的类的main
方法。
它通常包含一行正在运行的应用程序。但即使在此之前尝试打印该环境的值。带有System.getenv("MY_PROP")
的变量
【讨论】:
感谢您的回答。我已经更新了我的 pom.xml(请参阅我原始帖子中的编辑),但我仍然遇到同样的问题。我希望至少能够从 IDE 运行它。我不确定要按照您所说的使用 spring-boot 的工件来构建它的步骤? 我已经更新了我的答案并提供了一种方法来验证这个假设 你说得对,System.getenv("MY_PROP")
返回 null。所以这是一个 Spring 配置问题?关于为什么我无法访问我的环境变量的任何提示? (我正在网上搜索)。
不,它不是 spring 配置问题,它是传播 env 的问题。执行 spring-boot:run 目标时通过 spring-boot-maven-plugin 进行变量
baeldung.com/spring-boot-command-line-arguments 请阅读并尝试以这种方式传播 MY_PROPS 的值...【参考方案2】:
我认为应用程序的 application.properties 必须完整,因为日志显示您的应用程序无法读取 docker 文件。
一旦你正确定义了 application.properties,你就可以运行了:
$ docker run -e "SPRING_PROFILES_ACTIVE=prod" -p 8080:8080 -t springio/gs-spring-boot-docker
一个有用的指南是here
【讨论】:
在说“应用程序的 application.prop 必须完整”时不确定您在说什么。它是指application.properties
文件吗?如果是,怎么不完整?
是的,我的意思是 application.properties,我不确定你可以在 application.properties 中引用 docker 文件或他的一些道具以上是关于Spring从docker添加环境变量的主要内容,如果未能解决你的问题,请参考以下文章
使用 Docker 将环境变量传递给 Spring Boot 应用程序不起作用