Spring Boot with Docker

本指南将引导您完成构建码头工人?用于运行 Spring 引导应用程序的映像。我们从一个基本开始,并进行一些调整。然后我们展示了几个使用构建插件(用于 Maven 和 Gradle)而不是 .这是一个“入门”指南,因此范围仅限于一些基本需求。如果要构建用于生产用途的容器映像,则需要考虑许多事项,并且不可能在简短指南中涵盖所有事项。??Dockerfile????docker??

还有一个关于 Docker 的主题指南,它涵盖了我们在这里拥有的更广泛的选择,并且更详细。

您将构建什么

码头工人是一个具有“社交”方面的 Linux 容器管理工具包,允许用户发布容器镜像并使用其他人发布的容器镜像。Docker 映像是运行容器化进程的方法。在本指南中,我们为一个简单的 Spring 引导应用程序构建了一个。

你需要什么约15分钟最喜欢的文本编辑器或 IDEJDK 1.8或以后格拉德尔 4+或梅文 3.2+您也可以将代码直接导入到 IDE 中:弹簧工具套件 (STS)智能理念VSCode

如果您不使用 Linux 机器,则需要一台虚拟化服务器。如果您安装了VirtualBox,则Mac等其他工具可以为您无缝管理它。访问??boot2docker??VirtualBox的下载网站,然后选择适合您机器的版本。下载并安装。不要担心实际运行它。

您还需要码头工人,仅在 64 位计算机上运行。看https://docs.docker.com/installation/#installation了解有关为您的计算机设置 Docker 的详细信息。在继续操作之前,请验证是否可以从 shell 运行命令。如果使用 ,则需要先运行它。??docker????boot2docker??

从 Spring 初始化开始

你可以使用这个预初始化项目,然后单击生成以下载 ZIP 文件。此项目配置为适合本教程中的示例。

手动初始化项目:

导航到https://start.spring.io.此服务拉入应用程序所需的所有依赖项,并为您完成大部分设置。选择 Gradle 或 Maven 以及您要使用的语言。本指南假定您选择了 Java。单击“依赖关系”,然后选择“Spring Web”。单击生成。下载生成的 ZIP 文件,该文件是配置了您选择的 Web 应用程序的存档。

如果您的 IDE 集成了 Spring Initializr,则可以从 IDE 完成此过程。

您也可以从 Github 分叉项目,然后在 IDE 或其他编辑器中打开它。

设置 Spring 引导应用程序

现在,您可以创建一个简单的应用程序:

??src/main/java/hello/Application.java??

package hello;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;@SpringBootApplication@RestControllerpublic class Application { @RequestMapping(“/”) public String home() { return “Hello Docker World”; } public static void main(String[] args) { SpringApplication.run(Application.class, args); }}

该类被标记为 a 和 a ,这意味着它已准备好供 Spring MVC 用于处理 Web 请求。 映射到发送响应的方法。该方法使用 Spring Boot 的方法启动应用程序。??@SpringBootApplication????@RestController????@RequestMapping????/????home()????Hello World????main()????SpringApplication.run()??

现在我们可以在没有 Docker 容器的情况下运行应用程序(即在主机操作系统中):

如果您使用 Gradle,请运行以下命令:

./gradlew build && java -jar build/libs/gs-spring-boot-docker-0.1.0.jar

如果使用 Maven,请运行以下命令:

./mvnw package && java -jar target/gs-spring-boot-docker-0.1.0.jar

然后转到??本地主机:8080??以查看您的“Hello Docker World”消息。

容器化

Docker有一个简单的“Dockerfile”用于指定图像“图层”的文件格式。在 Spring 引导项目中创建以下 Dockerfile:

例 1.Dockerfile

FROM openjdk:8-jdk-alpineARG JAR_FILE=target/*.jarCOPY ${JAR_FILE} app.jarENTRYPOINT [“java”,”-jar”,”/app.jar”]

如果您使用 Gradle,则可以使用以下命令运行它:

docker build –build-arg JAR_FILE=build/libs/\*.jar -t springio/gs-spring-boot-docker .

如果使用 Maven,则可以使用以下命令运行它:

docker build -t springio/gs-spring-boot-docker .

此命令将生成映像并将其标记为 。??springio/gs-spring-boot-docker??

这个 Dockerfile 非常简单,但它是运行 Spring Boot 应用程序所需要的一切,没有任何多余的装饰:只有 Java 和一个 JAR 文件。该构建将创建一个 spring 用户和一个 spring 组来运行应用程序。然后(通过命令)将项目 JAR 文件复制到容器中,作为 ,在 中运行。使用 Dockerfile 的数组形式,以便没有 shell 包装 Java 进程。这??COPY????app.jar????ENTRYPOINT????ENTRYPOINT??关于 Docker 的主题指南将更详细地讨论此主题。

要减少雄猫启动时间?,我们曾经添加一个指向熵源的系统属性。这不再是必需的??/dev/urandom??JDK 8 或更高版本.

使用用户权限运行应用程序有助于降低某些风险(例如,请参阅:堆栈交换上的一个线程).因此,对 的一个重要改进是以非 root 用户身份运行应用程序:??Dockerfile??

例 2.Dockerfile

FROM openjdk:8-jdk-alpineRUN addgroup -S spring && adduser -S spring -G springUSER spring:springARG JAR_FILE=target/*.jarCOPY ${JAR_FILE} app.jarENTRYPOINT [“java”,”-jar”,”/app.jar”]

生成并运行应用程序时,可以在应用程序启动日志中看到用户名:

docker build -t springio/gs-spring-boot-docker .docker run -p 8080:8080 springio/gs-spring-boot-docker

请注意第一个日志条目中的:??started by????INFO??

:: Spring Boot :: (v2.2.1.RELEASE)2020-04-23 07:29:41.729 INFO 1 — [ main] hello.Application : Starting Application on b94c86e91cf9 with PID 1 (/app started by spring in /)…

此外,在 Spring Boot 胖 JAR 文件中,依赖项和应用程序资源之间存在清晰的分离,我们可以利用这一事实来提高性能。关键是在容器文件系统中创建层。这些层在构建时和运行时(在大多数运行时)都缓存,因此我们希望将最频繁更改的资源(通常是应用程序本身中的类和静态资源)分层在变化较慢的资源之后。因此,我们使用稍微不同的 Dockerfile 实现:

例 3.Dockerfile

FROM openjdk:8-jdk-alpineRUN addgroup -S spring && adduser -S spring -G springUSER spring:springARG DEPENDENCY=target/dependencyCOPY ${DEPENDENCY}/BOOT-INF/lib /app/libCOPY ${DEPENDENCY}/META-INF /app/META-INFCOPY ${DEPENDENCY}/BOOT-INF/classes /appENTRYPOINT [“java”,”-cp”,”app:app/lib/*”,”hello.Application”]

这个 Dockerfile 有一个参数,指向我们解压缩胖 JAR 的目录。要将参数与 Gradle 一起使用,请运行以下命令:??DEPENDENCY????DEPENDENCY??

mkdir -p build/dependency && (cd build/dependency; jar -xf ../libs/*.jar)

要将参数与 Maven 一起使用,请运行以下命令:??DEPENDENCY??

mkdir -p target/dependency && (cd target/dependency; jar -xf ../*.jar)

如果我们做对了,它已经包含一个包含依赖 JAR 的目录,以及一个包含应用程序类的目录。请注意,我们使用应用程序自己的主类:。(这比使用胖 JAR 启动器提供的间接寻址更快。??BOOT-INF/lib????BOOT-INF/classes????hello.Application??

分解 JAR 文件可能导致类路径顺序为运行时不同.一个行为良好且编写良好的应用程序不应该关心这一点,但如果依赖项没有得到仔细管理,您可能会看到行为变化。

如果使用 ,则需要先运行它,然后再使用 Docker 命令行或构建工具执行任何操作(它运行一个守护进程,在虚拟机中为您处理工作)。??boot2docker??

在 Gradle 构建中,您需要在 Docker 命令行中添加显式构建参数:

docker build –build-arg DEPENDENCY=build/dependency -t springio/gs-spring-boot-docker .

要在 Maven 中构建映像,可以使用更简单的 Docker 命令行:

docker build -t springio/gs-spring-boot-docker .

当然,如果您只使用 Gradle,则可以更改默认值 使默认值 与解压缩存档的位置相匹配。??Dockerfile????DEPENDENCY??

您可能希望使用构建插件,而不是使用 Docker 命令行进行构建。Spring Boot 支持使用自己的构建插件从 Maven 或 Gradle 构建容器。谷歌也有一个名为臂有Maven和Gradle插件。这种方法最有趣的地方可能是您不需要 .您可以使用与从 获取的相同的标准容器格式来生成映像。此外,它可以在未安装 docker 的环境中工作(在构建服务器中并不少见)。??Dockerfile????docker build??

默认情况下,默认构建包生成的映像不会以 root 用户身份运行应用程序。查看配置指南格拉德尔?或马文了解如何更改默认设置。

使用 Gradle 构建 Docker 镜像

您可以在一个命令中使用 Gradle 构建标记的 docker 映像:

./gradlew bootBuildImage –imageName=springio/gs-spring-boot-docker使用 Maven 构建 Docker 镜像

要快速入门,您可以运行 Spring 启动映像生成器,甚至无需更改您的(请记住,如果仍然存在,则忽略):??pom.xml????Dockerfile??

./mvnw spring-boot:build-image -Dspring-boot.build-image.imageName=springio/gs-spring-boot-docker

要推送到 Docker 注册表,您需要具有推送权限,默认情况下您没有推送权限。将映像前缀更改为您自己的 Dockerhub ID,并确保在运行 Docker 之前进行身份验证。??docker login??

推送后

示例中的 A 失败(除非您是 Dockerhub 的“springio”组织的一部分)。但是,如果更改配置以匹配自己的 docker ID,则应该会成功。然后,您将拥有一个新的标记的已部署映像。??docker push??

您不必向 docker 注册或发布任何内容即可运行本地构建的 docker 映像。如果你使用 Docker 构建(从命令行或从 Spring Boot),你仍然有一个本地标记的镜像,你可以像这样运行它:

$ docker run -p 8080:8080 -t springio/gs-spring-boot-dockerContainer memory limit unset. Configuring JVM for 1G container.Calculated JVM Memory Configuration: -XX:MaxDirectMemorySize=10M -XX:MaxMetaspaceSize=86381K -XX:ReservedCodeCacheSize=240M -Xss1M -Xmx450194K (Head Room: 0%, Loaded Class Count: 12837, Thread Count: 250, Total Memory: 1073741824)….2015-03-31 13:25:48.035 INFO 1 — [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http)2015-03-31 13:25:48.037 INFO 1 — [ main] hello.Application : Started Application in 5.613 seconds (JVM running for 7.293)

CF 内存计算器在运行时用于调整 JVM 的大小以适合容器。

然后,该应用程序可在??http://localhost:8080??(访问它,它说,“你好码头工人世界”)。

将 Mac 与 boot2docker 配合使用时,您通常会在启动时看到如下内容:

Docker client to the Docker daemon, please set: export DOCKER_CERT_PATH=/Users/gturnquist/.boot2docker/certs/boot2docker-vm export DOCKER_TLS_VERIFY=1 export DOCKER_HOST=tcp://192.168.59.103:2376

要查看应用程序,您必须访问 DOCKER_HOST 中的 IP 地址而不是本地主机 — 在这种情况下,https://192.168.59.103:8080,VM 的面向公众的 IP。

当它运行时,您可以在容器列表中看到,类似于以下示例:

$ docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES81c723d22865 springio/gs-spring-boot-docker:latest “java -Djava.secur…” 34 seconds ago Up 33 seconds 0.0.0.0:8080->8080/tcp goofy_brown

若要再次关闭它,可以使用上一个列表中的容器 ID 运行(你的 ID 会有所不同):??docker stop??

docker stop goofy_brown81c723d22865

如果您愿意,也可以在完成容器后删除容器(它保留在文件系统中的某个位置):??/var/lib/docker??

docker rm goofy_brown使用弹簧轮廓

使用 Spring 配置文件运行新创建的 Docker 映像就像将环境变量传递给 Docker run 命令(对于配置文件)一样简单:??prod??

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

您可以对配置文件执行相同的操作:??dev??

docker run -e “SPRING_PROFILES_ACTIVE=dev” -p 8080:8080 -t springio/gs-spring-boot-docker在 Docker 容器中调试应用程序

若要调试应用程序,可以使用JPDA 运输.我们将容器视为远程服务器。要启用此功能,请在变量中传递 Java 代理程序设置,并在容器运行期间将代理程序的端口映射到本地主机。跟JAVA_OPTS适用于 Mac 的 Docker,有一个限制,因为我们无法通过 IP 访问容器,没有黑魔法用法.

docker run -e “JAVA_TOOL_OPTIONS=-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 应用程序创建了一个 Docker 容器!默认情况下,Spring 引导应用程序在容器内的端口 8080 上运行,我们通过命令行将其映射到主机上的同一端口。??-p??

妩媚动人,让我感受到了大自然的神奇。

Spring Boot with Docker

相关文章:

你感兴趣的文章:

标签云: