You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker Compose容器化Postgres时Spring Boot应用构建的正确方案

问题:Docker集成Postgres的Spring Boot应用测试流水线方案

我正在使用Docker开发集成Postgres的Spring Boot应用,当前的Dockerfile和docker-compose.yml配置如下:

Dockerfile

FROM adoptopenjdk/openjdk11-openj9:alpine-slim
ADD target/app-0.0.1-SNAPSHOT.jar /app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "-Dspring.profiles.active=${ENV}", "/app.jar"]

docker-compose.yml

version: '2'

services:
  app:
    image: 'app:latest'
    build:
      context: .
    container_name: app
    depends_on:
      - db
    environment:
      - ENV=local
    ports:
      - "8080:8080"

  db:
    image: 'postgres:13.1-alpine'
    container_name: db
    environment:
      - POSTGRES_USER=labuser
      - POSTGRES_PASSWORD=labpwd

执行docker-compose up前必须在target目录生成jar包,但构建jar时因数据库尚未存在导致构建失败。我知道可以通过./mvnw clean package -DskipTests跳过测试,但不清楚生产流水线中如何正常运行这些测试,恳请给出建议。


解决方案建议

1. 流水线中临时启动测试数据库

在CI/CD流水线中,先启动独立的Postgres容器,等服务就绪后执行测试,完成后清理容器:

# 启动临时测试数据库
docker run -d --name test-db -e POSTGRES_USER=labuser -e POSTGRES_PASSWORD=labpwd -p 5432:5432 postgres:13.1-alpine

# 等待数据库服务可用(避免直接执行测试时连接失败)
until docker exec test-db pg_isready -U labuser; do
  echo "等待数据库启动..."
  sleep 2
done

# 运行所有测试
./mvnw clean test

# 测试完成后销毁临时容器
docker stop test-db && docker rm test-db

# 测试通过后构建jar包
./mvnw clean package -DskipTests

这种方式无需修改代码,纯靠流水线脚本控制,适配大多数CI平台(GitLab CI、GitHub Actions等)。

2. 使用Testcontainers框架自动管理测试数据库

引入Testcontainers依赖后,测试时会自动启动真实的Postgres容器,无需手动维护数据库:

  • 首先在pom.xml中添加Testcontainers依赖(Maven示例):
<dependency>
    <groupId>org.testcontainers</groupId>
    <artifactId>postgresql</artifactId>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.testcontainers</groupId>
    <artifactId>junit-jupiter</artifactId>
    <scope>test</scope>
</dependency>
  • 配置测试环境的数据源(src/test/resources/application-test.yml):
spring:
  datasource:
    url: jdbc:tc:postgres:13.1-alpine:///testdb
    username: labuser
    password: labpwd
  jpa:
    hibernate:
      ddl-auto: create-drop
  • 在测试类上激活test profile:
@SpringBootTest
@ActiveProfiles("test")
class YourApplicationTests {
    // 测试逻辑
}

运行测试时,Testcontainers会自动拉取镜像、启动容器、建立连接,测试结束后自动销毁容器,本地和流水线都能无缝运行测试。

3. 拆分流水线的构建、测试、打包阶段

把流水线拆分为三个独立阶段,避免打包时依赖测试环境:

  1. 编译阶段:仅执行代码编译,不测试也不打包
    ./mvnw clean compile
    
  2. 测试阶段:启动数据库容器,连接编译后的代码运行测试
    (可参考方案1的脚本,仅执行./mvnw test)
  3. 打包阶段:测试通过后,跳过测试直接构建jar包并制作Docker镜像
    ./mvnw package -DskipTests
    docker build -t app:latest .
    

这种方式分离了构建与测试的依赖,确保每个阶段职责单一,流水线更稳定。


内容的提问来源于stack exchange,提问作者Manish

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 11:22:53