Skip to main content Instalar con Codex o Claude Copia este prompt, pégalo en Codex, Claude u otro asistente, y deja que revise la página de la skill y la instale por ti.
Un comando directo omite el prompt de revisión. Revisa el origen antes de ejecutarlo.
npx skills add https://github.com/microwind/ai-skills --skill docker-composeEl comando permanece en una sola línea. Desplázate horizontalmente para revisarlo antes de copiarlo.
¿Prefieres una copia local? Descarga los archivos que SkillsMP tiene disponibles ahora.
Ocupaciones relacionadasSOC
Basado en la clasificación ocupacional SOC
Explorador de archivos
3 archivos| name | Docker Compose编排 |
| description | 当编排容器时,分析服务依赖,优化配置管理,解决网络问题。验证容器架构,设计部署策略,和最佳实践。 |
| license | MIT |
Docker Compose编排技能
概述
Docker Compose是定义和运行多容器Docker应用程序的工具,通过YAML文件配置服务、网络和卷,实现容器化应用的快速部署和管理。不当的Compose配置会导致服务启动失败、资源浪费、网络通信问题。
核心原则: 好的Compose配置应该服务独立、依赖明确、资源合理、网络清晰。坏的配置会导致服务耦合、启动顺序混乱、资源冲突。
何时使用
始终:
- 开发环境搭建时
- 微服务本地测试时
- CI/CD流水线构建时
- 多服务应用部署时
- 环境隔离管理时
- 服务编排测试时
触发短语:
- "如何配置Docker Compose?"
- "服务依赖管理"
- "容器网络配置"
- "数据卷持久化"
- "环境变量管理"
- "服务健康检查"
Docker Compose编排技能功能
服务配置
- 镜像构建管理
- 容器启动配置
- 环境变量设置
- 端口映射管理
- 资源限制配置
- 健康检查设置
依赖管理
- 服务依赖关系
- 启动顺序控制
- 等待条件设置
- 依赖检查机制
- 故障恢复策略
- 重启策略配置
网络配置
- 自定义网络创建
- 服务发现配置
- 网络隔离设置
- 端口暴露管理
- 负载均衡配置
- DNS解析设置
数据管理
- 数据卷创建
- 持久化存储
- 备份恢复策略
- 数据同步机制
- 权限管理设置
- 存储优化配置
常见问题
❌ 服务启动失败
- 镜像拉取失败
- 端口冲突
- 环境变量错误
- 依赖服务未就绪
- 资源不足
❌ 网络通信问题
- 服务间无法通信
- DNS解析失败
- 端口映射错误
- 网络隔离配置错误
- 防火墙阻拦
❌ 数据持久化问题
- 数据丢失
- 权限错误
- 存储空间不足
- 备份策略缺失
- 数据同步失败
❌ 资源管理问题
- 内存溢出
- CPU使用过高
- 磁盘空间不足
- 容器重启频繁
- 性能瓶颈
代码示例
基础Web应用Compose配置
version: '3.8'
services:
web:
build:
context: ./web
dockerfile: Dockerfile
args:
NODE_ENV: production
image: myapp/web:latest
container_name: myapp-web
restart: unless-stopped
ports:
- "3000:3000"
environment:
- NODE_ENV=production
- API_URL=http://api:8000
- REDIS_URL=redis://redis:6379
volumes:
- ./web/logs:/app/logs
- web_uploads:/app/uploads
depends_on:
api:
condition: service_healthy
redis:
condition: service_started
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
interval: 30s
timeout: 10s
retries:
[, , , ]
[, ]
[, , , , ]
[, , , ]
开发环境配置
version: '3.8'
services:
web:
build:
context: ./web
dockerfile: Dockerfile.dev
image: myapp/web:dev
container_name: myapp-web-dev
ports:
- "3000:3000"
- "9229:9229"
environment:
- NODE_ENV=development
- API_URL=http://localhost:8000
- REDIS_URL=redis://localhost:6379
volumes:
- ./web:/app
- /app/node_modules
- web_dev_logs:/app/logs
command: npm run dev
depends_on:
- api
- redis
networks:
- dev-network
api:
build:
context: ./api
dockerfile: Dockerfile.dev
image:
[, ]
生产环境配置
version: '3.8'
services:
web:
image: myapp/web:${VERSION}
container_name: myapp-web-prod
restart: always
environment:
- NODE_ENV=production
- API_URL=https://api.myapp.com
- REDIS_URL=redis://redis:6379
deploy:
replicas: 3
resources:
limits:
cpus: '1.0'
memory: 512M
reservations:
cpus: '0.5'
memory: 256M
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
window: 120s
update_config:
parallelism: 1
delay: 10s
failure_action: rollback
monitor: 60s
max_failure_ratio: 0.3
healthcheck:
[, , , ]
[, , , ]
[, ]
[, , , , ]
[, , , ]
自动化部署脚本
#!/bin/bash
set -e
PROJECT_NAME="myapp"
ENVIRONMENT=${1:-development}
VERSION=${2:-latest}
COMPOSE_FILE="docker-compose.yml"
ENV_FILE=".env.${ENVIRONMENT}"
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
log_info() {
echo -e "${GREEN}[INFO]${NC} $1"
}
log_warn() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
check_dependencies() {
log_info "检查依赖..."
if ! command -v docker &> /dev/null; then
log_error "Docker未安装"
exit 1
fi
if ! command -v docker-compose &> /dev/null; then
log_error "Docker Compose未安装"
exit 1
! docker info &> /dev/null;
log_error
1
log_info
}
() {
log_info
[ -f ];
$( | grep -v | xargs)
log_info
log_warn
VERSION=
ENVIRONMENT=
}
() {
log_info
)
docker-compose -f docker-compose.dev.yml build
;;
)
docker-compose -f docker-compose.prod.yml build
;;
*)
docker-compose build
;;
log_info
}
() {
log_info
)
docker-compose -f docker-compose.dev.yml up -d
;;
)
docker-compose -f docker-compose.prod.yml up -d
;;
*)
docker-compose up -d
;;
log_info
}
() {
log_info
max_attempts=30
attempt=1
[ -le ];
log_info
docker-compose ps | grep -q ;
log_info
0
10
((attempt++))
log_error
docker-compose ps
1
}
() {
log_info
)
docker-compose -f docker-compose.dev.yml -T api python manage.py migrate
;;
)
docker-compose -f docker-compose.prod.yml -T api python manage.py migrate
;;
*)
docker-compose -T api python manage.py migrate
;;
log_info
}
() {
log_info
backup_dir=
timestamp=$( +%Y%m%d_%H%M%S)
backup_file=
-p
)
docker-compose -f docker-compose.dev.yml -T postgres pg_dump -U dev myapp_dev >
;;
)
docker-compose -f docker-compose.prod.yml -T postgres pg_dump -U prod_user myapp_prod >
;;
*)
docker-compose -T postgres pg_dump -U user myapp >
;;
log_info
}
() {
log_info
docker image prune -f
images_to_keep=3
docker images --format | \
grep | \
-n +$((images_to_keep + )) | \
awk | \
xargs -r docker rmi
log_info
}
() {
log_info
docker-compose ps
log_info
docker-compose logs --=50
}
() {
target_version=
[ -z ];
log_error
1
log_warn
docker-compose down
VERSION=
build_images
start_services
health_check
log_info
}
() {
=
)
check_dependencies
load_environment
build_images
start_services
health_check
run_migrations
show_status
;;
)
check_dependencies
load_environment
build_images
docker-compose up -d
health_check
;;
)
log_info
docker-compose down
;;
)
log_info
docker-compose restart
health_check
;;
)
docker-compose logs -f
;;
)
show_status
;;
)
backup_database
;;
)
cleanup_images
;;
)
rollback
;;
)
health_check
;;
*)
1
;;
}
main
监控和日志管理
version: '3.8'
services:
prometheus:
image: prom/prometheus:latest
container_name: prometheus
restart: unless-stopped
ports:
- "9090:9090"
volumes:
- ./monitoring/prometheus.yml:/etc/prometheus/prometheus.yml:ro
- prometheus_data:/prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
- '--web.console.libraries=/etc/prometheus/console_libraries'
- '--web.console.templates=/etc/prometheus/consoles'
- '--storage.tsdb.retention.time=200h'
- '--web.enable-lifecycle'
networks:
- monitoring
grafana:
image: grafana/grafana:latest
container_name: grafana
restart: unless-stopped
ports:
- "3001:3000"
environment:
- GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PASSWORD}
最佳实践
配置管理
- 环境分离: 开发、测试、生产环境分别配置
- 变量管理: 使用环境变量管理敏感信息
- 版本控制: 镜像版本标签化管理
- 配置验证: 启动前验证配置正确性
服务设计
- 单一职责: 每个容器只运行一个主进程
- 无状态设计: 服务无状态,便于水平扩展
- 优雅关闭: 处理SIGTERM信号
- 健康检查: 实现健康检查端点
网络安全
- 网络隔离: 使用自定义网络隔离服务
- 最小权限: 只开放必要的端口
- 内部通信: 敏感服务使用内部网络
- SSL/TLS: 生产环境启用HTTPS
资源优化
- 资源限制: 设置CPU和内存限制
- 日志管理: 配置日志轮转和清理
- 镜像优化: 使用多阶段构建减小镜像大小
- 缓存策略: 合理使用Docker层缓存
相关技能
3
start_period:
40s
networks:
-
app-network
deploy:
resources:
limits:
cpus:
'0.5'
memory:
512M
reservations:
cpus:
'0.25'
memory:
256M
api:
build:
context:
./api
dockerfile:
Dockerfile
image:
myapp/api:latest
container_name:
myapp-api
restart:
unless-stopped
ports:
-
"8000:8000"
environment:
-
DATABASE_URL=postgresql://user:password@postgres:5432/myapp
-
REDIS_URL=redis://redis:6379
-
JWT_SECRET=${JWT_SECRET}
-
DEBUG=false
volumes:
-
./api/logs:/app/logs
-
api_data:/app/data
depends_on:
postgres:
condition:
service_healthy
redis:
condition:
service_started
healthcheck:
test:
"CMD"
"curl"
"-f"
"http://localhost:8000/health"
interval:
30s
timeout:
10s
retries:
3
start_period:
40s
networks:
-
app-network
-
db-network
deploy:
resources:
limits:
cpus:
'1.0'
memory:
1G
reservations:
cpus:
'0.5'
memory:
512M
postgres:
image:
postgres:15-alpine
container_name:
myapp-postgres
restart:
unless-stopped
ports:
-
"5432:5432"
environment:
-
POSTGRES_DB=myapp
-
POSTGRES_USER=user
-
POSTGRES_PASSWORD=password
-
POSTGRES_INITDB_ARGS=--encoding=UTF-8
--lc-collate=C
--lc-ctype=C
volumes:
-
postgres_data:/var/lib/postgresql/data
-
./postgres/init:/docker-entrypoint-initdb.d
-
./postgres/config/postgresql.conf:/etc/postgresql/postgresql.conf
healthcheck:
test:
"CMD-SHELL"
"pg_isready -U user -d myapp"
interval:
10s
timeout:
5s
retries:
5
start_period:
30s
networks:
-
db-network
deploy:
resources:
limits:
cpus:
'0.5'
memory:
1G
reservations:
cpus:
'0.25'
memory:
512M
redis:
image:
redis:7-alpine
container_name:
myapp-redis
restart:
unless-stopped
ports:
-
"6379:6379"
command:
redis-server
--appendonly
yes
--requirepass
${REDIS_PASSWORD}
volumes:
-
redis_data:/data
-
./redis/redis.conf:/usr/local/etc/redis/redis.conf
healthcheck:
test:
"CMD"
"redis-cli"
"--raw"
"incr"
"ping"
interval:
10s
timeout:
3s
retries:
5
start_period:
30s
networks:
-
app-network
deploy:
resources:
limits:
cpus:
'0.25'
memory:
256M
reservations:
cpus:
'0.1'
memory:
128M
nginx:
image:
nginx:alpine
container_name:
myapp-nginx
restart:
unless-stopped
ports:
-
"80:80"
-
"443:443"
volumes:
-
./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
-
./nginx/conf.d:/etc/nginx/conf.d:ro
-
./ssl:/etc/nginx/ssl:ro
-
nginx_logs:/var/log/nginx
depends_on:
-
web
-
api
healthcheck:
test:
"CMD"
"curl"
"-f"
"http://localhost/health"
interval:
30s
timeout:
10s
retries:
3
start_period:
30s
networks:
-
app-network
deploy:
resources:
limits:
cpus:
'0.25'
memory:
128M
reservations:
cpus:
'0.1'
memory:
64M
networks:
app-network:
driver:
bridge
ipam:
config:
-
subnet:
172.20
.0
.0
/16
gateway:
172.20
.0
.1
db-network:
driver:
bridge
ipam:
config:
-
subnet:
172.21
.0
.0
/16
gateway:
172.21
.0
.1
internal:
true
volumes:
postgres_data:
driver:
local
driver_opts:
type:
none
o:
bind
device:
/data/postgres
redis_data:
driver:
local
driver_opts:
type:
none
o:
bind
device:
/data/redis
web_uploads:
driver:
local
api_data:
driver:
local
nginx_logs:
driver:
local
myapp/api:dev
container_name:
myapp-api-dev
ports:
-
"8000:8000"
-
"5678:5678"
environment:
-
DATABASE_URL=postgresql://dev:dev@postgres-dev:5432/myapp_dev
-
REDIS_URL=redis://redis-dev:6379
-
JWT_SECRET=dev-secret
-
DEBUG=true
volumes:
-
./api:/app
-
api_dev_data:/app/data
-
api_dev_logs:/app/logs
command:
python
-m
debugpy
--listen
0.0
.0
.0
:5678
--wait-for-client
-m
uvicorn
main:app
--host
0.0
.0
.0
--port
8000
--reload
depends_on:
postgres-dev:
condition:
service_healthy
redis-dev:
condition:
service_started
networks:
-
dev-network
postgres-dev:
image:
postgres:15-alpine
container_name:
myapp-postgres-dev
ports:
-
"5433:5432"
environment:
-
POSTGRES_DB=myapp_dev
-
POSTGRES_USER=dev
-
POSTGRES_PASSWORD=dev
volumes:
-
postgres_dev_data:/var/lib/postgresql/data
-
./postgres/init-dev:/docker-entrypoint-initdb.d
healthcheck:
test:
"CMD-SHELL"
"pg_isready -U dev -d myapp_dev"
interval:
10s
timeout:
5s
retries:
5
networks:
-
dev-network
redis-dev:
image:
redis:7-alpine
container_name:
myapp-redis-dev
ports:
-
"6380:6379"
command:
redis-server
--appendonly
yes
volumes:
-
redis_dev_data:/data
networks:
-
dev-network
adminer:
image:
adminer:latest
container_name:
myapp-adminer
ports:
-
"8080:8080"
environment:
-
ADMINER_DEFAULT_SERVER=postgres-dev
depends_on:
-
postgres-dev
networks:
-
dev-network
redis-commander:
image:
rediscommander/redis-commander:latest
container_name:
myapp-redis-commander
ports:
-
"8081:8081"
environment:
-
REDIS_HOSTS=local:redis-dev:6379
depends_on:
-
redis-dev
networks:
-
dev-network
networks:
dev-network:
driver:
bridge
volumes:
postgres_dev_data:
redis_dev_data:
web_dev_logs:
api_dev_data:
api_dev_logs:
test:
"CMD"
"curl"
"-f"
"http://localhost:3000/health"
interval:
30s
timeout:
10s
retries:
3
start_period:
60s
logging:
driver:
"json-file"
options:
max-size:
"10m"
max-file:
"3"
networks:
-
prod-network
api:
image:
myapp/api:${VERSION}
container_name:
myapp-api-prod
restart:
always
environment:
-
DATABASE_URL=postgresql://prod_user:${DB_PASSWORD}@postgres:5432/myapp_prod
-
REDIS_URL=redis://redis:6379
-
JWT_SECRET=${JWT_SECRET}
-
DEBUG=false
deploy:
replicas:
2
resources:
limits:
cpus:
'2.0'
memory:
1G
reservations:
cpus:
'1.0'
memory:
512M
restart_policy:
condition:
on-failure
delay:
5s
max_attempts:
3
window:
120s
update_config:
parallelism:
1
delay:
10s
failure_action:
rollback
monitor:
60s
max_failure_ratio:
0.3
healthcheck:
test:
"CMD"
"curl"
"-f"
"http://localhost:8000/health"
interval:
30s
timeout:
10s
retries:
3
start_period:
60s
logging:
driver:
"json-file"
options:
max-size:
"10m"
max-file:
"3"
networks:
-
prod-network
-
db-network
postgres:
image:
postgres:15-alpine
container_name:
myapp-postgres-prod
restart:
always
environment:
-
POSTGRES_DB=myapp_prod
-
POSTGRES_USER=prod_user
-
POSTGRES_PASSWORD=${DB_PASSWORD}
volumes:
-
postgres_prod_data:/var/lib/postgresql/data
-
./backups:/backups
deploy:
resources:
limits:
cpus:
'2.0'
memory:
2G
reservations:
cpus:
'1.0'
memory:
1G
healthcheck:
test:
"CMD-SHELL"
"pg_isready -U prod_user -d myapp_prod"
interval:
10s
timeout:
5s
retries:
5
start_period:
30s
logging:
driver:
"json-file"
options:
max-size:
"10m"
max-file:
"3"
networks:
-
db-network
redis:
image:
redis:7-alpine
container_name:
myapp-redis-prod
restart:
always
command:
redis-server
--appendonly
yes
--requirepass
${REDIS_PASSWORD}
volumes:
-
redis_prod_data:/data
deploy:
resources:
limits:
cpus:
'0.5'
memory:
512M
reservations:
cpus:
'0.25'
memory:
256M
healthcheck:
test:
"CMD"
"redis-cli"
"--raw"
"incr"
"ping"
interval:
10s
timeout:
3s
retries:
5
start_period:
30s
logging:
driver:
"json-file"
options:
max-size:
"10m"
max-file:
"3"
networks:
-
prod-network
nginx:
image:
nginx:alpine
container_name:
myapp-nginx-prod
restart:
always
ports:
-
"80:80"
-
"443:443"
volumes:
-
./nginx/nginx.prod.conf:/etc/nginx/nginx.conf:ro
-
./nginx/conf.d:/etc/nginx/conf.d:ro
-
./ssl:/etc/nginx/ssl:ro
-
nginx_prod_logs:/var/log/nginx
depends_on:
-
web
-
api
deploy:
resources:
limits:
cpus:
'0.5'
memory:
128M
reservations:
cpus:
'0.25'
memory:
64M
healthcheck:
test:
"CMD"
"curl"
"-f"
"http://localhost/health"
interval:
30s
timeout:
10s
retries:
3
start_period:
30s
logging:
driver:
"json-file"
options:
max-size:
"10m"
max-file:
"3"
networks:
-
prod-network
networks:
prod-network:
driver:
bridge
driver_opts:
com.docker.network.bridge.name:
prod-network
db-network:
driver:
bridge
internal:
true
volumes:
postgres_prod_data:
driver:
local
redis_prod_data:
driver:
local
nginx_prod_logs:
driver:
local
fi
if
then
"Docker服务未运行"
exit
fi
"依赖检查通过"
load_environment
"加载环境变量: $ENVIRONMENT"
if
"$ENV_FILE"
then
export
cat
$ENV_FILE
'^#'
"环境变量加载完成"
else
"环境文件不存在: $ENV_FILE"
fi
export
$VERSION
export
$ENVIRONMENT
build_images
"构建镜像..."
case
$ENVIRONMENT
in
"development"
"production"
esac
"镜像构建完成"
start_services
"启动服务..."
case
$ENVIRONMENT
in
"development"
"production"
esac
"服务启动完成"
health_check
"等待服务健康检查..."
local
local
while
$attempt
$max_attempts
do
"健康检查尝试 $attempt/$max_attempts"
if
"Up (healthy)"
then
"服务健康检查通过"
return
fi
sleep
done
"健康检查失败"
return
run_migrations
"运行数据库迁移..."
case
$ENVIRONMENT
in
"development"
exec
"production"
exec
exec
esac
"数据库迁移完成"
backup_database
"备份数据库..."
local
"./backups"
local
date
local
"$backup_dir/postgres_backup_$timestamp.sql"
mkdir
$backup_dir
case
$ENVIRONMENT
in
"development"
exec
$backup_file
"production"
exec
$backup_file
exec
$backup_file
esac
"数据库备份完成: $backup_file"
cleanup_images
"清理旧镜像..."
local
"table {{.Repository}}\t{{.Tag}}\t{{.ID}}"
"^$PROJECT_NAME/"
tail
1
'{print $3}'
"镜像清理完成"
show_status
"服务状态:"
"服务日志:"
tail
rollback
local
$1
if
"$target_version"
then
"请指定回滚版本"
exit
fi
"回滚到版本: $target_version"
export
$target_version
"回滚完成"
main
local
command
${1:-deploy}
case
$command
in
"deploy"
"update"
"stop"
"停止服务..."
"restart"
"重启服务..."
"logs"
"status"
"backup"
"cleanup"
"rollback"
$2
"health"
echo
"用法: $0 {deploy|update|stop|restart|logs|status|backup|cleanup|rollback|health} [version]"
exit
esac
"$@"
-
GF_USERS_ALLOW_SIGN_UP=false
volumes:
-
grafana_data:/var/lib/grafana
-
./monitoring/grafana/dashboards:/etc/grafana/provisioning/dashboards:ro
-
./monitoring/grafana/datasources:/etc/grafana/provisioning/datasources:ro
depends_on:
-
prometheus
networks:
-
monitoring
node-exporter:
image:
prom/node-exporter:latest
container_name:
node-exporter
restart:
unless-stopped
ports:
-
"9100:9100"
volumes:
-
/proc:/host/proc:ro
-
/sys:/host/sys:ro
-
/:/rootfs:ro
command:
-
'--path.procfs=/host/proc'
-
'--path.rootfs=/rootfs'
-
'--path.sysfs=/host/sys'
-
'--collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($$|/)'
networks:
-
monitoring
cadvisor:
image:
gcr.io/cadvisor/cadvisor:latest
container_name:
cadvisor
restart:
unless-stopped
ports:
-
"8080:8080"
volumes:
-
/:/rootfs:ro
-
/var/run:/var/run:ro
-
/sys:/sys:ro
-
/var/lib/docker/:/var/lib/docker:ro
-
/dev/disk/:/dev/disk:ro
privileged:
true
devices:
-
/dev/kmsg
networks:
-
monitoring
elasticsearch:
image:
docker.elastic.co/elasticsearch/elasticsearch:8.8.0
container_name:
elasticsearch
restart:
unless-stopped
environment:
-
discovery.type=single-node
-
"ES_JAVA_OPTS=-Xms512m -Xmx512m"
-
xpack.security.enabled=false
ports:
-
"9200:9200"
volumes:
-
elasticsearch_data:/usr/share/elasticsearch/data
networks:
-
monitoring
logstash:
image:
docker.elastic.co/logstash/logstash:8.8.0
container_name:
logstash
restart:
unless-stopped
ports:
-
"5044:5044"
volumes:
-
./monitoring/logstash/pipeline:/usr/share/logstash/pipeline:ro
-
./monitoring/logstash/config/logstash.yml:/usr/share/logstash/config/logstash.yml:ro
depends_on:
-
elasticsearch
networks:
-
monitoring
kibana:
image:
docker.elastic.co/kibana/kibana:8.8.0
container_name:
kibana
restart:
unless-stopped
ports:
-
"5601:5601"
environment:
-
ELASTICSEARCH_HOSTS=http://elasticsearch:9200
depends_on:
-
elasticsearch
networks:
-
monitoring
networks:
monitoring:
driver:
bridge
volumes:
prometheus_data:
grafana_data:
elasticsearch_data: