本文介绍了如何将Spring Boot应用使用Docker进行容器化部署的入门知识,详细讲解了从环境准备到构建Docker镜像,再到运行Docker容器的全过程。通过示例,读者可以轻松掌握Spring Boot应用的Docker容器化部署入门技巧。从安装Docker、创建Spring Boot项目到编写Dockerfile、构建和运行Docker容器的各个步骤,本文都将一一展开介绍。
Spring Boot 是由 Pivotal 团队提供的一个开源框架,旨在简化新 Spring 应用的初始搭建以及开发过程。通过 Spring Boot,可以非常方便地创建独立的、生产级别的基于 Spring 框架的应用程序。
Spring Boot 是 Spring 的一个模块,它提供了一种新的方式来简化 Spring 应用程序的配置。它通过约定优于配置的方式,帮助开发者快速搭建项目。Spring Boot 的核心功能是允许开发者通过一个独立的可执行的 JAR 文件,并提供一系列默认配置来运行应用程序。
Docker 是一个开源的应用容器引擎,基于容器技术(如 LXC 和 AUFS),可以将应用及其依赖打包在统一的容器中进行分发和运行。
在开始将 Spring Boot 应用容器化之前,需要确保系统上已经安装了 Docker,并且成功创建了一个 Spring Boot 项目。
安装 Docker 的步骤根据操作系统不同而略有不同,这里以 Ubuntu 系统为例,Docker 安装步骤如下:
更新软件包索引:
sudo apt-get update
安装 Docker 的包和依赖:
sudo apt-get install apt-transport-https ca-certificates curl software-properties-common
添加 Docker 的官方 GPG 密钥:
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
添加 Docker 的 APT 仓库:
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
sudo apt-get update sudo apt-get install docker-ce
安装完成后,可以通过运行命令 docker --version
来验证 Docker 是否安装成功。
这里以创建一个简单的 Spring Boot 应用程序为例。可以通过 Spring Initializr(如 https://start.spring.io/)来快速创建一个新的 Spring Boot 项目。选择所需依赖,例如 Web 依赖,并下载生成的项目,或者使用命令行工具 spring init
来创建项目:
mvn archetype:generate -DarchetypeGroupId=org.springframework.boot -DarchetypeArtifactId=spring-boot-archetype-web -DarchetypeVersion=2.2.2.RELEASE -DgroupId=com.example -DartifactId=hello-world -Dversion=1.0.0-SNAPSHOT -Dpackage=com.example.hello-world
在项目根目录下,可以通过执行以下命令来运行项目:
mvn spring-boot:run
以下是一个简单的 Spring Boot 应用程序的完整代码:
package com.example.hello; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @SpringBootApplication public class HelloWorldApplication { public static void main(String[] args) { SpringApplication.run(HelloWorldApplication.class, args); } @RestController public class HelloController { @GetMapping("/hello") public String hello() { return "Hello, Docker!"; } } }
Dockerfile 是 Docker 镜像的构建文件,它定义了如何构建 Docker 镜像的步骤。Dockerfile 中的每一行指令都会执行一次构建步骤,并生成一个新的镜像层。
Dockerfile 的主要作用是定义一个镜像的构建过程,包括基础镜像的选择、环境变量的设置、文件的复制、依赖的安装等。通过 Dockerfile,可以自动化构建出一个包含所有应用依赖的独立镜像。
以下是一个简单的 Dockerfile 示例,用于构建一个 Spring Boot 应用程序的 Docker 镜像:
# 使用官方的 Java 运行时作为基础镜像 FROM openjdk:8-jdk-alpine # 设置镜像的工作目录 WORKDIR /app # 复制编译好的 jar 文件到镜像中 COPY target/*.jar app.jar # 设置环境变量 ENV JAVA_OPTS="" # 暴露应用程序使用的端口 EXPOSE 8080 # 运行应用程序的命令 ENTRYPOINT ["java", "$JAVA_OPTS", "-jar", "/app/app.jar"]
FROM openjdk:8-jdk-alpine
:这一行指定了 Dockerfile 使用的基镜像,这里使用了 openjdk:8-jdk-alpine
,它是一个基于 Alpine Linux 的 Java 运行时环境。WORKDIR /app
:定义了在 Docker 容器内部的工作目录。COPY target/*.jar app.jar
:将当前目录中 target
文件夹下的所有 .jar
文件复制到容器的 /app
目录下,并命名为 app.jar
。EXPOSE 8080
:指定容器运行时暴露 8080 端口,这是 Spring Boot 应用默认使用的端口。ENTRYPOINT ["java", "$JAVA_OPTS", "-jar", "/app/app.jar"]
:指定了容器启动时运行的命令,这里使用 Java 命令运行 app.jar
文件。在编写了 Dockerfile 后,接下来需要通过 Docker 命令来构建 Docker 镜像,并验证构建是否成功。
构建 Docker 镜像的命令如下:
docker build -t spring-boot-app:1.0 .
这个命令将当前目录(.
)作为 Dockerfile 的位置,并使用 -t
参数为镜像指定一个名称和标签(这里是 spring-boot-app:1.0
)。
构建完成后,可以通过命令查看构建的镜像列表:
docker images
这会列出所有可用的 Docker 镜像,其中应该包括我们刚刚构建的 spring-boot-app:1.0
镜像。
# 构建命令及输出 $ docker build -t spring-boot-app:1.0 . Sending build context to Docker daemon 88.18MB Step 1/4 : FROM openjdk:8-jdk-alpine ---> 810b8e3e8e4f Step 2/4 : WORKDIR /app ---> Using cache ---> 810b8e3e8e4f Step 3/4 : COPY target/*.jar app.jar ---> Using cache ---> 810b8e3e8e4f Step 4/4 : EXPOSE 8080 ---> Using cache ---> 810b8e3e8e4f Successfully built 810b8e3e8e4f Successfully tagged spring-boot-app:1.0
在成功构建 Docker 镜像后,接下来就可以使用 Docker 命令来启动容器了。
启动容器的命令如下:
docker run -d -p 8080:8080 --name spring-boot-container spring-boot-app:1.0
这个命令启动了一个 Docker 容器,并将其暴露在主机的 8080 端口上。-d
参数表示以分离模式运行容器,--name
参数用于为容器指定名称。
在构建镜像时,我们已经使用 EXPOSE
指令指定了容器将要暴露的端口。然后在运行容器时,通过 -p
参数将容器内的端口映射到主机的端口。例如,-p 8080:8080
表示将容器内的 8080 端口映射到主机的 8080 端口。
# 运行命令及输出 $ docker run -d -p 8080:8080 --name spring-boot-container spring-boot-app:1.0 Unable to find image 'spring-boot-app:1.0' locally 1.0: Pulling from library/spring-boot-app Digest: sha256:6a005d6b3d7b9f1d434f480c26c2b5b9d9c1e2c9e27b9e5d6a005d6b3d7b9f1d Status: Downloaded newer image for spring-boot-app:1.0 00b0f65b6e8b66a10499966e8b66a1049996 # 验证容器是否运行 $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 00b0f65b6e8b spring-boot-app "java -jar app.jar" 5 minutes ago Up 5 minutes 0.0.0.0:8080->8080/tcp spring-boot-container
为了更好地理解如何将 Spring Boot 应用容器化,以下是一个完整的示例,包括从创建 Spring Boot 应用到容器化部署的所有步骤。
首先,创建一个简单的 Spring Boot 应用,添加一个简单的 REST 控制器:
package com.example.hello; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @SpringBootApplication public class HelloWorldApplication { public static void main(String[] args) { SpringApplication.run(HelloWorldApplication.class, args); } @RestController public class HelloController { @GetMapping("/hello") public String hello() { return "Hello, Docker!"; } } }
在项目目录中,执行以下命令构建项目:
mvn clean install
这会生成 target
目录下的 jar 文件。
# 构建命令及输出 $ mvn clean install [INFO] Scanning for projects... [INFO] [INFO] --------------< com.example:hello-world >--------------- [INFO] Building hello-world 1.0.0-SNAPSHOT [INFO] --------------------------------[ jar ]---------------------- [INFO] [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ hello-world --- [INFO] Using 'UTF-8' encoding to copy filtered resources. [INFO] skip non existing resourceDirectory /path/to/project/src/main/resources [INFO] [INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ hello-world --- [INFO] Changes detected - recompiling the module! [INFO] Compiling 1 source file to /path/to/project/target/classes [INFO] [INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ hello-world --- [INFO] Using 'UTF-8' encoding to copy filtered resources. [INFO] skip non existing resourceDirectory /path/to/project/src/test/resources [INFO] [INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ hello-world --- [INFO] Nothing to compile - skip compiling [INFO] [INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ hello-world --- [INFO] No tests to run. [INFO] [INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ hello-world --- [INFO] Building jar: /path/to/project/target/hello-world-1.0.0-SNAPSHOT.jar [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 2.190 s [INFO] Finished at: 2023-10-08T12:34:56+08:00 [INFO] Final Memory: 15M/311M [INFO] ------------------------------------------------------------------------
在项目根目录下创建一个 Dockerfile
文件,并添加以下内容:
FROM openjdk:8-jdk-alpine WORKDIR /app COPY target/*.jar app.jar EXPOSE 8080 ENTRYPOINT ["java", "-jar", "app.jar"]
在项目根目录下,执行以下命令构建 Docker 镜像:
docker build -t spring-boot-app:1.0 .
# 构建命令及输出 $ docker build -t spring-boot-app:1.0 . Sending build context to Docker daemon 88.18MB Step 1/4 : FROM openjdk:8-jdk-alpine ---> 810b8e3e8e4f Step 2/4 : WORKDIR /app ---> Using cache ---> 810b8e3e8e4f Step 3/4 : COPY target/*.jar app.jar ---> Using cache ---> 810b8e3e8e4f Step 4/4 : EXPOSE 8080 ---> Using cache ---> 810b8e3e8e4f Successfully built 810b8e3e8e4f Successfully tagged spring-boot-app:1.0
构建完成后,执行以下命令启动容器:
docker run -d -p 8080:8080 --name spring-boot-container spring-boot-app:1.0
# 运行命令及输出 $ docker run -d -p 8080:8080 --name spring-boot-container spring-boot-app:1.0 Unable to find image 'spring-boot-app:1.0' locally 1.0: Pulling from library/spring-boot-app Digest: sha256:6a005d6b3d7b9f1d434f480c26c2b5b9d9c1e2c9e27b9e5d6a005d6b3d7b9f1d Status: Downloaded newer image for spring-boot-app:1.0 00b0f65b6e8b66a10499966e8b66a1049996 # 验证容器是否运行 $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 00b0f65b6e8b spring-boot-app "java -jar app.jar" 5 minutes ago Up 5 minutes 0.0.0.0:8080->8080/tcp spring-boot-container
在浏览器中访问 http://localhost:8080/hello
,可以看到返回的响应 Hello, Docker!
,表示容器已经成功运行。
通过以上步骤,已经成功将一个简单的 Spring Boot 应用程序容器化,并运行在 Docker 容器中。