第五部分-DockerCompose——24. 多环境配置
24. 多环境配置
1. 多环境配置概述
在实际开发中,通常需要在不同环境(开发、测试、生产)中使用不同的配置。Docker Compose 提供了多种方式实现多环境配置管理。
┌─────────────────────────────────────────────────────────────┐ │ 多环境配置架构 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ docker-compose.yml (基础配置) │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ services: │ │ │ │ web: │ │ │ │ image: myapp │ │ │ │ ports: │ │ │ │ - "8080:80" │ │ │ └─────────────────────────────────────────────────────┘ │ │ │ │ │ ┌─────────────────┼─────────────────┐ │ │ ▼ ▼ ▼ │ │ ┌───────────┐ ┌───────────┐ ┌───────────┐ │ │ │ 开发环境 │ │ 测试环境 │ │ 生产环境 │ │ │ ├───────────┤ ├───────────┤ ├───────────┤ │ │ │ 热重载 │ │ 测试数据 │ │ 优化配置 │ │ │ │ 调试工具 │ │ Mock服务 │ │ 监控告警 │ │ │ │ 开发卷 │ │ 测试卷 │ │ 生产卷 │ │ │ └───────────┘ └───────────┘ └───────────┘ │ │ │ └─────────────────────────────────────────────────────────────┘2. 多文件覆盖
2.1 基础文件结构
compose/ ├── docker-compose.yml # 基础配置 ├── docker-compose.dev.yml # 开发覆盖 ├── docker-compose.test.yml # 测试覆盖 ├── docker-compose.prod.yml # 生产覆盖 └── docker-compose.override.yml # 自动覆盖(开发)2.2 基础配置
# docker-compose.ymlversion:'3.8'services:web:image:myapp:latestports:-"80"environment:-NODE_ENV=productionhealthcheck:test:["CMD","curl","-f","http://localhost"]2.3 开发覆盖
# docker-compose.dev.ymlversion:'3.8'services:web:build:.ports:-"3000:3000"environment:-NODE_ENV=development-DEBUG=truevolumes:-.:/app-/app/node_modulescommand:npm run devhealthcheck:disable:true2.4 生产覆盖
# docker-compose.prod.ymlversion:'3.8'services:web:image:myapp:${TAG:-latest}ports:-"80:3000"environment:-NODE_ENV=productionrestart:alwayslogging:driver:json-fileoptions:max-size:"10m"max-file:"3"deploy:resources:limits:cpus:'1'memory:1G2.5 使用多文件
# 开发环境docker-compose-fdocker-compose.yml-fdocker-compose.dev.yml up-d# 测试环境docker-compose-fdocker-compose.yml-fdocker-compose.test.yml up-d# 生产环境docker-compose-fdocker-compose.yml-fdocker-compose.prod.yml up-d# 指定多个文件docker-compose-fbase.yml-fdev.yml-flocal.yml config3. 环境变量替换
3.1 基础使用
# docker-compose.ymlversion:'3.8'services:web:image:myapp:${TAG:-latest}ports:-"${WEB_PORT:-8080}:3000"environment:-DB_HOST=${DB_HOST:-localhost}-DB_PORT=${DB_PORT:-5432}-DB_USER=${DB_USER}-DB_PASSWORD=${DB_PASSWORD}3.2 .env 文件
# .env(默认加载)TAG=1.0.0WEB_PORT=80DB_HOST=postgresDB_PORT=5432DB_USER=myuserDB_PASSWORD=secret# .env.devTAG=devWEB_PORT=3000DEBUG=true# .env.prodTAG=latestWEB_PORT=80LOG_LEVEL=info# 使用特定 env 文件docker-compose--env-file .env.dev up-d# 合并多个 env 文件docker-compose--env-file .env --env-file .env.dev up-d3.3 Shell 环境变量
# 导出环境变量exportDB_HOST=prod-db.example.comexportDB_PASSWORD=prod-secret# 使用环境变量docker-composeup-d# 使用环境变量覆盖docker-composerun-eDB_HOST=test-db webbash4. 扩展字段
# docker-compose.ymlversion:'3.8'# 定义可复用的配置块x-logging:&default-loggingdriver:json-fileoptions:max-size:"10m"max-file:"3"x-resources:&default-resourcesresources:limits:cpus:'0.5'memory:512Mservices:web:image:nginxlogging:*default-loggingdeploy:*default-resourcesapi:image:myapilogging:*default-loggingdeploy:*default-resources# 覆盖部分配置worker:image:myworkerlogging:*default-loggingdeploy:resources:limits:cpus:'1'memory:1G5. 环境特定配置
5.1 开发环境
# docker-compose.override.yml(自动加载)version:'3.8'services:web:build:context:.target:developmentvolumes:-.:/app-/app/node_modulesenvironment:-NODE_ENV=development-DEBUG=app:*command:npm run devports:-"9229:9229"# Node.js 调试端口db:ports:-"5432:5432"environment:-POSTGRES_PASSWORD=devpassredis:ports:-"6379:6379"5.2 测试环境
# docker-compose.test.ymlversion:'3.8'services:web:build:context:.target:testenvironment:-NODE_ENV=test-DB_HOST=db-testdepends_on:-db-testcommand:npm testdb-test:image:postgres:13environment:-POSTGRES_DB=testdb-POSTGRES_USER=test-POSTGRES_PASSWORD=testtmpfs:-/var/lib/postgresql/data5.3 生产环境
# docker-compose.prod.ymlversion:'3.8'services:web:image:registry.example.com/myapp:${TAG}ports:-"80:3000"environment:-NODE_ENV=production-LOG_LEVEL=inforestart:alwayslogging:driver:syslogoptions:syslog-address:"tcp://syslog.example.com:514"tag:"myapp-web"deploy:replicas:3update_config:parallelism:1delay:10srestart_policy:condition:on-failuredb:image:postgres:13environment:-POSTGRES_PASSWORD_FILE=/run/secrets/db_passwordsecrets:-db_passwordvolumes:-db-data:/var/lib/postgresql/datadeploy:placement:constraints:[node.role == manager]secrets:db_password:external:true6. 配置模板示例
6.1 完整项目结构
project/ ├── docker-compose.yml ├── docker-compose.dev.yml ├── docker-compose.prod.yml ├── .env ├── .env.dev ├── .env.prod ├── config/ │ ├── dev/ │ │ └── nginx.conf │ └── prod/ │ └── nginx.conf └── scripts/ ├── dev-entrypoint.sh └── prod-entrypoint.sh6.2 Makefile 管理
# Makefile .PHONY: dev prod test clean dev: docker-compose -f docker-compose.yml -f docker-compose.dev.yml up -d prod: docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d test: docker-compose -f docker-compose.yml -f docker-compose.test.yml run --rm web npm test clean: docker-compose down -v logs-dev: docker-compose -f docker-compose.yml -f docker-compose.dev.yml logs -f exec-dev: docker-compose -f docker-compose.yml -f docker-compose.dev.yml exec web bash7. 最佳实践
✅ 推荐做法
- 基础配置放在 docker-compose.yml
- 环境特定配置放在独立文件
- 敏感信息使用环境变量或 secrets
- 使用 .env 文件管理环境变量
- 扩展字段复用配置
- 版本控制只提交基础配置
❌ 避免事项
- 硬编码敏感信息
- 在配置文件中使用不同的版本号
- 忘记 .gitignore 忽略 .env 文件
- 覆盖过于复杂导致难以维护
8. 常见问题
Q1: 如何查看合并后的配置?
docker-compose-fdocker-compose.yml-fdocker-compose.dev.yml configQ2: 环境变量优先级?
Shell 环境 > .env 文件 > Compose 文件
Q3: 如何忽略 .env 文件?
添加到 .gitignore:.env .env.* !.env.example
9. 小结
- 多文件覆盖:不同环境使用不同覆盖文件
- 环境变量:支持 .env 文件和 shell 变量
- 扩展字段:复用通用配置
- 敏感信息:使用 secrets 或环境变量
- 版本控制:提交示例文件,忽略真实配置
- Makefile:简化环境切换命令
