许多人使用容器来包装他们的 Spring Boot 应用程序,而构建容器并不是一件简单的事情。这是针对 Spring Boot 应用程序开发人员的指南,容器对于开发人员来说并不总是一个好的抽象。它们迫使你去了解和思考低层次的问题。但是,有时可能会要求您创建或使用容器,因此了解构建块是值得的。在本指南中,我们旨在向您展示如果您面临需要创建自己的容器的前景,您可以做出的一些选择。
我们假设您知道如何创建和构建基本的 Spring Boot 应用程序。如果没有,请转到入门指南之一 ——例如,关于构建REST 服务的指南。从那里复制代码并练习本指南中包含的一些想法。
还有一个关于Docker的入门指南,这也是一个很好的起点,但它没有涵盖我们在此处介绍的选择范围或详细介绍它们。
一个基本的 Dockerfile
Spring Boot 应用程序很容易转换为可执行的 JAR 文件。所有的入门指南都是这样做的,你从Spring Initializr下载的每个应用程序都有一个构建步骤来创建一个可执行的 JAR。使用 Maven,你运行./mvnw install,使用 Gradle,你运行./gradlew build。运行该 JAR 的基本 Dockerfile 将如下所示,位于项目的顶层:
Dockerfile
FROM openjdk:8-jdk-alpine
VOLUME /tmp
ARG JAR_FILE
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]复制
JAR_FILE您可以作为命令的一部分传入docker(Maven 和 Gradle 不同)。对于 Maven,以下命令有效:
docker build --build-arg JAR_FILE=target/*.jar -t myorg/myapp .复制
对于 Gradle,以下命令有效:
docker build --build-arg JAR_FILE=build/libs/*.jar -t myorg/myapp .复制
一旦你选择了一个构建系统,你就不需要ARG. 您可以对 JAR 位置进行硬编码。对于 Maven,如下所示:
Dockerfile
FROM openjdk:8-jdk-alpine
VOLUME /tmp
COPY target/*.jar app.jar
ENTRYPOINT ["java","-jar","/app.jar"]复制
然后我们可以使用以下命令构建镜像:
docker build -t myorg/myapp .复制
然后我们可以通过运行以下命令来运行它:
docker run -p 8080:8080 myorg/myapp复制
输出类似于以下示例输出:
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.0.2.RELEASE)
Nov 06, 2018 2:45:16 PM org.springframework.boot.StartupInfoLogger logStarting
INFO: Starting Application v0.1.0 on b8469cdc9b87 with PID 1 (/app.jar started by root in /)
Nov 06, 2018 2:45:16 PM org.springframework.boot.SpringApplication logStartupProfileInfo
...复制
如果你想在镜像内部四处寻找,你可以通过运行以下命令在其中打开一个 shell(注意基础镜像没有bash):
docker run -ti --entrypoint /bin/sh myorg/myapp复制
输出类似于以下示例输出:
/ # ls
app.jar dev home media proc run srv tmp var
bin etc lib mnt root sbin sys usr
/ #
我们在示例中使用的 alpine 基础容器没有bash,所以这是一个ashshell。它具有一些但不是全部的特性bash。
如果你有一个正在运行的容器并且你想查看它,你可以通过运行docker exec:
docker run --name myapp -ti --entrypoint /bin/sh myorg/myapp
docker exec -ti myapp /bin/sh
/ #复制
传递给命令myapp的位置在哪里。如果您没有使用,docker 会分配一个助记名称,您可以从. 您还可以使用容器的 SHA 标识符而不是名称。SHA 标识符在输出中也可见。--namedocker run--namedocker psdocker ps
入口点
使用Dockerfile的exec 形式ENTRYPOINT,以便没有外壳包装 Java 进程。优点是java进程响应KILL发送到容器的信号。实际上,这意味着(例如)如果您docker run在本地使用图像,则可以使用CTRL-C. 如果命令行有点长,您可以COPY在运行之前将其提取到 shell 脚本中并放入映像中。以下示