使用 Docker Compose Profiles 对应用程序的部分进行单元测试
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 的服务(postgres、jobrunner)。适用于轻量级测试堆栈。 |
docker compose --profile full up | 启动标记为 full 的服务(nextjs、authserver)。 |
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 |
|---|---|
test | unit-test-db |
prod | app-db |
没有 运行时切换——您启动的 profile 决定应用在启动时根据提供的环境变量连接到哪个数据库。
替代方案
而不是使用 profiles,您可以维护单独的 Compose 文件:
docker-compose.test.ymldocker-compose.prod.yml
每个文件都可以硬编码正确的数据库主机。这提供了更清晰的分离,但需要维护多个文件。
使用 unit-test-db 和 app-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-dbapp
docker compose --profile prod up
仅启动:
app-dbapp
清晰的思维模型
| Profile | DB Container | DATABASE_URL host |
|---|---|---|
| test | unit-test-db | unit-test-db |
| prod | app-db | app-db |
服务名称在 Docker 网络中会成为 DNS 主机名。每次配置启动都会定义:
- 哪个数据库容器在运行
- 应用程序收到的
DATABASE_URL是哪个
祝写作愉快!