一、docker-compose.yml
docker-compose.yml 本质上是把多个 docker run 命令翻译成 YAML 格式。它描述了:
-
有哪些服务(容器)
-
每个服务用什么镜像
-
端口怎么映射
-
数据怎么持久化
-
服务之间怎么依赖

二、文件的基本结构
version: '3.8' # Compose 文件版本
services: # 定义所有服务(必填)
service_name: # 服务名(自己起)
image: ... # 镜像
ports: ... # 端口映射
environment: ... # 环境变量
volumes: ... # 数据卷
depends_on: ... # 依赖关系
volumes: # 声明数据卷(可选)
networks: # 声明网络(可选)
三、怎么写:从 docker run 翻译过来
1. 先写一个 docker run
docker run -d \
--name mysql_db \
-p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=123456 \
-e MYSQL_DATABASE=mydb \
-v mysql_data:/var/lib/mysql \
--restart always \
mysql:8.0
2. 翻译成 docker-compose.yml
version: '3.8'
services:
mysql:
image: mysql:8.0
container_name: mysql_db
ports:
- "3306:3306"
environment:
MYSQL_ROOT_PASSWORD: 123456
MYSQL_DATABASE: mydb
volumes:
- mysql_data:/var/lib/mysql
restart: always
volumes:
mysql_data:
3. 参数对应关系
| docker run 参数 | docker-compose.yml 字段 |
|---|---|
--name mysql_db |
container_name: mysql_db |
-p 3306:3306 |
ports: - "3306:3306" |
-e KEY=VALUE |
environment: KEY: VALUE |
-v mysql_data:/var/lib/mysql |
volumes: - mysql_data:/var/lib/mysql |
--restart always |
restart: always |
mysql:8.0 |
image: mysql:8.0 |
四、多个服务的示例
以 Python 应用 + MySQL + Redis 为例:
version: '3.8'
services:
# Python 应用
app:
build: . # 从当前目录的 Dockerfile 构建
container_name: python_app
ports:
- "8080:8080"
environment:
DB_HOST: mysql # 用服务名访问,不是 localhost
DB_PORT: 3306
DB_USER: app_user
DB_PASSWORD: app_pass
REDIS_HOST: redis
volumes:
- ./app:/app # 挂载代码(开发用)
depends_on:
- mysql
- redis
restart: always
# MySQL 数据库
mysql:
image: mysql:8.0
container_name: mysql_db
ports:
- "3306:3306"
environment:
MYSQL_ROOT_PASSWORD: 123456
MYSQL_DATABASE: mydb
MYSQL_USER: app_user
MYSQL_PASSWORD: app_pass
volumes:
- mysql_data:/var/lib/mysql
restart: always
# Redis 缓存
redis:
image: redis:7.0-alpine
container_name: redis_cache
ports:
- "6379:6379"
volumes:
- redis_data:/data
restart: always
volumes:
mysql_data:
redis_data:
五、常用字段
1. image vs build
# 用现成的镜像
image: mysql:8.0
# 从 Dockerfile 构建
build:
context: . # 构建上下文
dockerfile: Dockerfile # Dockerfile 路径
2. ports:端口映射
ports:
- "8080:8080" # 主机:容器
- "443:443"
- "127.0.0.1:3306:3306" # 只绑定本地
3. environment:环境变量
# 方式一:键值对
environment:
DB_HOST: mysql
DB_PORT: 3306
# 方式二:列表
environment:
- DB_HOST=mysql
- DB_PORT=3306
# 方式三:从 .env 文件读取
env_file:
- .env
4. volumes:数据卷
volumes:
# 命名卷(Docker 管理)
- mysql_data:/var/lib/mysql
# 绑定挂载(主机路径)
- ./app:/app
# 只读挂载
- ./config:/app/config:ro
5. depends_on:依赖关系
depends_on:
- mysql
- redis
注意 :depends_on 只保证启动顺序 ,不保证服务就绪 。如果需要等待服务就绪,要用 healthcheck:
services:
app:
depends_on:
mysql:
condition: service_healthy
mysql:
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 10s
timeout: 5s
retries: 5
6. restart:重启策略
| 值 | 说明 |
|---|---|
no |
不自动重启(默认) |
always |
总是重启 |
on-failure |
失败时重启 |
unless-stopped |
除非手动停止,否则重启 |
7. command:覆盖启动命令
command: python app.py
# 或
command: ["python", "app.py"]
8. networks:自定义网络
services:
app:
networks:
- app_network
networks:
app_network:
driver: bridge
六、用 .env 文件管理敏感信息
不要在 docker-compose.yml 里写密码 ,用 .env 文件:
# .env
MYSQL_ROOT_PASSWORD=123456
MYSQL_DATABASE=mydb
DB_USER=app_user
DB_PASSWORD=app_pass
# docker-compose.yml
services:
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: ${MYSQL_DATABASE}
备注: Compose 会自动读取同目录下的 .env 文件。
七、写 docker-compose.yml 的套路
步骤:
-
列出所有服务:应用、数据库、缓存、消息队列等
-
确定每个服务的镜像:从 Docker Hub 查官方镜像名
-
配置端口:需要外部访问的才映射
-
配置环境变量:查官方文档,看哪些是必填的
-
配置数据卷:有状态的服务(数据库)必须挂载
-
配置依赖 :
depends_on控制启动顺序 -
配置重启策略 :生产环境用
always -
声明 volumes 和 networks:在文件末尾统一声明
docker-compose.yml 就是把多个 docker run 命令翻译成 YAML 格式。先写 docker run,再逐条翻译成 YAML 字段,最后用 docker-compose up -d 一键启动。

