Docker化的Spring Boot 应用程序

x33g5p2x  于2021-10-20 转载在 Spring  
字(7.0k)|赞(0)|评价(0)|浏览(408)

在本文中,您将学习如何构建用于运行 Spring Boot 应用程序的 docker 镜像。我先给大家简单介绍一下 docker,然后我们会为我们的 Spring Boot 应用程序创建一个 docker 镜像,并在本地运行它。最后,我们将 docker 镜像推送到 docker hub。

让我们开始吧!

Docker 快速介绍

Docker 是一个软件平台,使开发人员能够在 容器 的帮助下在任何地方开发、发布和运行应用程序。

现在容器到底是什么,docker 用容器解决了什么问题?

好吧,让我们通过问几个问题来理解这一点。您是否对以下任何内容感到熟悉?

“它在我的机器上运行!!”
*
“我认为你的 Tomcat 版本 已经过时了!
*
“我不想在能够运行您的应用程序之前安装 10 个不同的库和工具。难道它不能以 打包形式 提供它需要的所有库和工具吗?”
*
“我们有使用不同语言、工具、系统库和环境编写的应用程序。有没有办法让我们在相同的基础设施上独立运行它们?”

我敢打赌其中一些确实如此。

Docker 通过创建应用程序的轻量级、独立、可执行包来解决这些问题,其中包含运行它所需的一切,包括代码、运行时、库、工具、环境和配置。

这些独立的可执行包称为 docker 镜像。一个正在运行的 docker 镜像实例称为 docker 容器

现在,这些容器镜像可以在任何环境中的任何地方共享、运送和运行。无论它们运行的​​环境如何,它们的行为都将完全相同。

此外,您可以在同一基础架构上运行多个配置完全不同的容器。所有容器都是完全隔离的,并且彼此独立运行。

很酷,不是吗?好吧,现在让我们学习如何在 docker 容器中运行 Spring Boot 应用程序。但在此之前,请继续在您的平台上install docker community edition
另请阅读:What is a Container and What is the difference between Containers and Virtual Machines

使用 Docker 的 Spring Boot:Dockerizing 一个 Spring Boot 应用程序

1. 将应用程序下载到 Dockerize

在本文中,我们将使用 Spring Boot 构建一个基于 Web 套接字的群聊应用程序。您可以从 github 下载该应用程序 -

$ git clone https://github.com/callicoder/spring-boot-websocket-chat-demo

Heroku 上有此应用程序的现场演示。如果你好奇,就去看看吧。您还可以阅读教程以了解如何从头开始构建它。

好的!现在让我们学习如何创建这个 Spring Boot 应用程序的 docker 镜像。

2. 使用 Dockerfile 定义 docker 镜像

转到应用程序的根目录并创建一个名为 Dockerfile 的新文件。

$ cd spring-boot-websocket-chat-demo
$ touch Dockerfile

Dockerfile 是我们定义 docker 镜像并指定运行应用程序所需的所有配置的地方。以下是我们的 Spring Boot 应用程序的 Dockerfile -

# Start with a base image containing Java runtime
FROM openjdk:11

# Add Maintainer Info
LABEL maintainer="callicoder@gmail.com"

# Add a volume pointing to /tmp
VOLUME /tmp

# Make port 8080 available to the world outside this container
EXPOSE 8080

# The application's jar file
ARG JAR_FILE=target/websocket-demo-0.0.1-SNAPSHOT.jar

# Add the application's jar to the container
ADD ${JAR_FILE} websocket-demo.jar

# Run the jar file 
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/websocket-demo.jar"]

Dockerfile 非常简单且具有声明性。让我们浏览 Dockerfile 的每一行并了解详细信息。

FROM:一个 docker 镜像可以使用 docker 注册表中的另一个可用镜像作为其基础或父镜像。在上面的例子中,我们使用 openjdk:11 图像作为我们的基础图像。
*
LABELLABEL 指令用于向图像添加元数据。在上面的 Dockerfile 中,我们通过 LABEL 指令添加了一些关于图像 maintainer 的信息。
*
VOLUME:卷是一种机制,用于将容器生成的数据保存在主机操作系统上,并与容器共享主机操作系统中的目录。

VOLUME 指令在具有指定路径的容器上创建一个挂载点。当您运行容器时,您可以指定给定挂载点将映射到的热操作系统上的目录。之后,容器写入挂载路径的任何内容都会写入主机操作系统上的映射目录。

卷最常见的用例之一是将容器生成的日志文件存储在主机操作系统上。例如,假设您的应用程序将日志文件写入一个位置 /var/log/app.log

您可以在 Dockerfile 中挂载一个路径为 /var/logVOLUME,然后在运行容器时指定此挂载点将映射到的 Host OS 上的目录。之后,您将能够从主机操作系统上的映射目录访问日志。

在上面的 Dockerfile 中,我们创建了一个路径为 /tmp 的挂载点,因为这是 Spring Boot 应用程序默认为 Tomcat 创建工作目录的地方。虽然这个 spring boot 应用程序不需要它,因为谁在乎 tomcat 目录。但是如果你想存储像 tomcat 访问日志这样的东西,那么 VOLUMES 是非常有用的。

您可以从 official documentation 了解有关 Volumes 的更多信息。
*
EXPOSE:顾名思义,这条指令允许你将某个端口暴露给外界。
*
ARGARG 指令定义了一个带有 defa 的变量终极值。您可以通过在构建时传递变量来覆盖变量的默认值。

ARG <name>[=<default value>]

一旦定义,变量就可以被它后面的指令使用。
*
ADDADD 指令用于将新文件和目录复制到 docker 镜像。
*
ENTRYPOINT:您可以在此处配置应用程序在容器内的执行方式。

3. 构建 Docker 镜像

现在我们已经定义了 Dockerfile,让我们为我们的应用程序构建一个 docker 镜像。

在构建 docker 镜像之前,您需要确保您已经使用 maven 将应用程序打包为 jar 文件的形式。可以在项目根目录下输入以下命令进行打包——

$ mvn clean package

上述命令在项目的target目录下创建了一个jar文件。

现在让我们通过键入以下命令来构建 docker 镜像 -

$ docker build -t spring-boot-websocket-chat-demo .

就是这样。您现在可以使用以下命令查看系统上所有 docker 镜像的列表 -

$ docker image ls

REPOSITORY                        TAG                 IMAGE ID            CREATED             SIZE
spring-boot-websocket-chat-demo   latest              30ad8958ac67        22 hours ago        126MB
openjdk                           8-jdk-alpine        224765a6bdbe        3 months ago        102MB

这应该会显示我们新建的 docker 镜像。

4. 运行 docker 镜像

一旦你有了一个 docker 镜像,你就可以像这样使用 docker run 命令运行它 -

$ docker run -p 5000:8080 spring-boot-websocket-chat-demo

run 命令中,我们已经指定容器上的端口 8080 应该映射到主机操作系统上的端口 5000

应用程序启动后,您应该可以通过 http://localhost:5000 访问它。

容器在前台运行,按 CTRL + C 将停止它。现在让我们看看如何在后台运行容器。

在后台以分离模式运行 docker 镜像。

您可以使用 docker run 命令中的 -d 选项在后台运行容器 -

$ docker run -d -p 5000:8080 spring-boot-websocket-chat-demo
1c3528715862a8a8efb712c85bc8ab61f3419c04eb6dc613af76c89846d316e0

上面的命令在后台启动容器并为您提供容器 ID。您可以使用以下命令查看系统中运行的所有容器的列表 -

$ docker container ls

CONTAINER ID        IMAGE                             COMMAND                  CREATED              STATUS              PORTS                            NAMES
1c3528715862        spring-boot-websocket-chat-demo   "java -Djava.securit…"   About a minute ago   Up About a minute   8080/tcp, 0.0.0.0:4000->80/tcp   vigorous_stallman

5. 将 docker 镜像推送到 docker hub

现在让我们将 docker 镜像推送到 docker hub,以便其他人可以下载和使用我们的镜像。

使用您的 Docker Id 登录

$ docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username (callicoder): callicoder
Password:
Login Succeeded

标记图像

To push a local image to docker registry, you need to associate the local image with a repository on the docker registry. The notation for the repository on docker registry is `username/repository:tag`.

To tag an image, we use the `docker tag` command -

```bash
$ docker tag image username/repository:tag

For example, Here is how we can tag the local image of our spring boot application -

$ docker tag spring-boot-websocket-chat-demo callicoder/spring-boot-websocket-chat-demo:0.0.1-SNAPSHOT

Make sure to replace my username callicoder with your docker id in the above command.

Once the tagging is done, you can type docker image ls in the terminal to see the newly tagged image -

$ docker image ls

REPOSITORY                                   TAG                 IMAGE ID            CREATED             SIZE

callicoder/spring-boot-websocket-chat-demo 0.0.1-SNAPSHOT 30ad8958ac67 23 小时前 126MB spring-boot-websocket-chat-demo 最新 30ad8958ac67 23 小时前 126MB openjdk 8-jdk-alpineb2b262 个月前


*
**将镜像推送到docker hub**

最后,使用 `docker push` 命令将标记的图像推送到 docker hub,如下所示 -

$ docker push callicoder/spring-boot-websocket-chat-demo:0.0.1-SNAPSHOT



同样,不要忘记将用户名 `callicoder` 替换为您的 docker id。

就这样!该图像现已发布在以下链接的 docker hub 上 - [https://hub.docker.com/r/callicoder/spring-boot-websocket-chat-demo/](https://hub.docker.com/r/callicoder/spring-boot-websocket-chat-demo/)

#### 6. 从 docker hub 拉取镜像并运行

在我们将镜像发布到 docker hub 之后,任何人都可以拉取这个镜像并在他们的环境中运行它。键入以下命令以在您的机器上拉取并运行我们刚刚推送到 docker hub 的镜像 -

$ docker run -p 5000:8080 callicoder/spring-boot-websocket-chat-demo:0.0.1-SNAPSHOT



如果本地不可用,`docker run` 命令从 docker hub 拉取镜像,然后运行它。

您会发现与他人分享您的图像是多么容易。人们不需要安装任何东西来运行你的应用程序。他们只需要拉取镜像并使用 docker 运行它。

### 使用 dockerfile-maven-plugin 自动创建和发布 Docker 镜像

您可以使用 [`dockerfile-maven-plugin`](https://github.com/spotify/dockerfile-maven) 自动化从构建 docker 镜像到在 docker hub 上发布的所有内容。

使用以下配置将插件添加到 `pom.xml` 文件中 -

<plugin> <groupId>com.spotify</groupId> <artifactId>dockerfile-maven-plugin</artifactId> <version>1.4.0</version> <configuration> <!-- replace `callicoder` with your docker id--> <repository>callicoder/spring-boot-websocket-chat-demo</repository> <tag>${project.version}</tag> <buildArgs> <JAR_FILE>target/${project.build.finalName}.jar</JAR_FILE> </buildArgs> </configuration> <executions> <execution> <id>default</id> <phase>install</phase> <goals> <goal>build</goal> <goal>push</goal> </goals> </execution> </executions> </plugin> ```

插件的配置包括远程存储库名称和存储库标签。请将 callicoder 元素中的用户名 $28$ 替换为您的 docker Id。

我们还在 <buildArgs> 元素中传递 JAR_FILE 参数。还记得我们在 Dockerfile 中添加了 ARG JAR_FILE 指令吗?此处传递的参数将覆盖该值。

以下是使用 docker-file-maven 插件构建 docker 镜像的方法 -

$ mvn package dockerfile:build

上述命令首先将应用程序打包成jar文件的形式,然后构建docker镜像。

最后,您可以使用 dockerfile:push 命令将 docker 镜像推送到 docker 注册表 -

$ mvn dockerfile:push

现在为了进一步自动化,我们使用 <executions> 标签将 dockerfile:builddockerfile:push 目标注册到 maven 构建生命周期的 install 阶段。

因此,每当您运行 mvn install 时,都会执行 dockerfile-maven-pluginbuildpush 目标,并且您的 docker 镜像会被构建并推送到 docker hub。

dockerfile-maven-plugin 使用存储在任何配置文件 ~/.dockercfg~/.docker/config.json 中的身份验证信息将 docker 镜像推送到您的 docker 配置文件。这些配置文件是在您通过 docker login 登录 docker 时创建的。

您还可以在 maven settings.xmlpom.xml 文件中指定身份验证详细信息。查看插件的官方自述文件以获取更多信息。

相关文章