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/resourcessrc/main/resources/config ENV MY_PROP testpropertyfromdocker in Dockerfile 也可以

现在,您的配置中的可疑之处在于您实际运行项目的方式。通常 mvn 包应该创建一个 docker 应用程序的 JAR(你应该为此使用 spring-boot-maven-plugin)。但是当它这样做时,您应该使用以下命令运行工件: java -jar &lt;YOUR_ARTIFACT.JAR&gt;

相反,您选择使用 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添加环境变量的主要内容,如果未能解决你的问题,请参考以下文章

dockerfile 容器添加 环境变量

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

Spring Cloud+Docker创建微服务容器实例

基于 docker-compose 环境变量将文件添加到 docker 容器

从 Docker 容器中获取环境变量

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