一、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.02. 翻译成 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: - .env4. volumes:数据卷
volumes: # 命名卷(Docker 管理) - mysql_data:/var/lib/mysql # 绑定挂载(主机路径) - ./app:/app # 只读挂载 - ./config:/app/config:ro5. 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: 56. 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一键启动。