DevOps•
2025-06-16
•8 min
•alltools.one Team
YAMLDockerDocker ComposeDevOpsContainers
Docker Compose 的 YAML 配置:模式与技巧
Docker Compose 使用 YAML 来定义多容器应用。一个结构良好的 docker-compose.yml 是顺畅开发环境与数小时调试容器问题之间的关键区别。本指南涵盖了核心模式和常见陷阱。
基本结构
services:
web:
image: nginx:alpine
ports:
- "80:80"
volumes:
- ./html:/usr/share/nginx/html
depends_on:
- api
api:
build: ./api
ports:
- "3000:3000"
environment:
DATABASE_URL: postgres://db:5432/myapp
depends_on:
- db
db:
image: postgres:16
volumes:
- pgdata:/var/lib/postgresql/data
environment:
POSTGRES_DB: myapp
POSTGRES_PASSWORD: secret
volumes:
pgdata:
环境变量
内联方式
services:
api:
environment:
NODE_ENV: production
PORT: "3000"
DEBUG: "false"
从文件加载
services:
api:
env_file:
- .env
- .env.local # 覆盖 .env 中的值
变量替换
引用宿主机环境变量:
services:
api:
image: myapp:${TAG:-latest} # 默认为 "latest"
environment:
API_KEY: ${API_KEY} # 必需 - 未设置时会失败
LOG_LEVEL: ${LOG_LEVEL:-info} # 默认为 "info"
网络配置
自定义网络
services:
web:
networks:
- frontend
api:
networks:
- frontend
- backend
db:
networks:
- backend
networks:
frontend:
backend:
internal: true # 禁止外部访问
同一网络上的服务可以通过服务名相互访问。db 服务只能从 api 访问,不能从 web 访问。
端口映射
ports:
- "8080:80" # 宿主机:容器
- "443:443"
- "127.0.0.1:3000:3000" # 仅绑定到 localhost
- "3000" # 随机宿主机端口
卷
命名卷(持久化)
services:
db:
volumes:
- pgdata:/var/lib/postgresql/data
volumes:
pgdata:
driver: local
绑定挂载(开发环境)
services:
api:
volumes:
- ./src:/app/src # 源代码
- /app/node_modules # 匿名卷(防止覆盖)
匿名卷模式(/app/node_modules)可以防止宿主机绑定挂载覆盖容器内安装的依赖。
健康检查
services:
db:
image: postgres:16
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
start_period: 30s
api:
depends_on:
db:
condition: service_healthy
这确保 api 只在 db 通过健康检查后才启动——而不仅仅是容器启动时。
扩展字段(DRY 模式)
使用 x- 前缀字段配合 YAML 锚点来减少重复:
x-common: &common
restart: unless-stopped
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"
x-env: &common-env
TZ: UTC
LOG_FORMAT: json
services:
api:
<<: *common
build: ./api
environment:
<<: *common-env
PORT: "3000"
worker:
<<: *common
build: ./worker
environment:
<<: *common-env
QUEUE: default
了解更多 YAML 锚点用法,请参阅我们的 YAML 锚点和别名指南。
多阶段 Compose
开发环境 vs 生产环境
# docker-compose.yml(基础配置)
services:
api:
build: ./api
environment:
DATABASE_URL: postgres://db:5432/myapp
# docker-compose.override.yml(开发环境 - 自动加载)
services:
api:
volumes:
- ./api/src:/app/src
environment:
NODE_ENV: development
DEBUG: "true"
ports:
- "3000:3000"
- "9229:9229" # 调试端口
# docker-compose.prod.yml
services:
api:
environment:
NODE_ENV: production
deploy:
replicas: 3
# 开发环境(自动加载 override)
docker compose up
# 生产环境
docker compose -f docker-compose.yml -f docker-compose.prod.yml up
常见陷阱
1. 未加引号的端口号
# 有风险 - YAML 会将 80:80 解释为六十进制数字
ports:
- 80:80
# 安全 - 始终使用引号
ports:
- "80:80"
2. 布尔类型的环境变量
# 错误 - YAML 会转换为布尔值
environment:
DEBUG: true # 变成 Python 的 True,而不是字符串 "true"
# 正确 - 所有环境变量值都加引号
environment:
DEBUG: "true"
3. depends_on 的时机问题
depends_on 仅等待容器启动,而不是就绪状态:
# 容器启动了但数据库可能还没准备好
depends_on:
- db
# 等待健康检查通过
depends_on:
db:
condition: service_healthy
使用我们的 YAML 验证器 验证您的 Docker Compose 文件。
常见问题
docker-compose.yml 和 compose.yml 有什么区别?
两个文件名都可以使用。compose.yml 是 Docker 推荐的新命名规范。docker-compose.yml 是旧名称。Docker Compose v2+ 会查找两者,如果同时存在则优先使用 compose.yml。新项目建议使用 compose.yml。
应该在生产环境中使用 Docker Compose 吗?
Docker Compose 非常适合开发和简单部署。对于大规模生产环境,可以考虑 Docker Swarm(原生使用 Compose 文件)或 Kubernetes。Compose 的优势在于开发配置可以直接用于生产,减少环境差异。
相关资源
- YAML 验证器 — 验证 Docker Compose YAML
- YAML 锚点和别名 — DRY 配置模式
- YAML 语法教程 — YAML 基础知识