使用 Docker Compose Profiles 对应用程序的部分进行单元测试

发布: (2026年2月20日 GMT+8 17:26)
5 分钟阅读
原文: Dev.to

Source: Dev.to

请提供您希望翻译的完整文本(除代码块、URL 和 Markdown 语法外),我将把它翻译成简体中文并保持原有的格式。谢谢!

概述

Compose profiles 让您可以将服务分组,以便在特定场景下只启动堆栈的子集(例如,轻量测试 vs. 完整生产)。

docker‑compose.yml 中,为想要分组的每个服务添加 profiles 列表:

services:
  postgres:
    profiles: ["core"]
    ...

  jobrunner:
    profiles: ["core"]

  nextjs:
    profiles: ["full"]

  authserver:
    profiles: ["full"]

工作原理

命令会启动什么
docker compose up (no --profile)仅会启动 没有 profiles 键的服务。在上面的示例中,除非定义默认(未使用 profile)的服务,否则不会启动任何东西。
docker compose --profile core up启动标记为 core 的服务(postgresjobrunner)。适用于轻量级测试堆栈。
docker compose --profile full up启动标记为 full 的服务(nextjsauthserver)。
docker compose --profile core --profile full up同时启动 core full 服务。

提示: 如果某个服务应始终运行,请省略 profiles 键。无论使用何种 profile 标志,它都会启动。

多数据库和配置文件

Docker Compose 允许使用相同名称的多个服务——即使在不同的 profile(配置文件)之间也是如此。
如果需要同时使用生产数据库和单元测试数据库,请为它们指定唯一的服务名称,并将每个服务分配到各自的 profile(配置文件)中:

services:
  app-db:
    profiles: ["prod"]

  unit-test-db:
    profiles: ["test"]

数据库配置策略

  • 您的应用容器一次只使用 一个 DATABASE_URL
  • 每次启动的 profile 决定应用连接到哪个数据库。
配置文件DATABASE_URL
testunit-test-db
prodapp-db

没有 运行时切换——您启动的 profile 决定应用在启动时根据提供的环境变量连接到哪个数据库。

替代方案

而不是使用 profiles,您可以维护单独的 Compose 文件:

  • docker-compose.test.yml
  • docker-compose.prod.yml

每个文件都可以硬编码正确的数据库主机。这提供了更清晰的分离,但需要维护多个文件。

使用 unit-test-dbapp-db 的具体示例

下面是一个干净、完整可运行的示例。

1️⃣ docker-compose.yml

services:
  # -----------------
  # Databases
  # -----------------
  unit-test-db:
    image: postgres:15
    container_name: unit-test-db
    profiles: ["test"]
    environment:
      POSTGRES_USER: test
      POSTGRES_PASSWORD: test
      POSTGRES_DB: testdb
    ports:
      - "5433:5432"

  app-db:
    image: postgres:15
    container_name: app-db
    profiles: ["prod"]
    environment:
      POSTGRES_USER: prod
      POSTGRES_PASSWORD: prod
      POSTGRES_DB: proddb
    ports:
      - "5432:5432"

  # -----------------
  # Application
  # -----------------
  app:
    build: .
    depends_on:
      - unit-test-db
      - app-db
    environment:
      DATABASE_URL: ${DATABASE_URL}

2️⃣ DATABASE_URL 应该是什么样子

在 Docker 中,主机名就是 服务名称

测试配置 → 连接到 unit-test-db

postgresql://test:test@unit-test-db:5432/testdb

生产配置 → 连接到 app-db

postgresql://prod:prod@app-db:5432/proddb

3️⃣ 使用不同的环境变量集合运行

✅ 方案 A — 使用独立的 .env 文件(推荐)

.env.test

DATABASE_URL=postgresql://test:test@unit-test-db:5432/testdb

.env.prod

DATABASE_URL=postgresql://prod:prod@app-db:5432/proddb

启动测试堆栈

docker compose --profile test --env-file .env.test up

启动生产堆栈

docker compose --profile prod --env-file .env.prod up

✅ 方案 B — 内联环境变量

测试

DATABASE_URL=postgresql://test:test@unit-test-db:5432/testdb \
docker compose --profile test up

生产

DATABASE_URL=postgresql://prod:prod@app-db:5432/proddb \
docker compose --profile prod up

4️⃣ 实际启动的服务

docker compose --profile test up

仅启动:

  • unit-test-db
  • app
docker compose --profile prod up

仅启动:

  • app-db
  • app

清晰的思维模型

ProfileDB ContainerDATABASE_URL host
testunit-test-dbunit-test-db
prodapp-dbapp-db

服务名称在 Docker 网络中会成为 DNS 主机名。每次配置启动都会定义:

  • 哪个数据库容器在运行
  • 应用程序收到的 DATABASE_URL 是哪个

祝写作愉快!

0 浏览
Back to Blog

相关文章

阅读更多 »