Docker Compose 高級配置與多服務編排實戰 2026 | 容器編排完全指南

Docker Compose 是定義和運行多容器 Docker 應用程序的工具。從簡單的開發環境到複雜的生產部署,Compose 都能勝任。本文將深入 Compose 的高級特性,從環境變量管理到滾動更新,全面掌握容器編排技能。
一、Compose 文件結構
1.1 Compose 版本與基本結構
yaml
# docker-compose.yml
version: '3.8'
services:
web:
build: .
ports:
- "80:80"
depends_on:
- db
- redis
db:
image: postgres:15
volumes:
- pgdata:/var/lib/postgresql/data
redis:
image: redis:7-alpine
volumes:
pgdata:
networks:
default:
name: my-network1.2 常用配置項速查
| 配置項 | 說明 |
|---|---|
image | 使用的鏡像 |
build | 構建鏡像的上下文 |
ports | 端口映射 |
volumes | 數據卷掛載 |
environment | 環境變量 |
env_file | 環境變量文件 |
depends_on | 服務依賴 |
networks | 網絡配置 |
healthcheck | 健康檢查 |
restart | 重啟策略 |
deploy | 部署配置(Swarm) |
command | 覆蓋啟動命令 |
entrypoint | 覆蓋入口點 |
二、環境變量管理
2.1 多種環境變量方式
yaml
# 方式1:直接在 docker-compose.yml 中定義
services:
web:
image: nginx
environment:
- NODE_ENV=production
- API_URL=https://api.example.com
- DEBUG=false
# 方式2:鍵值對格式
services:
web:
image: nginx
environment:
NODE_ENV: production
API_URL: https://api.example.com2.2 使用 .env 文件
bash
# .env
NODE_ENV=production
API_URL=https://api.example.com
DB_PASSWORD=secret123
REDIS_URL=redis://redis:6379yaml
# docker-compose.yml
services:
web:
image: myapp
env_file:
- .env2.3 多環境配置
yaml
# docker-compose.base.yml - 基礎配置
services:
web:
build: .
volumes:
- ./src:/app/srcyaml
# docker-compose.dev.yml - 開發環境
services:
web:
environment:
- NODE_ENV=development
- DEBUG=true
ports:
- "3000:3000"
command: npm run dev
db:
image: postgres:15
ports:
- "5432:5432"yaml
# docker-compose.prod.yml - 生產環境
services:
web:
environment:
- NODE_ENV=production
ports:
- "80:3000"
restart: always
deploy:
replicas: 3bash
# 啟動開發環境
docker-compose -f docker-compose.base.yml -f docker-compose.dev.yml up -d
# 啟動生產環境
docker-compose -f docker-compose.base.yml -f docker-compose.prod.yml up -d2.4 變量替換
yaml
services:
web:
image: myapp:${VERSION:-latest}
ports:
- "${WEB_PORT:-8080}:3000"
environment:
- DB_HOST=${DB_HOST:-db}三、網絡配置
3.1 自定義網絡
yaml
services:
frontend:
image: nginx
networks:
- frontend
- backend
api:
image: myapi
networks:
- backend
- database
db:
image: postgres
networks:
- database
networks:
frontend:
name: frontend-net
driver: bridge
backend:
name: backend-net
driver: bridge
database:
name: database-net
driver: bridge
internal: true # 內部網絡,無法訪問外網3.2 網絡別名
yaml
services:
web:
image: nginx
networks:
frontend:
aliases:
- webserver
- nginx-server
app:
image: myapp
networks:
backend:
aliases:
- api-server3.3 主機網絡模式
yaml
services:
monitoring:
image: prom/prometheus
network_mode: host # 使用主機網絡
pid: host # 使用主機 PID 命名空間四、數據持久化
4.1 命名卷(推薦)
yaml
services:
db:
image: postgres:15
volumes:
- postgres_data:/var/lib/postgresql/data
redis:
image: redis:7
volumes:
- redis_data:/data
volumes:
postgres_data:
name: postgres-data
driver: local
redis_data:
name: redis-data
driver: local4.2 綁定掛載
yaml
services:
web:
image: nginx
volumes:
# 配置文件
- ./nginx.conf:/etc/nginx/nginx.conf:ro
# 靜態文件
- ./static:/usr/share/nginx/html:ro
# 日誌
- ./logs:/var/log/nginx
app:
image: myapp
volumes:
# 源代碼(開發用)
- ./src:/app/src
# 上傳文件
- ./uploads:/app/uploads4.3 tmpfs(內存文件系統)
yaml
services:
cache:
image: redis:7
tmpfs:
- /tmp
- /var/run4.4 卷的備份與恢復
bash
# 備份數據卷
docker run --rm \
-v postgres-data:/data \
-v $(pwd)/backup:/backup \
alpine tar czf /backup/postgres-backup.tar.gz /data
# 恢復數據卷
docker run --rm \
-v postgres-data:/data \
-v $(pwd)/backup:/backup \
alpine tar xzf /backup/postgres-backup.tar.gz -C /五、健康檢查
5.1 HTTP 健康檢查
yaml
services:
web:
image: nginx
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 10s5.2 TCP 健康檢查
yaml
services:
db:
image: postgres:15
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
start_period: 30s
redis:
image: redis:7
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 35.3 自定義健康檢查腳本
yaml
services:
app:
build: .
healthcheck:
test: ["CMD-SHELL", "node /app/scripts/healthcheck.js"]
interval: 30s
timeout: 10s
retries: 3
start_period: 15sjavascript
// scripts/healthcheck.js
const http = require('http')
const options = {
hostname: 'localhost',
port: 3000,
path: '/health',
method: 'GET'
}
const req = http.request(options, (res) => {
process.exit(res.statusCode === 200 ? 0 : 1)
})
req.on('error', () => {
process.exit(1)
})
req.end()5.4 服務依賴與健康檢查
yaml
services:
web:
image: myapp
depends_on:
db:
condition: service_healthy
redis:
condition: service_healthy
cache:
condition: service_started
db:
image: postgres:15
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
retries: 5
redis:
image: redis:7
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
retries: 3六、資源限制與性能調優
6.1 CPU 和內存限制
yaml
services:
web:
image: nginx
deploy:
resources:
limits:
cpus: '2.0'
memory: 1G
reservations:
cpus: '1.0'
memory: 512M6.2 ulimit 調優
yaml
services:
nginx:
image: nginx
ulimits:
nofile:
soft: 65536
hard: 65536
nproc: 655356.3 重啟策略
yaml
services:
web:
image: nginx
restart: unless-stopped # always | unless-stopped | on-failure | no
worker:
image: my-worker
restart: on-failure:5 # 失敗最多重啟 5 次七、多服務編排實戰
7.1 完整 Web 應用棧
yaml
# docker-compose.yml
version: '3.8'
services:
# Nginx 反向代理
nginx:
image: nginx:1.25-alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d:ro
- ./nginx/ssl:/etc/nginx/ssl:ro
- ./logs/nginx:/var/log/nginx
depends_on:
- web
- api
restart: unless-stopped
healthcheck:
test: ["CMD", "wget", "--spider", "http://localhost/health"]
interval: 30s
timeout: 10s
retries: 3
networks:
- frontend
- backend
# 前端應用
web:
image: my-web-app:latest
build:
context: ./web
dockerfile: Dockerfile
environment:
- NODE_ENV=production
- API_BASE_URL=https://api.example.com
restart: unless-stopped
healthcheck:
test: ["CMD", "wget", "--spider", "http://localhost:3000"]
interval: 30s
retries: 3
networks:
- backend
# API 服務
api:
image: my-api:latest
build:
context: ./api
dockerfile: Dockerfile
environment:
- NODE_ENV=production
- DB_HOST=db
- DB_PORT=5432
- REDIS_HOST=redis
- JWT_SECRET=${JWT_SECRET}
depends_on:
db:
condition: service_healthy
redis:
condition: service_healthy
restart: unless-stopped
healthcheck:
test: ["CMD", "wget", "--spider", "http://localhost:3001/health"]
interval: 30s
retries: 3
deploy:
replicas: 2
resources:
limits:
cpus: '1.0'
memory: 512M
networks:
- backend
- database
# PostgreSQL 數據庫
db:
image: postgres:15-alpine
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=${DB_PASSWORD}
- POSTGRES_DB=myapp
volumes:
- postgres_data:/var/lib/postgresql/data
- ./postgres/init:/docker-entrypoint-initdb.d:ro
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
networks:
- database
# Redis 緩存
redis:
image: redis:7-alpine
command: redis-server --appendonly yes --requirepass ${REDIS_PASSWORD}
volumes:
- redis_data:/data
restart: unless-stopped
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 3
networks:
- database
volumes:
postgres_data:
redis_data:
networks:
frontend:
name: frontend-net
backend:
name: backend-net
database:
name: database-net
internal: true7.2 啟動順序與依賴管理
bash
# 查看服務啟動順序
docker-compose config --services
# 只啟動某個服務及其依賴
docker-compose up -d web
# 查看服務狀態
docker-compose ps
# 查看服務日誌
docker-compose logs -f web
# 重啟某個服務
docker-compose restart api
# 縮容/擴容
docker-compose up -d --scale api=3八、生產環境部署
8.1 滾動更新
yaml
services:
web:
image: myapp:latest
deploy:
replicas: 3
update_config:
parallelism: 1 # 每次更新 1 個
delay: 10s # 間隔時間
failure_action: rollback # 失敗回滾
monitor: 30s # 監控時間
max_failure_ratio: 0.3 # 最大失敗率
rollback_config:
parallelism: 1
delay: 10s
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
window: 120s
resources:
limits:
cpus: '2.0'
memory: 1G
reservations:
cpus: '1.0'
memory: 512M8.2 零停機部署
bash
# 構建新版本鏡像
docker build -t myapp:v2 .
# 更新鏡像標籤
docker tag myapp:v2 myapp:latest
# 觸發滾動更新
docker-compose up -d --no-deps web
# 查看更新進度
docker-compose ps
docker-compose logs -f web8.3 藍綠部署
yaml
# docker-compose.blue.yml - 藍色環境
services:
web-blue:
image: myapp:v1
ports:
- "8080:3000"yaml
# docker-compose.green.yml - 綠色環境
services:
web-green:
image: myapp:v2
ports:
- "8081:3000"bash
# 1. 部署綠色環境
docker-compose -f docker-compose.green.yml up -d
# 2. 驗證綠色環境正常
curl http://localhost:8081/health
# 3. 切換流量(更新 Nginx 配置指向綠色環境)
# 4. 停止藍色環境
docker-compose -f docker-compose.blue.yml down九、常用命令與技巧
9.1 日常管理命令
bash
# 啟動服務
docker-compose up -d
docker-compose up -d --build # 構建後啟動
docker-compose up -d --force-recreate # 強制重建
# 停止服務
docker-compose stop
docker-compose down
docker-compose down -v # 刪除數據卷
# 查看狀態
docker-compose ps
docker-compose logs
docker-compose logs -f web
docker-compose logs --tail=100
# 進入容器
docker-compose exec web bash
docker-compose exec db psql -U postgres
# 查看配置
docker-compose config
docker-compose config --services
docker-compose config --volumes9.2 清理與維護
bash
# 刪除未使用的鏡像
docker image prune
# 刪除未使用的容器
docker container prune
# 刪除未使用的數據卷
docker volume prune
# 一鍵清理
docker system prune -a
# 查看磁盤使用
docker system df9.3 調試技巧
bash
# 查看容器啟動日誌
docker-compose logs web --no-log-prefix
# 查看實時資源使用
docker stats
# 進入容器調試
docker-compose exec web sh
# 複製文件到容器
docker cp ./local-file.txt mycontainer:/app/
# 從容器複製文件
docker cp mycontainer:/app/file.txt ./local/十、最佳實踐
10.1 配置管理
- 使用多文件配置:基礎配置 + 環境配置
- 敏感信息用 .env:不要提交到版本控制
- 使用變量替換:提高配置靈活性
- 配置文件分層:common / dev / staging / prod
10.2 安全建議
- 最小權限原則:容器以非 root 用戶運行
- 只讀文件系統:
read_only: true - 不暴露不必要的端口:只暴露需要的端口
- 使用內部網絡:數據庫等放在內部網絡
10.3 性能優化
- 合理設置資源限制:避免資源爭搶
- 使用命名卷:性能優於綁定掛載
- 健康檢查:及時發現故障
- 多副本部署:提高可用性
十一、總結
- ✅ 掌握 Compose 文件結構與常用配置
- ✅ 環境變量管理與多環境配置
- ✅ 網絡配置(自定義網絡、別名、內部網絡)
- ✅ 數據持久化(命名卷、綁定掛載、備份恢復)
- ✅ 健康檢查與服務依賴
- ✅ 資源限制與性能調優
- ✅ 多服務編排實戰(完整 Web 應用棧)
- ✅ 生產環境部署(滾動更新、藍綠部署)
- ✅ 常用命令與調試技巧
Docker Compose 是容器編排的入門利器,掌握這些高級配置技巧,讓你能夠輕鬆管理複雜的多容器應用。
相關閱讀: