Dockerizing Spring Boot应用程序
1.概述
在本教程中,我们将重点介绍如何对 Spring Boot应用程序 在一个孤立的环境中运行,也称为。 容器.
我们将学习如何创建容器的组合,这些容器相互依赖,并在虚拟专用网络中相互链接。我们还将看到如何使用单个命令来管理它们。
让我们首先创建一个简单的SpringBoot应用程序,然后在运行的轻量级基础映像中运行 Alpine Linux.
2.Dockerize是一个独立的Spring Boot应用程序
作为一个可以dockerize的应用程序示例,我们将创建一个简单的Spring Boot应用程序, docker-message-server公开一个端点(endpoint)并返回静态消息:
@RestController
public class DockerMessageController {
@GetMapping("/messages")
public String getMessage() {
return "Hello from Docker!";
}
}
使用正确配置的Maven文件,我们可以创建一个可执行的jar文件:
$> mvn clean package
接下来,我们将启动Spring Boot应用程序:
$> java -jar target/docker-message-server-1.0.0.jar
现在我们有了一个工作的Spring Boot应用程序可以访问 localhost:8888/messages。
要对接应用程序,我们首先创建一个名为 Dockerfile文件内容如下:
FROM openjdk:8-jdk-alpine
MAINTAINER baeldung.com
COPY target/docker-message-server-1.0.0.jar message-server-1.0.0.jar
ENTRYPOINT ["java","-jar","/message-server-1.0.0.jar"]
此文件包含以下信息:
- FROM:作为我们镜像的基础,我们将 Java语言-已启用 Alpine Linux在上一节中创建。
- MAINTAINER:镜像的维护者。
- COPY:我们让 Docker 将我们的jar文件复制到镜像中。
- ENTRYPOINT:这将是容器启动时要启动的可执行文件。我们必须将它们定义为 JSON数组 因为我们将使用 ENTRYPOINT 与 CMD 作为某些应用程序参数。
要通过 Dockerfile文件创建一个镜像,我们需要像以前一样执行 'docker build':
$> docker build --tag=message-server:latest .
最后,我们可以从镜像中运行容器:
$> docker run -p8887:8888 message-server:latest
这将在Docker中启动我们的应用程序,我们可以在 localhost:8887/messages这里定义端口映射,它将主机(8887)上的端口映射到Docker内的端口(8888). 这是我们在Spring Boot应用程序的属性中定义的端口。
注意:端口8887可能在我们启动容器的机器上不可用。在这种情况下,映射可能不起作用,我们需要选择一个仍然可用的端口。
如果我们在分离模式下运行容器,我们可以检查其详细信息,停止它,然后使用以下命令将其删除:
$> docker inspect message-server
$> docker stop message-server
$> docker rm message-server
2.1.更改基础图像
为了使用不同的Java版本,我们可以轻松地更改基础映像。例如,如果我们想使用亚马逊的Corretto发行版,我们可以简单地更改 Dockerfile文件:
FROM amazoncorretto:11-alpine-jdk
MAINTAINER baeldung.com
COPY target/docker-message-server-1.0.0.jar message-server-1.0.0.jar
ENTRYPOINT ["java","-jar","/message-server-1.0.0.jar"]
此外,我们可以使用自定义的基础镜像。我们将在本教程后面介绍如何做到这一点。
3.在Composite中的Dockerize应用程序
Docker 命令和 Dockerfiles文件 特别适用于创建单独的容器。然而,如果我们想 在独立应用程序的网络上运行,容器管理很快变得混乱。
为了解决这个问题, Docker公司提供了一个名为 Docker Compose的工具. 此工具在中附带了自己的构建文件 YAML 格式,更适合管理多个容器。例如,它能够在一个命令中启动或停止服务的组合,或者将多个服务的日志输出合并输出到一个 伪终端(pseudo-tty).
3.1.第二个Spring Boot应用程序
让我们构建一个在不同Docker容器中运行的两个应用程序的示例。它们将相互通信,并作为“单个单元”呈现给主机系统。作为一个简单的示例,我们将创建第二个SpringBoot应用程序 docker-product-server:
@RestController
public class DockerProductController {
@GetMapping("/products")
public String getMessage() {
return "A brand new product";
}
}
我们可以使用相同的方式创建和启动它作为我们的 消息服务器.
3.2.Docker Compose文件
我们可以在一个名为 docker-compose.yml:
version: '2'
services:
message-server:
container_name: message-server
build:
context: docker-message-server
dockerfile: Dockerfile
image: message-server:latest
ports:
- 18888:8888
networks:
- spring-cloud-network
product-server:
container_name: product-server
build:
context: docker-product-server
dockerfile: Dockerfile
image: product-server:latest
ports:
- 19999:9999
networks:
- spring-cloud-network
networks:
spring-cloud-network:
driver: bridge
- version:指定应使用的格式版本。这是必填字段。这里我们使用较新的版本,而 传统格式 是“1”。
- services:此键中的每个对象定义一个 服务,又名容器。本节是强制性的。
- build:如果给定, docker-compose 能够从 Dockerfile文件创建一个镜像
- context:如果给定, 他指定了构建目录,并且在其中查找 Dockerfile文件。
- dockerfile:如果给定,他设置一个备用名称给Dockerfile。
- image:告诉我们 Docker 当使用构建功能时,它应该给镜像起什么名字。否则,它将在 库 或 远程注册表 中搜索此镜像。
- networks:这是要使用的命名网络的标识符。给定的名称-值必须列在网络部分
- build:如果给定, docker-compose 能够从 Dockerfile文件创建一个镜像
- networks:在本节中,我们将指定 网络可用于我们的服务. 在这个例子中,我们让 docker-compose 创建命名的 network 类型的 “桥” 。如果选项 external 设置为 true,它将使用具有给定名称的现有文件。
在继续之前,我们将检查构建文件中的语法错误:
$> docker-compose config
然后我们可以构建我们的图像,创建定义的容器,并在一个命令中启动它:
$> docker-compose up --build
这将启动 消息服务器 和 产品服务器 一气呵成。
要停止容器,并删除Docker 与 网络 的连接。为此,我们可以使用相反的命令:
$> docker-compose down
有关详细介绍 docker-compose, 我们可以阅读我们的文章 Docker Compose简介.
3.3.缩放服务
一个很好的功能 docker-compose 是 扩展服务的能力.例如,我们可以用 Docker 运行三个容器 消息服务器(message-server) 和两个容器 产品服务器(product-server).
然而,为了使其正常工作,我们必须删除 容器名称 来自我们的 docker-compose.yml所以 Docker 可以选择名称,并更改 暴露端口配置以避免冲突。
对于端口,我们可以告诉Docker将主机上的一系列端口映射到Docker中的一个特定端口:
ports:
- 18800-18888:8888
之后,我们可以这样扩展我们的服务(请注意,我们使用的是修改的 yml文件):
$> docker-compose --file docker-compose-scale.yml up -d --build --scale message-server=1 product-server=1
此命令将启动单个 消息服务器(message-server) 和一个 产品服务器(product-server).
要扩展我们的服务,我们可以运行以下命令:
$> docker-compose --file docker-compose-scale.yml up -d --build --scale message-server=3 product-server=2
此命令将启动 二 其他邮件服务器和 一 其他产品服务器。正在运行的容器不会停止。
4.自定义基础镜像
基本镜像(openjdk:8-jdk-alpine)到目前为止,我们使用的是已经安装了JDK 8的Alpine操作系统发行版。或者,我们可以构建自己的基础镜像(基于Alpine或任何其他操作系统)。
为此,我们可以使用Dockerfile文件以Alpine为基础镜像,并安装我们选择的JDK:
FROM alpine:edge
MAINTAINER baeldung.com
RUN apk add --no-cache openjdk8
- FROM:关键字 FROM告诉 Docker 使用带有标记的给定镜像作为构建基础。如果此镜像不在本地库中,请在线搜索 DockerHub或在任何其他配置的远程注册表上执行。
- MAINTAINER:通常是一个电子邮件地址,用于标识镜像的作者。
- RUN:使用 run 命令,我们正在目标系统中执行shell命令行。我们正在利用 Alpine Linux的 包管理器apk安装 Java 8 OpenJDK。
要最终构建镜像并将其存储在本地库中,我们必须运行:
docker build --tag=alpine-java:base --rm=true .
注意: 这个 -tag选项将给出镜像的名称,并且 -rm=true 将在构建成功后移除其中的镜像. 这个脚本最后的字符是一个点, 作为构建目录的参数
现在我们可以使用创建的镜像而不是 openjdk:8-jdk-alpine.
5.Spring Boot 2.3中的Buildpacks支持
Spring Boot 2.3增加了对内置包支持,简单地说,不需要创建我们自己的Dockerfile并使用类似 docker build,我们只需发出以下命令:
$ mvn spring-boot:build-image
同样,在Gradle:
$ ./gradlew bootBuildImage
为此,我们需要安装并运行Docker。
buildpacks背后的主要动机是创建一些知名云服务(如Heroku或cloud Foundry)已经提供了一段时间的部署体验。我们只是运行 生成镜像然后平台本身负责构建和部署工件。
此外,它可以帮助我们改变现状 更有效地构建Docker图像我们不需要对不同项目中的许多Dockerfile应用相同的更改,只需要更改或调整buildpacks图像生成器。
除了易于使用和更好的整体开发人员体验之外,它还可以更高效。例如,buildpacks方法将创建一个分层Docker图像,并使用Jar文件的分解版本。
让我们看看运行上述命令后会发生什么。
当我们列出可用的docker图像时:
docker image ls -a
我们看到我们刚刚创建的图像的一行:
docker-message-server 1.0.0 b535b0cc0079
这里,图像名称和版本与我们在Maven或Gradle配置文件中定义的名称和版本相匹配。哈希代码是图像哈希的简短版本。
然后,要启动我们的容器,我们可以简单地运行:
docker run -it -p9099:8888 docker-message-server:1.0.0
与我们构建的映像一样,我们需要映射端口,以便从Docker外部访问Spring Boot应用程序。
6.结论
在本文中,我们学习了如何构建自定义 Docker 图像,运行 Spring Boot应用程序 作为一个 Docker 容器,并使用 docker-compose.
有关构建文件的更多信息,请参阅官方 Docker reference 和 docker-compse.yml参考.
与往常一样,可以找到本文的源代码 在GitHub上.
- 本文标签: Cloud Docker Spring Boot
- 本文链接: https://www.v8en.com/article/279
- 版权声明: 本文由SIMON原创发布,转载请遵循《署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)》许可协议授权