Docker Compose用YAML文件定义和管理多个Docker容器,一条命令即可启动完整的应用栈。在搬瓦工VPS上使用Docker Compose,可以方便地部署Web应用+数据库+缓存等多服务架构。本文介绍Docker Compose的核心概念和实战配置。
# 安装Docker
curl -fsSL https://get.docker.com | sh
# Docker Compose V2已集成在Docker CLI中
docker compose version
# 如果需要安装独立的docker-compose
sudo apt install docker-compose-plugin -y
# 启动Docker服务
sudo systemctl enable docker
sudo systemctl start docker
创建 docker-compose.yml 文件:
version: '3.8'
services:
web:
image: nginx:alpine
ports:
- "80:80"
volumes:
- ./html:/usr/share/nginx/html:ro
restart: unless-stopped
app:
build: .
ports:
- "3000:3000"
environment:
- NODE_ENV=production
- DB_HOST=db
depends_on:
- db
- redis
restart: unless-stopped
db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: rootpassword
MYSQL_DATABASE: myapp
MYSQL_USER: appuser
MYSQL_PASSWORD: apppassword
volumes:
- mysql_data:/var/lib/mysql
restart: unless-stopped
redis:
image: redis:7-alpine
volumes:
- redis_data:/data
restart: unless-stopped
volumes:
mysql_data:
redis_data:
完整的生产环境应用栈配置:
version: '3.8'
services:
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d:ro
- ./nginx/ssl:/etc/nginx/ssl:ro
- static_files:/var/www/static:ro
depends_on:
- app
networks:
- frontend
restart: unless-stopped
app:
build:
context: .
dockerfile: Dockerfile
expose:
- "3000"
environment:
- NODE_ENV=production
- DATABASE_URL=postgresql://user:pass@postgres:5432/mydb
- REDIS_URL=redis://redis:6379
volumes:
- static_files:/app/public
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_started
networks:
- frontend
- backend
restart: unless-stopped
deploy:
resources:
limits:
memory: 512M
postgres:
image: postgres:16-alpine
environment:
POSTGRES_DB: mydb
POSTGRES_USER: user
POSTGRES_PASSWORD: pass
volumes:
- postgres_data:/var/lib/postgresql/data
- ./init.sql:/docker-entrypoint-initdb.d/init.sql
healthcheck:
test: ["CMD-SHELL", "pg_isready -U user -d mydb"]
interval: 10s
timeout: 5s
retries: 5
networks:
- backend
restart: unless-stopped
redis:
image: redis:7-alpine
command: redis-server --appendonly yes --maxmemory 128mb
volumes:
- redis_data:/data
networks:
- backend
restart: unless-stopped
volumes:
postgres_data:
redis_data:
static_files:
networks:
frontend:
backend:
Docker Compose自动创建默认网络,也可以自定义网络隔离:
networks:
frontend:
driver: bridge
backend:
driver: bridge
internal: true # 内部网络,无法访问外网
# 服务中引用网络
services:
nginx:
networks:
- frontend # 只能与frontend网络中的服务通信
app:
networks:
- frontend # 与nginx通信
- backend # 与数据库通信
db:
networks:
- backend # 只在backend网络,nginx无法直接访问
# 命名卷(Docker管理存储位置)
volumes:
db_data:
driver: local
# 绑定挂载(指定宿主机路径)
services:
app:
volumes:
- ./config:/app/config:ro # 只读挂载
- ./uploads:/app/uploads # 读写挂载
- db_data:/var/lib/mysql # 命名卷
# 查看数据卷
docker volume ls
# 查看卷详情
docker volume inspect project_db_data
# 备份数据卷
docker run --rm -v project_db_data:/data -v $(pwd):/backup alpine \
tar czf /backup/db-backup.tar.gz /data
# 清理未使用的卷
docker volume prune
# 启动所有服务(后台运行)
docker compose up -d
# 查看服务状态
docker compose ps
# 查看日志
docker compose logs
docker compose logs -f app # 实时跟踪指定服务
docker compose logs --tail 50 # 最近50行
# 停止所有服务
docker compose down
# 停止并删除数据卷(谨慎操作)
docker compose down -v
# 重建镜像并启动
docker compose up -d --build
# 只重启指定服务
docker compose restart app
# 进入容器
docker compose exec app sh
docker compose exec db mysql -u root -p
# 查看资源占用
docker compose top
docker stats
# .env文件(与docker-compose.yml同目录,自动加载)
MYSQL_ROOT_PASSWORD=secure_password
MYSQL_DATABASE=myapp
APP_PORT=3000
# 在docker-compose.yml中引用
services:
db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: ${MYSQL_DATABASE}
app:
ports:
- "${APP_PORT}:3000"
# 拉取最新镜像
docker compose pull
# 重建并启动(只重建修改过的服务)
docker compose up -d --build
# 查看是否成功启动
docker compose ps
docker compose logs --tail 20
deploy.resources.limits 限制内存docker compose down -v 会删除所有数据Tip: 更多教程请查看新手教程。