Docker Compose 配置文件详解
概述
Docker Compose 配置文件通常以 version 开头,用于指定 Compose 文件格式的版本。这决定了哪些配置项可用。
注意:自 Docker Compose V2 以后,version 字段逐渐被废弃,建议省略该字段,工具会使用最新版本。
文件的主体部分由多个顶级配置项组成,最重要的三个是:
- services:定义应用的一个或多个服务(容器)
- networks:定义自定义网络
- volumes:定义数据卷
文件版本与结构
传统写法(适用于旧版本 Compose)
现代写法(推荐,适用于 Compose V2 及以上)
Services 部分详解
基本配置
| YAML |
|---|
| services:
webapp: # 服务名称,用户自定义
image: nginx:latest # 使用的镜像
container_name: my-nginx # 指定容器名,不指定则自动生成
restart: unless-stopped # 重启策略 (no, always, on-failure, unless-stopped)
database:
build: . # 使用当前目录下的 Dockerfile 来构建镜像,而非从仓库拉取
# build: ./dir # 指定 Dockerfile 所在目录
# build:
# context: . # 构建上下文
# dockerfile: Dockerfile.dev # 指定 Dockerfile 文件名
# args: # 构建参数
# buildno: 1
|
端口映射
| YAML |
|---|
| services:
webapp:
image: nginx
ports:
- "8080:80" # 主机端口:容器端口 (将主机的 8080 映射到容器的 80)
- "8443:443"
- "9000" # 仅指定容器端口,主机端口随机分配
|
环境变量
| YAML |
|---|
| services:
database:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: my-secret-pw # 方式一:键值对
MYSQL_DATABASE: myapp
MYSQL_USER: user
MYSQL_PASSWORD: pass
app:
image: my-app
env_file: # 方式二:从文件读取
- ./database.env # 文件路径
- ./app.env
|
数据卷挂载
| YAML |
|---|
| services:
database:
image: mysql:8.0
volumes:
# 方式一:命名卷 (由 Docker 管理,适合数据库数据)
- db_data:/var/lib/mysql
# 方式二:绑定挂载 (直接映射到主机特定路径)
- /host/path/data:/var/lib/mysql
- ./config:/app/config # 使用相对路径
# 方式三:匿名卷 (不推荐,难以管理)
# - /var/lib/mysql
webapp:
image: nginx
volumes:
# 方式四:只读挂载
- ./static:/usr/share/nginx/html:ro
volumes: # 必须在顶级 volumes 部分声明命名卷
db_data: # 使用默认驱动
# 可以指定驱动和选项
# driver: local
|
依赖关系与启动顺序
使用 depends_on 控制服务启动顺序,但不保证服务完全就绪(例如 MySQL 启动完成但尚未接受连接)。对于就绪检查,需要结合健康检查。
| YAML |
|---|
| services:
webapp:
image: my-app
depends_on:
- database # 确保 database 服务先启动
- redis
database:
image: mysql
redis:
image: redis:alpine
|
网络配置
| YAML |
|---|
| services:
webapp:
image: nginx
networks: # 加入自定义网络
- frontend
- backend
database:
image: mysql
networks:
- backend
networks: # 在顶级 networks 部分声明
frontend:
driver: bridge
backend:
driver: bridge
# 可以配置更多网络选项,如自定义子网
# ipam:
# config:
# - subnet: 172.20.0.0/24
|
其他常用配置
| YAML |
|---|
| services:
app:
image: my-app
working_dir: /app # 容器内工作目录
command: ["python", "app.py"] # 覆盖 Dockerfile 中的 CMD
# command: python app.py --debug # 另一种写法
entrypoint: /docker-entrypoint.sh # 覆盖 Dockerfile 中的 ENTRYPOINT
labels: # 为容器添加元数据
- "com.example.description=My Web Application"
- "com.example.department=Engineering"
healthcheck: # 定义健康检查
test: ["CMD", "curl", "-f", "http://localhost"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
logging: # 日志配置
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
|
完整示例
下面是一个典型的 Web 应用(Nginx + Python Flask + MySQL + Redis)的 Compose 文件示例:
| YAML |
|---|
| # docker-compose.yml
services:
nginx:
image: nginx:alpine
ports:
- "80:80"
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
- static_volume:/app/static
depends_on:
- web
networks:
- webnet
web:
build: ./flask-app # 构建 flask-app 目录下的镜像
command: gunicorn --bind 0.0.0.0:5000 app:app
volumes:
- static_volume:/app/static
environment:
- DATABASE_URL=mysql+pymysql://user:pass@db:3306/myapp
- REDIS_URL=redis://redis:6379/0
depends_on:
- db
- redis
networks:
- webnet
db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: rootpass
MYSQL_DATABASE: myapp
MYSQL_USER: user
MYSQL_PASSWORD: pass
volumes:
- db_data:/var/lib/mysql
networks:
- webnet
redis:
image: redis:alpine
networks:
- webnet
volumes:
db_data:
static_volume:
networks:
webnet:
driver: bridge
|
配置项总结
| 配置项 |
说明 |
必需 |
services |
定义服务列表 |
是 |
image |
使用的镜像名称 |
是 |
build |
构建镜像的配置 |
否 |
ports |
端口映射 |
否 |
environment |
环境变量 |
否 |
volumes |
数据卷挂载 |
否 |
depends_on |
服务依赖 |
否 |
networks |
网络配置 |
否 |
restart |
重启策略 |
否 |
command |
覆盖默认命令 |
否 |
entrypoint |
覆盖入口点 |
否 |