Appearance
Compose 文件详解
docker-compose.yml 使用 YAML 格式,本节介绍所有常用配置项的详细说明。
文件结构
yaml
# Compose 文件版本(v2 已不需要指定 version)
# version: "3.9" # 可省略
services: # 服务定义
service-name:
...
networks: # 网络定义
network-name:
...
volumes: # 数据卷定义
volume-name:
...
configs: # 配置文件(Swarm 模式)
config-name:
...
secrets: # 密钥(Swarm 模式)
secret-name:
...services 服务配置
image — 使用现有镜像
yaml
services:
web:
image: nginx:alpine
db:
image: mysql:8.0
cache:
image: redis:7-alpinebuild — 构建镜像
yaml
services:
api:
# 简写:使用当前目录的 Dockerfile
build: .
# 完整写法
build:
context: ./api # 构建上下文
dockerfile: Dockerfile # Dockerfile 文件名
args: # 构建参数
NODE_ENV: production
VERSION: 1.0.0
target: production # 多阶段构建的目标阶段
cache_from: # 缓存来源
- myapp:latest
labels:
version: "1.0"ports — 端口映射
yaml
services:
web:
ports:
- "80:80" # 宿主机:容器
- "443:443"
- "8080" # 随机宿主机端口
- "127.0.0.1:8080:80" # 绑定到指定 IP
# 完整写法
ports:
- target: 80
published: 8080
protocol: tcp
mode: hostenvironment — 环境变量
yaml
services:
api:
environment:
# 键值对
NODE_ENV: production
PORT: 3000
# 引用 .env 文件或 shell 环境变量
DB_PASSWORD: ${DB_PASSWORD}
# 只写 key,从 shell 环境变量获取值
SECRET_KEY:
# 或者使用列表格式
environment:
- NODE_ENV=production
- PORT=3000env_file — 从文件加载环境变量
yaml
services:
api:
env_file:
- .env # 默认 .env 文件
- .env.local # 覆盖配置
- ./api/.env # 指定路径volumes — 挂载配置
yaml
services:
mysql:
volumes:
# 命名卷
- mysql-data:/var/lib/mysql
# 绑定挂载
- ./config/my.cnf:/etc/mysql/conf.d/custom.cnf:ro
- ./logs:/var/log/mysql
# 匿名卷
- /tmp/cache
# 完整写法
- type: volume
source: mysql-data
target: /var/lib/mysql
- type: bind
source: ./config
target: /etc/app/config
read_only: true
volumes:
mysql-data: # 声明命名卷networks — 网络配置
yaml
services:
api:
networks:
- backend
- frontend
# 完整写法(指定 IP、别名)
db:
networks:
backend:
ipv4_address: 172.20.0.10
aliases:
- database
networks:
backend:
driver: bridge
ipam:
config:
- subnet: 172.20.0.0/24
frontend:
driver: bridgedepends_on — 服务依赖
yaml
services:
api:
depends_on:
- db # 简写:db 启动后启动 api(不等待健康)
# 等待健康状态
depends_on:
db:
condition: service_healthy
redis:
condition: service_started # 仅等待启动
db:
image: mysql:8.0
healthcheck:
test: ["CMD", "mysqladmin", "ping"]
interval: 10s
retries: 5restart — 重启策略
yaml
services:
api:
restart: unless-stopped # 推荐生产使用
# 可选值:no / always / on-failure / unless-stopped
worker:
restart: on-failure:3 # 失败后最多重启 3 次command — 覆盖默认命令
yaml
services:
api:
image: node:20-alpine
command: node app.js # shell 格式
command: ["node", "app.js"] # exec 格式(推荐)
worker:
image: myapp
command: ["python", "worker.py", "--queue", "high"]entrypoint — 覆盖入口点
yaml
services:
app:
entrypoint: /entrypoint.sh
entrypoint: ["sh", "/entrypoint.sh"]healthcheck — 健康检查
yaml
services:
api:
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
# 禁用健康检查
worker:
healthcheck:
disable: truedeploy — 部署配置(Swarm 模式)
yaml
services:
api:
deploy:
replicas: 3 # 实例数
resources:
limits:
cpus: "0.5"
memory: 512M
reservations:
cpus: "0.25"
memory: 256M
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
update_config:
parallelism: 1 # 每次更新 1 个实例
delay: 10s # 每次更新间隔
failure_action: rollbacklogging — 日志配置
yaml
services:
api:
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"
# 输出到 syslog
worker:
logging:
driver: syslog
options:
syslog-address: "udp://loghost:514"labels — 标签
yaml
services:
api:
labels:
- "app=myapp"
- "env=production"
- "traefik.enable=true"
- "traefik.http.routers.api.rule=Host(`api.example.com`)"profiles — 服务配置集
yaml
services:
api:
image: myapi # 总是启动
debug-tools:
image: alpine
profiles:
- debug # 只在 debug 配置集下启动
command: sh
migrate:
image: myapp
profiles:
- tools # 工具类服务
command: migratebash
# 启动特定 profile
docker compose --profile debug up -d
docker compose --profile tools run migrate完整示例
yaml
services:
# PostgreSQL 数据库
postgres:
image: postgres:16-alpine
restart: unless-stopped
environment:
POSTGRES_USER: ${POSTGRES_USER:-myuser}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: ${POSTGRES_DB:-mydb}
volumes:
- postgres-data:/var/lib/postgresql/data
- ./db/init.sql:/docker-entrypoint-initdb.d/init.sql:ro
networks:
- backend
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-myuser}"]
interval: 10s
timeout: 5s
retries: 5
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"
# Redis 缓存
redis:
image: redis:7-alpine
restart: unless-stopped
command: redis-server --requirepass ${REDIS_PASSWORD}
volumes:
- redis-data:/data
networks:
- backend
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 3
# 后端 API
api:
build:
context: .
dockerfile: Dockerfile
target: production
restart: unless-stopped
environment:
NODE_ENV: production
DATABASE_URL: postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB}
REDIS_URL: redis://:${REDIS_PASSWORD}@redis:6379
ports:
- "3000:3000"
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
networks:
- backend
- frontend
healthcheck:
test: ["CMD", "wget", "-qO-", "http://localhost:3000/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 30s
logging:
driver: json-file
options:
max-size: "10m"
max-file: "5"
# Nginx 反向代理
nginx:
image: nginx:alpine
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
depends_on:
api:
condition: service_healthy
networks:
- frontend
volumes:
postgres-data:
labels:
backup: daily
redis-data:
networks:
backend:
driver: bridge
frontend:
driver: bridge总结
Compose 文件最常用的配置项:
| 配置项 | 作用 |
|---|---|
image / build | 指定镜像或构建方式 |
ports | 端口映射 |
environment | 环境变量 |
volumes | 数据挂载 |
networks | 网络连接 |
depends_on | 服务依赖 |
restart | 重启策略 |
healthcheck | 健康检查 |
logging | 日志配置 |
deploy | 部署配置(Swarm) |