Compose 基础
docker-compose.yml 结构
version: '3.8' # Compose 文件版本
services:# 定义服务
web:# 服务名称
image: nginx:latest# 使用镜像
build: .# 或从 Dockerfile 构建
ports:# 端口映射
- "8080:80"
environment:# 环境变量
- NODE_ENV=production
volumes:# 卷挂载
- ./data:/data
depends_on:# 依赖关系
- db
networks:# 网络
- frontend
db:
image: postgres:15
environment:
POSTGRES_PASSWORD: example
volumes:
- db-data:/var/lib/postgresql/data
networks:
- backend
networks:# 定义网络
frontend:
backend:
volumes:# 定义卷
db-data:
________________________________________________________________________________
5.2 Compose 常用命令
# ============ 启动和管理服务 ============
# 启动服务(后台运行)
docker-compose up -d
# 启动服务(前台运行,查看日志)
docker-compose up
# 强制重新构建镜像
docker-compose up -d --build
# 创建并启动服务(不使用缓存)
docker-compose build --no-cache
docker-compose up -d
# 停止服务
docker-compose stop
# 停止并删除容器、网络
docker-compose down
# 停止并删除容器、网络、卷
docker-compose down -v
# 重启服务
docker-compose restart
# 重启单个服务
docker-compose restart web
# ============ 查看服务状态 ============
# 查看运行中的服务
docker-compose ps
# 查看服务日志
docker-compose logs
# 查看特定服务日志
docker-compose logs web
# 实时查看日志
docker-compose logs -f
# 查看最后100行日志
docker-compose logs --tail=100 web
# ============ 构建和管理镜像 ============
# 构建镜像
docker-compose build
# 构建特定服务
docker-compose build web
# 构建时不使用缓存
docker-compose build --no-cache
# 查看服务使用的镜像
docker-compose images
# ============ 执行命令 ============
# 在运行的容器中执行命令
docker-compose exec web bash
# 在新容器中运行一次性命令
docker-compose run web python manage.py migrate
# 运行命令并自动删除容器
docker-compose run --rm web python manage.py shell
# ============ 扩展服务 ============
# 扩展服务实例数量
docker-compose up -d --scale web=3
# ============ 其他命令 ============
# 暂停服务
docker-compose pause
# 恢复服务
docker-compose unpause
# 查看服务之间的端口映射
docker-compose port web 80
# 列出所有容器(包括停止的)
docker-compose ps -a
# 验证 Compose 文件
docker-compose config
# 查看最终配置(合并环境变量后)
docker-compose config --resolve-image-digests
_____________________________
5.3 实战 Compose 配置
完整的 Web 应用栈
version: '3.8'
services:
# ========== Nginx 反向代理 ==========
nginx:
image: nginx:alpine
container_name: app_nginx
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
- static_files:/app/static:ro
- media_files:/app/media:ro
depends_on:
- web
networks:
- frontend
restart: unless-stopped
healthcheck:
test: ["CMD", "wget", "-q", "--spider", "http://localhost/health"]
interval: 30s
timeout: 5s
retries: 3
# ========== Web 应用 ==========
web:
build:
context: .
dockerfile: Dockerfile
args:
- BUILD_ENV=production
container_name: app_web
command: gunicorn config.wsgi:application --bind 0.0.0.0:8000
volumes:
- static_files:/app/static
- media_files:/app/media
env_file:
- .env.production
environment:
- DATABASE_URL=postgresql://postgres:password@db:5432/appdb
- REDIS_URL=redis://redis:6379/0
depends_on:
db:
condition: service_healthy
redis:
condition: service_started
networks:
- frontend
- backend
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/health/"]
interval: 30s
timeout: 5s
retries: 3
start_period: 40s
# ========== PostgreSQL 数据库 ==========
db:
image: postgres:15-alpine
container_name: app_db
volumes:
- postgres_data:/var/lib/postgresql/data
- ./init.sql:/docker-entrypoint-initdb.d/init.sql:ro
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=password
- POSTGRES_DB=appdb
- PGDATA=/var/lib/postgresql/data/pgdata
networks:
- backend
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
shm_size: 128mb
# ========== Redis 缓存 ==========
redis:
image: redis:7-alpine
container_name: app_redis
command: redis-server --appendonly yes --requirepass redispassword
volumes:
- redis_data:/data
networks:
- backend
restart: unless-stopped
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
# ========== Celery Worker ==========
celery_worker:
build:
context: .
dockerfile: Dockerfile
container_name: app_celery_worker
command: celery -A config worker -l info
volumes:
- static_files:/app/static
- media_files:/app/media
env_file:
- .env.production
environment:
- DATABASE_URL=postgresql://postgres:password@db:5432/appdb
- REDIS_URL=redis://redis:6379/0
depends_on:
- db
- redis
networks:
- backend
restart: unless-stopped
# ========== Celery Beat ==========
celery_beat:
build:
context: .
dockerfile: Dockerfile
container_name: app_celery_beat
command: celery -A config beat -l info
volumes:
- ./celerybeat-schedule:/app/celerybeat-schedule
env_file:
- .env.production
environment:
- REDIS_URL=redis://redis:6379/0
depends_on:
- redis
networks:
- backend
restart: unless-stopped
# ========== Flower 监控 ==========
flower:
build:
context: .
dockerfile: Dockerfile
container_name: app_flower
command: celery -A config flower --port=5555
ports:
- "5555:5555"
environment:
- REDIS_URL=redis://redis:6379/0
- FLOWER_BASIC_AUTH=admin:admin123
depends_on:
- redis
networks:
- backend
restart: unless-stopped
networks:
frontend:
driver: bridge
backend:
driver: bridge
volumes:
postgres_data:
driver: local
redis_data:
driver: local
static_files:
driver: local
media_files:
driver: local
环境变量文件 (.env.production)
# .env.production
DATABASE_URL=postgresql://postgres:password@db:5432/appdb
REDIS_URL=redis://redis:6379/0
SECRET_KEY=your-secret-key-here
DEBUG=False
ALLOWED_HOSTS=yourdomain.com,www.yourdomain.com
EMAIL_HOST=smtp.gmail.com
EMAIL_PORT=587
EMAIL_USE_TLS=True
AWS_ACCESS_KEY_ID=your-access-key
AWS_SECRET_ACCESS_KEY=your-secret-key
AWS_S3_BUCKET=your-bucket-name
