关于 docker-compose
用于通过 Docker Compose 定义和运行多服务应用的速查技能,面向开发者提供配置示例、命令、故障排查及生产环境准备建议。
主要功能
- 01多服务 Compose 示例
- 02启动与停止命令
- 03开发环境覆盖配置
- 04环境文件配置
- 05生产安全与健康检查
- 06网络与故障排查
适用场景
- 01运行应用及其依赖服务
- 02区分开发与生产配置
- 03排查服务、网络或卷的问题
MCP 相关
该技能引用 `mcp__documentation__fetch_docs` 获取完整的 Docker Compose 文档。
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ claude-dev-suite/ claude-dev-suite --skill docker-compose安装后在 Claude Code 中输入/docker-compose确认已加载。
附带文件quick-ref/commands.mdquick-ref/services.md
详细介绍
Docker Compose 核心知识
深入了解:使用
mcp__documentation__fetch_docs,并将技术设为docker-compose,获取全面的文档。
全栈示例
# docker-compose.yml
services:
app:
build:
context: .
dockerfile: Dockerfile
ports:
- "3000:3000"
environment:
- DATABASE_URL=postgresql://user:pass@db:5432/mydb
- REDIS_URL=redis://redis:6379
depends_on:
db:
condition: service_healthy
redis:
condition: service_started
volumes:
- ./src:/app/src # Dev hot reload
networks:
- app-network
db:
image: postgres:16-alpine
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: pass
POSTGRES_DB: mydb
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U user -d mydb"]
interval: 5s
timeout: 5s
retries: 5
networks:
- app-network
redis:
image: redis:7-alpine
volumes:
- redis_data:/data
networks:
- app-network
volumes:
postgres_data:
redis_data:
networks:
app-network:
driver: bridge
常用命令
# Start services
docker-compose up -d
docker-compose up --build # Rebuild images
# Stop
docker-compose down
docker-compose down -v # Remove volumes too
# Logs
docker-compose logs -f app
docker-compose logs --tail=100 app
# Execute
docker-compose exec app sh
docker-compose exec db psql -U user mydb
# Scale
docker-compose up -d --scale app=3
开发环境覆盖配置
# docker-compose.override.yml (auto-loaded)
services:
app:
build:
target: development
volumes:
- .:/app
- /app/node_modules
command: npm run dev
环境文件
services:
app:
env_file:
- .env
- .env.local
不适用此技能的情况
以下情况请跳过此技能:
- 创建单容器 Dockerfile——使用
docker技能 - 部署到生产环境 Kubernetes 集群——使用
kubernetes技能 - 设置 CI/CD 工作流——使用
github-actions技能 - 使用 Docker Swarm(已弃用)——使用
kubernetes技能 - 仅构建 Docker 镜像(无需编排)——使用
docker技能
反模式
| 反模式 | 问题 | 解决方案 |
|---|---|---|
| 在 compose 中硬编码端口 | 端口冲突,缺乏灵活性 | 使用 ${PORT:-3000}:3000 和环境变量 |
| 没有健康检查 | 服务尚未就绪便启动 | 添加 healthcheck 和 depends_on.condition |
| 对外公开所有端口 | 存在安全风险 | 仅供本地访问时,绑定到 127.0.0.1:port |
使用 latest 标签 | 行为不可预测 | 固定具体版本,如 postgres:16-alpine |
| 在 compose 文件中存储机密 | 机密暴露 | 使用 Docker secrets 或环境文件(加入 gitignore) |
| 没有资源限制 | 资源耗尽 | 设置 deploy.resources.limits |
| 混用开发和生产配置 | 配置漂移 | 使用 docker-compose.override.yml 和 .prod.yml |
| 不使用命名卷 | 重建时数据丢失 | 使用命名卷持久化数据 |
| 服务使用默认网络 | 缺少隔离 | 为每个层级创建自定义网络 |
| 以 root 身份运行 | 安全漏洞 | 设置 user: "1000:1000" 或在 Dockerfile 中使用 USER |
快速故障排查
| 问题 | 诊断 | 修复方法 |
|---|---|---|
| 服务无法启动 | 依赖项尚未就绪 | 添加带有 condition: service_healthy 的 depends_on |
| 端口已被占用 | 另一个服务正在使用该端口 | 更改端口映射或停止冲突的服务 |
| 数据库连接被拒绝 | 服务名称错误,或存在网络问题 | 使用服务名称作为主机:db:5432,而不是 localhost |
| 更改未生效 | 旧容器仍在运行 | 运行 docker-compose down && docker-compose up --build |
| 卷数据未持久化 | 使用了匿名卷 | 在顶层 volumes: 中使用命名卷 |
| “network not found” | 网络已移除或名称错误 | 运行 docker-compose up 重新创建网络 |
| 服务之间无法连接 | 使用了不同的网络 | 将服务放在同一网络中 |
| 环境变量不起作用 | 语法错误或未加载 | 使用 ${VAR:-default} 并检查 .env 文件 |
| “service unhealthy” | 健康检查失败 | 检查 docker-compose logs 并修复健康检查端点 |
| Mac/Windows 上启动缓慢 | 卷挂载开销较大 | 对依赖项使用命名卷,而不是绑定挂载 |
生产环境就绪性
安全配置
# docker-compose.prod.yml
services:
app:
image: myapp:${VERSION:-latest}
security_opt:
- no-new-privileges:true
read_only: true
tmpfs:
- /tmp
cap_drop:
- ALL
cap_add:
- NET_BIND_SERVICE
user: "1000:1000"
deploy:
resources:
limits:
cpus: '2'
memory: 2G
reservations:
cpus: '0.5'
memory: 512M
db:
image: postgres:16-alpine
environment:
POSTGRES_PASSWORD_FILE: /run/secrets/db_password
secrets:
- db_password
volumes:
- postgres_data:/var/lib/postgresql/data:Z
secrets:
db_password:
file: ./secrets/db_password.txt
健康检查
services:
app:
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
db:
healthcheck:
test: ["CMD-SHELL", "pg_isready -U $POSTGRES_USER -d $POSTGRES_DB"]
interval: 10s
timeout: 5s
retries: 5
redis:
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 3
网络
services:
app:
networks:
- frontend
- backend
ports:
- "127.0.0.1:3000:3000" # Only localhost
db:
networks:
- backend
# No ports exposed externally
nginx:
networks:
- frontend
ports:
- "80:80"
- "443:443"
networks:
frontend:
driver: bridge
backend:
driver: bridge
internal: true # No internet access
日志记录
services:
app:
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"
labels: "service,environment"
labels:
- "service=app"
- "environment=production"
# Or use external logging
app:
logging:
driver: fluentd
options:
fluentd-address: localhost:24224
tag: "docker.{{.Name}}"
重启策略
services:
app:
restart: unless-stopped
deploy:
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
window: 120s
db:
restart: always
备份策略
services:
backup:
image: postgres:16-alpine
entrypoint: /bin/sh
command: -c "pg_dump -h db -U $$POSTGRES_USER $$POSTGRES_DB | gzip > /backups/backup_$$(date +%Y%m%d_%H%M%S).sql.gz"
environment:
PGPASSWORD_FILE: /run/secrets/db_password
secrets:
- db_password
volumes:
- ./backups:/backups
depends_on:
db:
condition: service_healthy
profiles:
- backup
测试
# docker-compose.test.yml
services:
test:
build:
context: .
target: test
environment:
- DATABASE_URL=postgresql://test:test@db-test:5432/testdb
depends_on:
db-test:
condition: service_healthy
command: npm test
db-test:
image: postgres:16-alpine
environment:
POSTGRES_USER: test
POSTGRES_PASSWORD: test
POSTGRES_DB: testdb
tmpfs:
- /var/lib/postgresql/data # In-memory for speed
# Run tests
docker-compose -f docker-compose.test.yml up --abort-on-container-exit --exit-code-from test
监控指标
| 指标 | 目标 |
|---|---|
| 容器运行时间 | > 99.9% |
| 健康检查通过率 | 100% |
| 重启次数 | < 1/天 |
| 内存使用量 | < 限额的 80% |
检查清单
- 安全选项(no-new-privileges、read_only)
- 资源限制(CPU、内存)
- 为所有服务配置健康检查
- 为数据库配置内部网络
- 机密管理(不要使用环境变量)
- 配置带轮转的日志记录
- 配置重启策略
- 制定备份策略
- 测试 compose 文件
- 生产环境覆盖文件
参考文档
评论
支持 Markdown