Docker 中的 Spring Boot

Posted

技术标签:

【中文标题】Docker 中的 Spring Boot【英文标题】:Spring Boot in Docker 【发布时间】:2017-09-28 04:47:15 【问题描述】:

我正在学习如何将 Docker 与 Spring Boot 应用程序一起使用。我遇到了一个小障碍,我希望有人能看到这个问题。我的应用程序严重依赖于环境特定属性文件中设置的 @Value。在我的 /src/main/resources 我有三个属性文件

application.properties application-local.properties application-prod.properties

我通常使用以下方式启动我的应用程序: java -jar -Dspring.profiles.active=本地构建/libs/finance-0.0.1-SNAPSHOT.jar

并且读取“application-local.properties”并正常运行。但是,我正在使用这个 src/main/docker/DockerFile:

FROM frolvlad/alpine-oraclejdk8:slim
VOLUME /tmp
ADD finance-0.0.1-SNAPSHOT.jar finance.jar
RUN sh -c 'touch /finance.jar'
EXPOSE 8081
ENV JAVA_OPTS=""
ENTRYPOINT [ "sh", "-c", "java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /finance.jar" ]

然后我开始:

docker run -p 8081:80 用户名/reponame/finance -Dspring.profiles.active=本地

我收到我的@Values 未找到的错误: 原因:java.lang.IllegalArgumentException:无法解析值“$spring.datasource.driverClassName”中的占位符“spring.datasource.driverClassName”

但是,该值确实存在于 *.local 和 *.prop 属性文件中。

spring.datasource.driverClassName=org.postgresql.Driver

我需要做一些特别的事情才能被取走吗?

更新

根据 M. Deinum 的反馈,我将自己的初创公司更改为:

docker run -p 8081:80 用户名/reponame/finance -eSPRING_PROFILES_ACTIVE=本地

但这在我意识到订单很重要之前不起作用,所以现在运行:

docker run -e"SPRING_PROFILES_ACTIVE=test" -p 8081:80 用户名/reponame/finance

工作得很好。

【问题讨论】:

尝试将ENV SPRING_PROFILES_ACTIVE=local 添加到您的 Docker 文件中 -Dspring.profiles.active 显然对 docker 的作用很小。而是使用 -e 来传递环境变量。请改用-e SPRING_PROFILES_ACTIVE=local M. Deinum,如果您将此作为答案,我将很乐意接受。感谢您的帮助! 在我的情况下,问题在于启动应用程序的 Dockerfile 中的 CMD 字符串。我将配置文件存储在标准路径之外(不在资源文件夹中),因此在将-Dspring.config.location=/app/conf/ 添加到启动字符串后,问题就解决了。启动字符串变成了这样:CMD java -Dspring.config.location=/app/conf/ -jar lib/application.jar 【参考方案1】:

您可以使用 docker run 使用 Spring Profiles。使用 Spring 配置文件运行新创建的 Docker 映像就像将环境变量传递给 Docker 运行命令一样简单

$ docker run -e "SPRING_PROFILES_ACTIVE=prod" -p 8080:8080 -t springio/gs-spring-boot-docker

您还可以在 Docker 容器中调试应用程序。可以使用 JPDA Transport 来调试应用程序。因此,我们将容器视为远程服务器。要启用此功能,请在 JAVA_OPTS 变量中传递 java 代理设置,并在容器运行期间将代理的端口映射到 localhost。

$ docker run -e "JAVA_OPTS=-agentlib:jdwp=transport=dt_socket,address=5005,server=y,suspend=n" -p 8080:8080 -p 5005:5005 -t springio/gs-spring-boot-docker

资源链接: Spring Boot with Docker

Using spring profile with docker for nightly and dev build:

启动容器时只需设置环境变量 SPRING_PROFILES_ACTIVE。这将切换 Spring 应用程序的活动状态。

以下两行将在端口 8081 上启动最新的 Planets dev 构建,并在端口 8080 上启动 nightly 构建。

docker run -d -p 8080:8080 -e \"SPRING_PROFILES_ACTIVE=nightly\" --name nightly-planets-server planets/server:nightly
docker run -d -p 8081:8080 -e \"SPRING_PROFILES_ACTIVE=dev\" --name dev-planets-server planets/server:latest

这可以通过 CI 系统自动完成。开发服务器包含最新版本,每晚将每天部署一次...

【讨论】:

【参考方案2】:

有 3 种不同的方法可以做到这一点,正如 here 所解释的那样

    在 Dockerfile 中传递 Spring Profile 在 Docker 中传递 Spring 配置文件 运行命令 在 DockerCompose 中传递 Spring 配置文件

下面是一个 Spring Boot 项目 dockerfile 的示例

<pre>FROM java:8
ADD target/my-api.jar rest-api.jar
RUN bash -c 'touch /pegasus.jar'
ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom","-Dspring.profiles.active=dev","-jar","/rest-api.jar"]
</pre>

你可以使用docker run命令

docker run -d -p 8080:8080 -e "SPRING_PROFILES_ACTIVE=dev" --name rest-api dockerImage:latest

如果你打算使用 docker compose,你可以使用类似这样的东西

version: "3"
services:
  rest-api:
     image: rest-api:0.0.1
     ports:
       - "8080:8080" 
     environment:
       - "SPRING_PROFILES_ACTIVE=dev"  

更多的描述和例子可以找到here

【讨论】:

以上是关于Docker 中的 Spring Boot的主要内容,如果未能解决你的问题,请参考以下文章

Docker 中的 Spring Boot

Docker中的Spring Boot静态文件夹

Docker 容器中的 Spring Boot 资源

Spring Boot 无法读取 Docker 中的 application.properties

Docker 中的 Consul 和 Spring Boot 服务 - 不取消注册

Spring Boot无法连接到同一网络的docker中的mysql