10.3.3 开发和生产用一套配置吗——环境隔离:开发/测试/生产配置差异
一套基础配置 + 环境覆盖 = 多环境部署。
多环境策略
文件组织
project/
├── docker-compose.yml # 基础配置
├── docker-compose.override.yml # 开发环境(自动加载)
├── docker-compose.prod.yml # 生产环境
├── docker-compose.test.yml # 测试环境
├── .env # 通用环境变量
├── .env.development # 开发环境变量
├── .env.production # 生产环境变量
└── .env.test # 测试环境变量基础配置
yaml
# docker-compose.yml - 所有环境共享的基础配置
services:
api:
image: my-api:${TAG:-latest}
environment:
- DATABASE_URL=${DATABASE_URL}
- REDIS_URL=${REDIS_URL}
depends_on:
- postgres
- redis
postgres:
image: postgres:15
environment:
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
volumes:
- postgres-data:/var/lib/postgresql/data
redis:
image: redis:7-alpine
volumes:
postgres-data:开发环境覆盖
yaml
# docker-compose.override.yml - 自动与 docker-compose.yml 合并
services:
api:
build: ./api # 开发时从本地构建
volumes:
- ./api:/app # 代码热重载
- /app/node_modules
command: npm run dev # 开发模式启动
ports:
- "3001:3001"
- "9229:9229" # Node.js 调试端口
postgres:
ports:
- "5432:5432" # 开发时暴露端口,方便调试自动加载
运行 docker compose up 时,如果存在 docker-compose.override.yml,会自动与 docker-compose.yml 合并。
生产环境配置
yaml
# docker-compose.prod.yml
services:
api:
image: registry.cn-hangzhou.aliyuncs.com/xxx/my-api:${TAG}
restart: always
deploy:
resources:
limits:
cpus: '1'
memory: 512M
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3001/health"]
interval: 30s
timeout: 10s
retries: 3
# 生产环境不映射端口,通过反向代理访问
postgres:
restart: always
# 生产环境不暴露数据库端口
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5启动不同环境
bash
# 开发环境(默认加载 override)
docker compose up
# 生产环境
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d
# 测试环境
docker compose -f docker-compose.yml -f docker-compose.test.yml up环境变量管理
.env 文件
env
# .env - 通用配置
COMPOSE_PROJECT_NAME=myappenv
# .env.development
DATABASE_URL=postgresql://postgres:devpass@postgres:5432/mydb
REDIS_URL=redis://redis:6379
POSTGRES_PASSWORD=devpass
NODE_ENV=developmentenv
# .env.production
DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD}@postgres:5432/mydb
REDIS_URL=redis://redis:6379
NODE_ENV=production
# POSTGRES_PASSWORD 从密钥管理服务获取,不写在文件中使用环境变量文件
bash
# 开发环境
docker compose --env-file .env.development up
# 生产环境
docker compose --env-file .env.production -f docker-compose.yml -f docker-compose.prod.yml up -d配置差异对比
| 配置项 | 开发环境 | 生产环境 |
|---|---|---|
| 镜像来源 | 本地构建 | 远程仓库 |
| 代码挂载 | 是(热重载) | 否 |
| 端口暴露 | 全部暴露 | 仅必要端口 |
| 调试端口 | 开启 | 关闭 |
| 日志级别 | debug | info/warn |
| 资源限制 | 无 | 有 |
| 健康检查 | 可选 | 必须 |
| 重启策略 | no | always |
配置覆盖规则
当多个 Compose 文件合并时:
yaml
# docker-compose.yml
services:
api:
image: my-api:latest
environment:
- NODE_ENV=development
# docker-compose.prod.yml
services:
api:
image: my-api:v1.0.0 # 覆盖镜像
environment:
- NODE_ENV=production # 覆盖环境变量
- LOG_LEVEL=info # 新增环境变量合并结果:
yaml
services:
api:
image: my-api:v1.0.0
environment:
- NODE_ENV=production
- LOG_LEVEL=info最佳实践
- 敏感信息不入库:
.env.production只放模板,真实值通过 CI/CD 注入 - 使用变量替换:
${VAR:-default}提供默认值 - 环境标识清晰:通过
COMPOSE_PROJECT_NAME区分环境 - 配置版本化:所有 compose 文件都纳入版本控制(除了包含密码的 .env)
