Docker Compose 从入门到生产:多容器应用编排实战
单容器只能解决单个服务的问题,实际应用往往需要 Web + App + Database + Cache 多个服务协同工作。Docker Compose 用一个 YAML 文件定义和管理多容器应用,是开发和中小规模生产部署的利器。本文从基础语法到生产实践,全面讲解 Docker Compose 的使用。
一、Docker Compose 安装
# Docker Desktop 已内置(Windows/Mac) # Linux 独立安装(推荐 v2 版本,命令为 docker compose 而非 docker-compose) sudo apt install docker-compose-plugin # 验证 docker compose version
二、compose.yaml 结构详解
# compose.yaml(新版推荐命名,旧版为 docker-compose.yml)
version: '3.9' # 指定 Compose 文件格式版本
services:
# Web 前端(Nginx)
nginx:
image: nginx:1.25-alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d:ro # 只读挂载配置
- ./certbot/www:/var/www/certbot:ro # Let's Encrypt 验证
- ./certbot/conf:/etc/letsencrypt:ro # SSL 证书
depends_on:
app:
condition: service_healthy # 等待 app 健康检查通过后再启动
restart: unless-stopped # 非手动停止则自动重启
# 后端应用(Node.js)
app:
build:
context: . # Dockerfile 所在目录
dockerfile: Dockerfile
target: production # 多阶段构建的目标阶段
environment:
- NODE_ENV=production
- DB_HOST=db # 用 service 名称替代 IP
- DB_PORT=3306
- DB_NAME=myapp
- DB_PASS=${DB_PASSWORD} # 从 .env 文件或环境变量读取
- REDIS_URL=redis://cache:6379
secrets:
- db_password # Docker Secrets 管理敏感信息
depends_on:
db:
condition: service_healthy
cache:
condition: service_started
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
interval: 30s
timeout: 5s
retries: 3
restart: unless-stopped
# MySQL 数据库
db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: myapp
MYSQL_USER: appuser
MYSQL_PASSWORD: ${DB_PASSWORD}
volumes:
- db_data:/var/lib/mysql # 命名卷持久化数据
- ./mysql/init.sql:/docker-entrypoint-initdb.d/init.sql:ro # 初始化 SQL
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 10s
retries: 5
restart: unless-stopped
# Redis 缓存
cache:
image: redis:7-alpine
command: redis-server --requirepass ${REDIS_PASSWORD} --maxmemory 512mb --maxmemory-policy allkeys-lru
volumes:
- redis_data:/data
restart: unless-stopped
volumes:
db_data: # 数据库数据卷(默认 local driver,数据存在 Docker 管理目录)
redis_data:
secrets:
db_password:
environment: DB_PASSWORD # 从环境变量创建 Secret
三、.env 文件管理环境变量
# .env(此文件不要提交到 Git!加入 .gitignore) MYSQL_ROOT_PASSWORD=MyRootPass@2026 DB_PASSWORD=MyAppPass@2026 REDIS_PASSWORD=MyRedisPass@2026 # .env.example(提交到 Git,作为模板) MYSQL_ROOT_PASSWORD=your_root_password_here DB_PASSWORD=your_app_password_here REDIS_PASSWORD=your_redis_password_here
四、常用 Compose 命令
docker compose up -d # 后台启动所有服务 docker compose up --build -d # 重新构建镜像后启动 docker compose down # 停止并删除容器(保留数据卷) docker compose down -v # 停止并删除容器 + 数据卷(谨慎!会删数据) docker compose ps # 查看服务状态 docker compose logs -f app # 实时查看 app 服务日志 docker compose exec app bash # 进入 app 容器 docker compose restart app # 重启 app 服务(不重建) # 只更新 app 服务(不重启其他服务) docker compose up -d --no-deps --build app docker compose pull # 拉取最新镜像 docker compose config # 验证并输出最终配置(调试用)
五、多环境配置(dev/staging/prod)
# 文件结构
compose.yaml # 公共基础配置
compose.dev.yaml # 开发环境覆盖
compose.prod.yaml # 生产环境覆盖
# compose.dev.yaml(开发环境:挂载源码、开 debug 模式)
services:
app:
volumes:
- .:/app # 挂载源码,实时生效
environment:
- NODE_ENV=development
- DEBUG=*
ports:
- "9229:9229" # Node.js 调试端口
# 使用多文件启动
docker compose -f compose.yaml -f compose.dev.yaml up -d
六、健康检查与服务依赖
depends_on 默认只等待容器启动,不等待服务就绪。使用 condition: service_healthy + healthcheck 才能确保数据库真正可用后再启动应用:
db:
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-p${MYSQL_ROOT_PASSWORD}"]
interval: 10s
timeout: 5s
retries: 5
start_period: 30s # 容器启动后30秒内的失败不计入重试
七、生产环境注意事项
- 不要用 latest 标签:指定精确版本(如 mysql:8.0.36),避免意外升级
- 日志驱动:配置
logging.options.max-size防止日志文件撑爆磁盘 - 资源限制:为每个服务配置
deploy.resources.limits(CPU/内存上限) - 数据卷备份:定期备份 db_data 卷,不能依赖容器本身
总结
Docker Compose 是中小项目容器化部署的首选方案。它简单直观,一个 YAML 文件描述整个应用栈,几条命令完成部署。掌握多文件多环境配置、健康检查依赖、.env 环境变量管理,你的 Compose 使用就能从”能跑”升级为”生产可用”。
