Spring Boot 3 中对 Docker Compose 的支持

1、概览

Spring Boot 3 具有一些新功能,比如将我们的应用程序构建为 GraalVM Native Image(原生镜像)。另一个相关支持是 Docker Compose。

在本教程中,我们将了解如何将 Docker Compose 工作流与 Spring Boot 3 整合。

2、Spring Boot 3 的 Docker Compose Support 提供了什么?

通常,我们会根据 docker-compose.yml 运行 docker-compose up 来启动和 docker-compose down 来停止我们的容器。现在,我们可以将这些 Docker Compose 命令委托给 Spring Boot 3。当 Spring Boot 应用程序启动或停止时,它也会管理我们的容器。

此外,它还内置了对多种服务的管理,如 SQL 数据库、MongoDB、Cassandra 等。因此,我们可能不需要在 application 资源文件中重复配置 class 或 properties。

最后,我们会看到如何在该支持中使用自定义 Docker 镜像和 Docker Compose profiles 。

3,设定

我们需要 Docker Compose 和 Spring Boot 3 来探索这种新的支持。

3.1、Docker Compose

Docker Compose 需要已安装的 Docker 引擎。它们很容易安装,不过根据操作系统的不同可能会有差异。

Docker 在主机中作为服务运行。通过 Docker 镜像,我们可以在系统中将容器作为轻量级进程运行。我们可以将镜像视为在最小 Linux 内核之上的多层镜像。

3.2、Spring Boot 3

有几种方法可以设置 Spring Boot 3 项目。例如,我们可以使用 3.1.0 版的 Spring Initializer。不论如何,始终需要 Spring Boot 3 starter 来为项目中的依赖提供支持。

首先,我们添加一个 parent POM:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <relativePath />
</parent>

我们希望在应用程序中使用 REST 端点,因此需要 web 依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

我们将连接到一个示例数据库。有多种开箱即用的支持,我们将使用 MongoDB::

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>

为了检查应用程序是否正常运行,我们将使用 Spring Boot Actuator 进行检查:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

最后,我们将添加 Docker Compose 依赖。如果我们想使用其他项目功能,但不想使用 Docker Compose 支持,可以将 optional 标签设置为 true

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-docker-compose</artifactId>
    <version>3.1.1</version>
</dependency>

如果使用 Gradle,我们可以使用 Spring Boot Gradle Plugin 来实现类似 BOM 的依赖管理。

4、使用 Docker Compose 启动 Spring Boot 3 应用

我们将创建一个使用 MongoDB 数据库的 Spring Boot 3 应用。一旦我们在启动时依赖了 spring-boot-docker-compose,我们的应用程序就会启动 docker-compose.yml 文件中的所有服务。

4.1、Docker Compose 文件

首先,创建 docker-compose.yml 文件:

version: '3.8'
services:
  db:
    image: mongo:latest
    ports:
      - '27017:27017'
    volumes:
      - db:/data/db
volumes:
  db:
    driver:
      local

4.2、Spring Profile

我们需要告诉 Spring Boot 3 Docker Compose 文件的名称和路径。我们可以在 application-{profile} properties 或 YAML 文件中添加这一点。我们将使用 docker-compose Spring profile。因此,我们将创建一个 application-docker-compose.yml 配置文件:

spring:
  docker:
    compose:
      enabled: true
      file: docker-compose.yml

4.3、数据库配置

我们不需要数据库配置。Docker Compose Support 会创建一个默认配置。不过,我们仍可以通过 profile 使用自定义 MongoDB 配置:

@Profile("!docker-compose")

这样,我们就可以选择是否使用 Docker Compose Support。如果我们不使用 profile,应用就会希望数据库已经运行。

4.4、Model

然后,我们为项目创建一个简单的文档(Document)类:

@Document("item")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Item {

    @Id
    private String id;
    private String name;
    private int quantity;
    private String category;
}

4.5、REST Controller

最后,让我们定义一个 controller,其中包含一些 CRUD 操作:

@RestController
@RequestMapping("/item")
@RequiredArgsConstructor
public class ItemController {
    ....
    @PostMapping(consumes = APPLICATION_JSON_VALUE)
    public ResponseEntity<Item> save(final @RequestBody Item item) {
        return ResponseEntity.ok(itemRepository.save(item));
    }
    // 其他端点
}

5、Application Test

我们可以通过 IDE 或命令行运行 Spring Boot 3 main class 来启动应用程序。

5.1、应用启动

记住要指定 spring profile。例如,我们可以在命令行中使用 Spring Boot maven plugin

mvn spring-boot:run -Pdocker-compose -Dspring-boot.run.profiles=docker-compose

我们还添加了一个专用的 Maven build profile(-Pdocker-compose),以防存在其他的。

现在,如果我们执行 docker ps,就会看到 MongoDb 容器正在运行:

CONTAINER ID   IMAGE             COMMAND                  CREATED        STATUS            PORTS                                           NAMES
77a9667b291a   mongo:latest      "docker-entrypoint.s…"   21 hours ago   Up 10 minutes     0.0.0.0:27017->27017/tcp, :::27017->27017/tcp   classes-db-1

现在,我们可以对应用进行一些实时测试。

5.2,应用检查

我们可以通过 actuator endpoint 检查应用是否已启动和运行:

curl --location 'http://localhost:8080/actuator/health'

如果一切正常,我们应该得到 200 status:

{
    "status": "UP"
}

为了进行数据库测试,让我们使用 POST 请求 http://localhost:8080/item 端点来添加一些项目。例如,使用 curl 发起 Post 请求:

curl --location 'http://localhost:8080/item' \
--header 'Content-Type: application/json' \
--data '{
    "name" : "Tennis Ball",
    "quantity" : 5,
    "category" : "sport"
}'

我们将得到一个包含已生成项目 ID 的响应:

{
    "id": "64b117b6a805f7296d8412d9",
    "name": "Tennis Ball",
    "quantity": 5,
    "category": "sport"
}

5.3,应用停止

最后,关闭 Spring Boot 3 应用也会停止我们的容器。我们可以通过执行 docker ps -a 来查看:

CONTAINER ID   IMAGE             COMMAND                  CREATED        STATUS                     PORTS     NAMES
77a9667b291a   mongo:latest      "docker-entrypoint.s…"   22 hours ago   Exited (0) 5 seconds ago             classes-db-1

6、Docker Compose Support 的特性

更多 Docker Compose Support 支持的功能可以在 官方文档中查阅。

6.1、服务连接

该支持会在启动时自动发现一些服务。我们已经看到了 MongoDB。不过,还有其他服务,如 Redis 或 ElasticSearch。服务连接将找到并使用本地映射的端口。我们可以跳过配置类或属性。Spring Boot 使用 ConnectionDetails 抽象实现了这一点。

6.2、自定义镜像

我们可以通过应用 label 来使用自定义的 Docker 镜像:

version: '3.8'
services:
  db:
    image: our-custom-mongo-image
    ports:
      - '27017:27017'
    volumes:
      - db:/data/db
    labels:
      org.springframework.boot.service-connection: mongo
volumes:
  db:
    driver:
      local

6.3、等待容器就绪

有趣的是,Spring Boot 3 会自动检查容器是否准备就绪。容器可能需要一段时间才能完全就绪,因此,Spring Boot 通过使用 healthcheck 命令来查看容器是否准备就绪。

6.4、激活 Docker Compose Profiles

我们可以在运行时切换不同的 Docker Compose profiles。我们的服务定义可能很复杂,因此我们可能希望选择启用哪个 profiles ,例如,如果我们处于 debug 或生产环境中。我们可以使用配置属性来实现这一点:

spring.docker.compose.profiles.active=myprofile

7、Docker Compose Support 的好处

在生产环境中,我们的 docker 服务可能会分布在不同的实例中。因此,在这种情况下,我们可能不需要这种支持。不过,我们可以激活一个 Spring profile ,从 docker-compose.yml 定义中加载,仅用于本地开发。

这种支持与我们的 IDE 很好地集成在一起,我们不用在命令行上来回切换来启动和停止 Docker 服务。 3.1 版刚刚开始提供支持。总的来说,它已经具备了一些不错的功能,比如多服务连接、服务就绪默认检查以及使用 Docker Compose profiles 的可能性。

8,总结

在本文中,我们了解了 Spring Boot 3.1.0 中新的 Docker Compose support,以及如何使用它设置和创建 Spring Boot 3 应用。

由于 Spring Boot 易于开发,这种支持非常方便,而且已经具备了很好的功能。在启动和停止应用时,Spring Boot 3 会管理 Docker 服务的生命周期。


参考:https://www.baeldung.com/ops/docker-compose-support-spring-boot