Docker Compose 最佳实践
- 不要把无关服务塞进一个 compose
- 生命周期统一:起 -> 用 -> 停 -> 删
✅ 正确:
erp/
├─ api/
├─ web/
└─ docker-compose.yml
❌ 错误:
all-in-one-compose.yml
- 不关心容器名
- 不依赖容器 IP
- 不写死 hostname
✅ 用 service 名通信
❌ 用 IP / container_name 通信
- 代码无状态
- 会话无状态
- 数据全部外置(DB / volume)
- 镜像不含环境差异
- 使用 env / env_file / volume
- 通过 override / profile 控制差异
- 不做 HA
- 不做自愈
- 不做调度
推荐结构
project/
├─ docker/
│ ├─ Dockerfile
│ ├─ nginx.conf
│ └─ entrypoint.sh
├─ docker-compose.yml
├─ docker-compose.override.yml
├─ .env
├─ api/
└─ web/
📌 Compose 文件在项目根目录
APP_ENV=dev
DB_HOST=db
DB_PORT=5432
services:
api:
env_file:
- .env
❌
POSTGRES_PASSWORD: 123456
✅
POSTGRES_PASSWORD: ${DB_PASSWORD}
Compose 不是模板引擎。
api -> db:5432
❌ 不用 IP ❌ 不用 links(废弃)
ports:
- "8080:80"
📌 容器间通信 不需要 ports
networks:
frontend:
backend:
volumes:
- pgdata:/var/lib/postgresql/data
volumes:
- ./config:/etc/app:ro
- 日志走 stdout
- Docker / ELK 收集
depends_on = 服务就绪
❌ 错
db:
healthcheck:
test: ["CMD", "pg_isready"]
interval: 5s
retries: 5
api:
depends_on:
db:
condition: service_healthy
推荐写法(本地 / CI)
mem_limit: 512m
cpus: 1.0
📌 防止:
- 本地机器被拖死
- CI OOM
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"
- stdout / stderr
- 交给 Docker / Loki / ELK
复杂逻辑放 Dockerfile。
build:
context: .
image: erp-api:${APP_VERSION}
场景控制
services:
admin:
profiles: ["dev"]
docker compose --profile dev up
📌 极佳替代多个 compose 文件。
docker-compose.override.yml
- 本地开发自动加载
- 不提交生产配置
services:
api:
volumes:
- ./api:/app
restart: unless-stopped
适合:
- API
- Web
- Worker
- ❌ 使用 container_name
- ❌ 使用 links
- ❌ 用 IP 通信
- ❌ 在容器里跑 cron / systemd
- ❌ 把 Compose 当 Kubernetes 用
- ❌ 在 Compose 里做复杂逻辑判断
| Compose | Kubernetes |
|---|---|
| service | Deployment |
| volume | PVC |
| network | Service |
| env | ConfigMap |
| secret | Secret |
📌 Compose 写得好,迁移成本极低。
name: erp
services:
api:
image: erp-api:${APP_VERSION}
build: .
ports:
- "8000:8000"
env_file:
- .env
depends_on:
db:
condition: service_healthy
restart: unless-stopped
mem_limit: 512m
cpus: 1.0
db:
image: postgres:16
volumes:
- pgdata:/var/lib/postgresql/data
environment:
POSTGRES_PASSWORD: ${DB_PASSWORD}
healthcheck:
test: ["CMD", "pg_isready"]
interval: 5s
retries: 5
volumes:
pgdata:
Compose 是单机级应用编排工具
Service 是模板,不是实例
Compose 管理的是“应用生命周期”