1. 概述

Spring Boot 3 带来了不少新特性,比如构建 GraalVM 原生镜像 或 Java 17 基线支持。但另一个值得关注的更新是对 Docker Compose 的集成支持。

本文将演示如何在 Spring Boot 3 中整合 Docker Compose 工作流。

2. Spring Boot 3 的 Docker Compose 支持能做什么?

传统做法下,我们需要手动执行 docker-compose up 启动容器、docker-compose down 停止容器。现在 Spring Boot 3 可以接管这些操作——在应用启动/停止时自动管理容器生命周期。

更关键的是,它内置了对多种服务的自动管理(如 SQL 数据库、MongoDB、Cassandra 等),这意味着我们可能不需要在配置文件中重复写这些服务的连接配置。

最后我们还会看到,该支持同样适用于自定义镜像和 Docker Compose 配置文件。

3. 环境准备

要使用这个新特性,需要同时安装 Docker Compose 和 Spring Boot 3。

3.1. Docker Compose

Docker Compose 依赖 Docker 引擎。安装过程因操作系统而异,但通常都很简单。

Docker 在主机上作为服务运行。我们可以将镜像视为基于精简 Linux 内核的多层镜像栈,并从中启动轻量级容器进程。

3.2. Spring Boot 3

创建 Spring Boot 3 项目有多种方式,比如使用 Spring Initializr(需选择 3.1.0+ 版本)。但必须确保所有依赖都使用 Spring Boot 3 的 starter 库。

首先添加父级 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>

通过 Actuator 检查应用状态:

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

最后添加核心的 Docker Compose 依赖。如果需要可选特性,可以设置 optionaltrue

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

Gradle 用户可参考 Spring Boot Gradle Plugin 实现类似依赖管理。

4. Spring Boot 3 与 Docker Compose 快速集成

我们将创建一个使用 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 配置文件

需要告诉 Spring Boot 3 Docker Compose 文件的位置和名称。在 application-{profile}.yml 中配置,这里使用 docker-compose 这个 profile:

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

4.3. 数据库配置

无需手动配置数据库连接! Docker Compose 支持会自动生成默认配置。

如果需要自定义配置,可以通过 profile 排除自动配置:

@Profile("!docker-compose")

这样就能灵活选择是否使用 Docker Compose 支持。不启用该 profile 时,应用会尝试连接已运行的数据库。

4.4. 数据模型

创建一个简单的 Item 文档类:

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

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

4.5. REST 控制器

实现基础的 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. 应用测试

通过 IDE 或命令行启动应用进行测试。

5.1. 启动应用

记得指定 Spring profile。命令行启动示例:

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

这里同时指定了 Maven 构建 profile (-Pdocker-compose) 和 Spring profile。

执行 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 接口检查健康状态:

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

正常应返回 200 状态码:

{
    "status": "UP"
}

测试数据库操作,向 http://localhost:8080/item 发送 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 应用时会自动停止关联容器!执行 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 支持特性

快速浏览核心特性(详见官方文档):

6.1. 服务连接

启动时自动发现多种服务(除 MongoDB 外还包括 RedisElasticSearch 等)。服务连接会自动使用本地映射端口,无需手动配置类或属性。这通过 Spring Boot 的 ConnectionDetails 抽象实现。

6.2. 自定义镜像

通过添加 label 使用自定义镜像:

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. 容器就绪等待

自动检查容器就绪状态! 容器启动需要时间,该特性免去了手动配置 healthcheck 的麻烦。

6.4. 激活 Docker Compose Profile

运行时切换不同的 Docker Compose profile。通过配置属性指定:

spring.docker.compose.profiles.active=myprofile

适用于区分调试/生产环境等场景。

7. Docker Compose 支持的优势

生产环境中,Docker 服务可能分布在多个实例上,此时可能不需要此特性。但对于本地开发,通过 Spring profile 加载 docker-compose.yml 会非常方便。

该支持与 IDE 深度集成,无需频繁切换命令行启动/停止 Docker 服务。

虽然从 3.1.0 版本才开始支持,但已包含多项实用特性:

  • 多服务连接
  • 默认服务就绪检查
  • 支持 Docker Compose profile

8. 总结

本文介绍了 Spring Boot 3.1.0 的新特性——Docker Compose 支持。我们演示了如何设置和创建集成应用。

秉承 Spring Boot 简化开发的理念,该支持非常实用且功能完善。在应用启动/停止过程中,Spring Boot 3 会自动管理 Docker 服务的生命周期。


原始标题:Docker Compose Support in Spring Boot | Baeldung