Docker Compose 文件格式参考
本文档提供 Docker Compose 文件格式的完整参考,包括所有配置选项、语法规则和最佳实践。
目录
文件规范
版本历史
| 版本 | Docker 版本 | 主要特性 |
|---|---|---|
| 3.8 | 19.03.0+ | 支持 max_replicas_per_node |
| 3.7 | 18.06.0+ | 支持 init 和 oom_score_adj |
| 3.6 | 18.02.0+ | 支持 start_period |
| 3.5 | 17.12.0+ | 支持 name 和 driver 选项 |
| 3.4 | 17.09.0+ | 支持 order 在更新配置中 |
| 3.3 | 17.06.0+ | 支持 build.labels |
| 3.2 | 17.04.0+ | 支持 cache_from 和 network |
| 3.1 | 1.13.1+ | 支持 secrets 和 healthcheck |
| 3.0 | 1.13.0+ | 支持 Swarm 模式 |
| 2.4 | 17.12.0+ | 支持 start_period |
| 2.3 | 17.06.0+ | 支持 target 和 cache_from |
| 2.2 | 1.13.0+ | 支持 init |
| 2.1 | 1.12.0+ | 支持 pids_limit 和 userns_mode |
| 2.0 | 1.10.0+ | 引入网络和卷 |
| 1.0 | 1.9.0+ | 初始版本 |
文件结构
yaml
version: "3.8" # 必需:指定 Compose 文件版本
services: # 必需:定义服务
service_name:
# 服务配置
networks: # 可选:定义网络
network_name:
# 网络配置
volumes: # 可选:定义卷
volume_name:
# 卷配置
configs: # 可选:定义配置(Swarm)
config_name:
# 配置定义
secrets: # 可选:定义密钥(Swarm)
secret_name:
# 密钥定义顶层元素
services
定义应用的服务组件。
yaml
services:
web:
image: nginx:alpine
ports:
- "80:80"
db:
image: postgres:15-alpine
environment:
POSTGRES_PASSWORD: secretnetworks
定义应用使用的网络。
yaml
networks:
frontend:
driver: bridge
backend:
driver: bridge
internal: truevolumes
定义应用使用的卷。
yaml
volumes:
db-data:
driver: local
cache:
driver: localconfigs
定义 Swarm 配置对象。
yaml
configs:
nginx-config:
file: ./nginx.conf
app-config:
external: truesecrets
定义 Swarm 密钥对象。
yaml
secrets:
db-password:
file: ./secrets/db-password.txt
api-key:
external: true服务配置详解
build
指定构建配置。
yaml
services:
web:
build:
# 上下文路径
context: ./web
# Dockerfile 路径
dockerfile: Dockerfile.prod
# 构建参数
args:
- NODE_ENV=production
- VERSION=1.0.0
# 缓存源
cache_from:
- myapp/web:latest
- myapp/web:cache
# 标签
labels:
- "com.example.description=Web application"
- "com.example.department=IT"
# 多阶段构建目标
target: production
# 构建网络
network: host
# 构建秘密
secrets:
- npmrc
# SSH 代理
ssh:
- default
# 额外主机
extra_hosts:
- "npm.registry:192.168.1.100"
# 隔离
isolation: default
# 平台
platforms:
- linux/amd64
- linux/arm64image
指定镜像。
yaml
services:
web:
image: nginx:alpine
app:
image: myregistry.com/myapp:v1.0.0command
覆盖默认命令。
yaml
services:
web:
image: nginx:alpine
# 字符串形式
command: nginx -g 'daemon off;'
# 列表形式
command: ["nginx", "-g", "daemon off;"]entrypoint
覆盖默认入口点。
yaml
services:
web:
image: nginx:alpine
entrypoint: /docker-entrypoint.sh
# 或
entrypoint: ["/docker-entrypoint.sh"]environment
设置环境变量。
yaml
services:
web:
image: myapp:latest
# 键值对形式
environment:
NODE_ENV: production
DEBUG: "false"
PORT: 3000
# 列表形式
environment:
- NODE_ENV=production
- DEBUG=false
- PORT=3000
# 引用环境变量
environment:
- NODE_ENV=${NODE_ENV:-production}
- API_KEY=${API_KEY}env_file
从文件加载环境变量。
yaml
services:
web:
image: myapp:latest
env_file:
- .env
- .env.local
# 或带路径
env_file:
- ./config/.envports
暴露端口。
yaml
services:
web:
image: nginx:alpine
# 短语法
ports:
- "3000" # 仅暴露容器端口
- "8080:80" # 主机:容器
- "127.0.0.1:8080:80" # 绑定地址
- "8080-8090:80-90" # 范围
- "8080:80/udp" # 指定协议
# 长语法
ports:
- target: 80
published: 8080
protocol: tcp
mode: host
- target: 443
published: 8443
protocol: tcp
mode: hostexpose
暴露端口(不发布到主机)。
yaml
services:
web:
image: myapp:latest
expose:
- "3000"
- "8080"volumes
挂载卷。
yaml
services:
web:
image: myapp:latest
# 短语法
volumes:
- /var/lib/mysql # 命名卷
- /opt/data:/var/lib/mysql # 绑定挂载
- ./cache:/tmp/cache:ro # 只读
- data-volume:/var/lib/mysql # 使用命名卷
# 长语法
volumes:
- type: volume
source: mydata
target: /data
volume:
nocopy: true
- type: bind
source: ./config
target: /config
read_only: true
- type: tmpfs
target: /tmp
tmpfs:
size: 100M
mode: 1770networks
连接网络。
yaml
services:
web:
image: myapp:latest
networks:
- frontend
- backend
# 带配置
networks:
frontend:
aliases:
- web-alias
backend:
ipv4_address: 172.16.238.10depends_on
配置服务依赖。
yaml
services:
web:
image: myapp:latest
# 简单依赖
depends_on:
- db
- redis
# 带条件(Compose v3+)
depends_on:
db:
condition: service_healthy
redis:
condition: service_startedhealthcheck
配置健康检查。
yaml
services:
web:
image: myapp:latest
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
disable: falsedeploy
Swarm 部署配置。
yaml
services:
web:
image: myapp:latest
deploy:
# 模式
mode: replicated # 或 global
# 副本数
replicas: 3
# 标签
labels:
- "com.example.description=Web service"
# 更新配置
update_config:
parallelism: 1
delay: 10s
failure_action: rollback
order: start-first
# 回滚配置
rollback_config:
parallelism: 1
delay: 10s
failure_action: pause
# 重启策略
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
window: 120s
# 放置约束
placement:
constraints:
- node.role == worker
- node.labels.zone == public
preferences:
- spread: node.labels.rack
max_replicas_per_node: 1
# 资源限制
resources:
limits:
cpus: '0.5'
memory: 512M
pids: 100
reservations:
cpus: '0.25'
memory: 256M
generic_resources:
- discrete_resource_spec:
kind: nvidia.com/gpu
value: 2
# endpoint_mode
endpoint_mode: vip # 或 dnsrrlogging
配置日志。
yaml
services:
web:
image: myapp:latest
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
labels: "service_name,environment"
env: "OS_VERSION"restart
配置重启策略。
yaml
services:
web:
image: myapp:latest
restart: unless-stopped
# 选项: no, always, on-failure, unless-stoppedsecurity_opt
配置安全选项。
yaml
services:
web:
image: myapp:latest
security_opt:
- no-new-privileges:true
- seccomp:unconfined
- apparmor:docker-defaultsysctls
配置内核参数。
yaml
services:
web:
image: myapp:latest
sysctls:
- net.core.somaxconn=1024
- net.ipv4.ip_forward=1ulimits
配置资源限制。
yaml
services:
web:
image: myapp:latest
ulimits:
nproc: 65535
nofile:
soft: 20000
hard: 40000
as:
soft: 102400000
hard: 102400000user
配置用户。
yaml
services:
web:
image: myapp:latest
user: "1000:1000"
# 或
user: appuserworking_dir
配置工作目录。
yaml
services:
web:
image: myapp:latest
working_dir: /appdomainname / hostname / ipc / mac_address / privileged / read_only / shm_size / stdin_open / tty / stop_signal / stop_grace_period
其他配置选项。
yaml
services:
web:
image: myapp:latest
domainname: example.com
hostname: web-server
ipc: host
mac_address: 02:42:ac:11:65:43
privileged: false
read_only: true
shm_size: 64M
stdin_open: true
tty: true
stop_signal: SIGTERM
stop_grace_period: 30s网络配置详解
基本配置
yaml
networks:
frontend:
driver: bridge
backend:
driver: bridge
driver_opts:
com.docker.network.bridge.name: backend-bridge
com.docker.network.bridge.enable_icc: "true"
com.docker.network.bridge.enable_ip_masquerade: "true"
ipam:
driver: default
config:
- subnet: 172.28.0.0/16
ip_range: 172.28.5.0/24
gateway: 172.28.5.254
aux_addresses:
host1: 172.28.1.5
host2: 172.28.1.6
options:
foo: bar
internal: true
attachable: true
labels:
- "com.example.description=Backend network"外部网络
yaml
networks:
existing-network:
external: true
name: my-pre-existing-networkOverlay 网络
yaml
networks:
overlay-network:
driver: overlay
attachable: true
driver_opts:
encrypted: "true"卷配置详解
基本配置
yaml
volumes:
db-data:
driver: local
app-data:
driver: local
driver_opts:
type: nfs
o: addr=192.168.1.100,rw
device: ":/path/to/dir"
labels:
- "com.example.description=Application data"外部卷
yaml
volumes:
existing-volume:
external: true
name: my-pre-existing-volume命名卷
yaml
volumes:
named-volume:
driver: local
driver_opts:
size: 10GiB高级特性
扩展字段
yaml
x-common-variables: &common-variables
TZ: Asia/Shanghai
LANG: en_US.UTF-8
x-common-deploy: &common-deploy
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
services:
web:
image: myapp:latest
environment:
<<: *common-variables
APP_NAME: web
deploy:
<<: *common-deploy
replicas: 3变量插值
yaml
services:
web:
image: "${WEB_IMAGE:-nginx:alpine}"
ports:
- "${WEB_PORT:-80}:80"
environment:
- NODE_ENV=${NODE_ENV:-production}
- DATABASE_URL=${DATABASE_URL:?required}多文件配置
yaml
# docker-compose.yml
version: '3.8'
services:
web:
image: nginx:alpine
# docker-compose.prod.yml
version: '3.8'
services:
web:
deploy:
replicas: 3
# 使用
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d完整示例
yaml
version: '3.8'
services:
nginx:
image: nginx:1.25.3-alpine
container_name: nginx-proxy
hostname: nginx
ports:
- target: 80
published: 80
protocol: tcp
mode: host
- target: 443
published: 443
protocol: tcp
mode: host
volumes:
- type: bind
source: ./nginx/nginx.conf
target: /etc/nginx/nginx.conf
read_only: true
- type: bind
source: ./nginx/ssl
target: /etc/nginx/ssl
read_only: true
- type: volume
source: nginx-cache
target: /var/cache/nginx
networks:
- frontend
depends_on:
web:
condition: service_healthy
api:
condition: service_healthy
healthcheck:
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost/health"]
interval: 30s
timeout: 10s
retries: 3
deploy:
resources:
limits:
cpus: '0.5'
memory: 256M
reservations:
cpus: '0.25'
memory: 128M
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
logging:
driver: json-file
options:
max-size: 10m
max-file: 3
labels:
- "traefik.enable=true"
- "traefik.http.routers.nginx.rule=Host(`example.com`)"
web:
build:
context: ./web
dockerfile: Dockerfile
args:
- NODE_ENV=production
target: production
cache_from:
- myapp/web:latest
image: myapp/web:${VERSION:-latest}
environment:
NODE_ENV: production
API_URL: http://api:8080
REDIS_URL: redis://redis:6379
volumes:
- type: tmpfs
target: /tmp
tmpfs:
size: 100M
networks:
- frontend
- backend
depends_on:
api:
condition: service_healthy
redis:
condition: service_healthy
healthcheck:
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:3000/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
deploy:
replicas: 3
update_config:
parallelism: 1
delay: 10s
failure_action: rollback
order: start-first
restart_policy:
condition: any
delay: 5s
max_attempts: 3
window: 120s
placement:
constraints:
- node.role == worker
preferences:
- spread: node.labels.zone
networks:
frontend:
driver: bridge
driver_opts:
com.docker.network.bridge.name: frontend
backend:
driver: bridge
internal: true
driver_opts:
com.docker.network.bridge.name: backend
com.docker.network.bridge.enable_icc: "true"
ipam:
driver: default
config:
- subnet: 172.20.0.0/16
gateway: 172.20.0.1
volumes:
nginx-cache:
driver: local