Loading...

文章背景图

Docker Compose 实战指南:从 compose.yaml 到多容器编排

2026-08-17
1
-
- 分钟

引言

单个容器用 docker run 就能跑,但真实项目几乎从不是单容器——Web 服务要连数据库、缓存、消息队列,可能还有 Nginx 反代、后台任务。如果靠手动敲 docker run 并逐个管理网络、数据卷、启动顺序,很快会陷入"启动要十几条命令、还容易漏"的泥潭。

Docker Compose 就是为解决这个问题而生: 用一份 YAML 文件描述整个应用栈,一条命令统一启停、编排。这篇指南覆盖从入门语法到生产实践,助你把多容器管理变成一件轻松事。

前置:确认环境已安装 Compose, docker compose version 能输出版本即可。Docker Desktop(Win/Mac)自带,Linux 上 Docker Engine 20.10+ 也已内置。


一、认识 Compose 与 v1→v2 迁移

1.1 Compose 能做什么

  • 一键编排docker compose up 即可启动定义的所有服务。

  • 统一管理网络与数据卷:Compose 自动为项目创建独立网络,容器间可直接用服务名互访。

  • 声明式配置:应用栈的全部依赖关系都写进 YAML,可版本化、可复现、可提交到 Git。

1.2 重要变化:Compose v1 → v2

Docker Compose 已从 v1(独立的 docker-compose 命令,Python 编写)全面迁移到 v2(Go 重写,集成进 Docker CLI)。关键变化:

 # 旧写法(v1,已弃用)
 docker-compose up -d
 ​
 # 新写法(v2,推荐)
 docker compose up -d    # 注意:是空格,不是连字符

维度

v1

v2

命令形式

docker-compose(连字符)

docker compose(空格,CLI 子命令)

实现语言

Python

Go

配置文件

docker-compose.yml

推荐 compose.yaml(旧文件名仍兼容)

扩展能力

有限

支持 x- 扩展字段复用、 compose ls 等新特性

安装方式

独立二进制

随 Docker 内置

迁移建议:脚本中全局替换 docker-composedocker compose;新项目优先使用 compose.yaml 命名。


二、compose.yaml 语法详解

这是 Compose 的核心,掌握语法就等于掌握了 Compose 90% 的用法。

2.1 顶级元素

一份 compose.yaml 通常包含以下顶级元素:

顶级元素

说明

services

定义各个容器服务(核心,必填)

networks

声明自定义网络

volumes

声明命名数据卷

configs / secrets

配置与密钥(Swarm 场景常用)

2.2 一个最小示例

 services:
   web:
     image: nginx:1.25
     ports:
       - "8080:80"

docker compose up -d 即可启动一个映射到宿主机 8080 端口的 Nginx。

2.3 service 常用配置项

配置项

说明

示例

image

指定镜像

image: nginx:1.25

build

从 Dockerfile 构建

build: .

command

覆盖默认启动命令

command: npm run start

ports

端口映射

ports: ["8080:80"]

environment

环境变量(列表或 map)

environment: NODE_ENV=production

env_file

从文件加载环境变量

env_file: .env

volumes

挂载数据卷/目录

volumes: ["db-data:/var/lib/mysql"]

networks

加入指定网络

networks: [app-net]

depends_on

声明启动依赖顺序

depends_on: [db]

restart

重启策略

restart: unless-stopped

healthcheck

健康检查

healthcheck: test: ["CMD", "curl", "-f", "http://localhost"]

logging

日志配置

logging: driver: json-file

2.4 build 的两种写法

 # 简单写法:构建上下文为当前目录
 services:
   web:
     build: .
 ​
 # 完整写法:指定上下文和 Dockerfile、构建参数
 services:
   web:
     build:
       context: ./web
       dockerfile: Dockerfile.dev
       args:
         NODE_ENV: production

2.5 环境变量与变量替换

Compose 支持在 YAML 中使用 ${VAR} 引用环境变量,非常适合区分环境:

 services:
   web:
     image: myapp:${APP_TAG:-latest}
     environment:
       DB_HOST: db
       DB_PASSWORD: ${DB_PASSWORD}
  • ${VAR:-default}:变量未设置时使用默认值。

  • Compose 会自动读取项目根目录下的 .env 文件作为默认环境变量来源。

2.6 扩展字段复用(x-)

v2 支持用 x- 前缀定义可复用的配置片段,减少重复:

 x-common-env: &common-env
   environment:
     - TZ=Asia/Shanghai
     - LOG_LEVEL=info
 ​
 services:
   web:
     image: myapp:1.0
     <<: *common-env
 ​
   worker:
     image: myapp:1.0
     <<: *common-env

三、常用命令详解

3.1 启动与停止

 # 构建并后台启动所有服务
 docker compose up -d
 ​
 # 仅构建镜像(不启动)
 docker compose build
 ​
 # 构建指定服务
 docker compose build web
 ​
 # 强制重新构建后启动(不读取缓存)
 docker compose up -d --build
 ​
 # 停止服务(保留容器)
 docker compose stop
 ​
 # 停止并删除容器、网络(默认不删数据卷)
 docker compose down
 ​
 # 连同数据卷一起删除(慎用)
 docker compose down -v

3.2 查看状态与日志

 # 查看项目服务状态
 docker compose ps
 ​
 # 查看日志(-f 跟随,--tail 限制行数)
 docker compose logs -f --tail 100
 ​
 # 只查看某个服务的日志
 docker compose logs web

3.3 操作单个服务

 # 在指定服务中执行命令(进入 shell)
 docker compose exec web bash
 ​
 # 运行一次性命令
 docker compose run --rm web python manage.py migrate
 ​
 # 重启 / 启动 / 停止指定服务
 docker compose restart web
 docker compose start web
 docker compose stop web

3.4 查看与校验配置

 # 查看合并后的最终配置(校验语法 + 预览)
 docker compose config
 ​
 # 列出所有 Compose 项目(v2 新特性)
 docker compose ls

四、实战案例:部署 Web + MySQL + Redis

下面是一个贴近真实开发的项目:一个 Web 应用 + MySQL 数据库 + Redis 缓存 + Nginx 反向代理。

4.1 项目结构

 myapp/
 ├── compose.yaml
 ├── .env
 ├── web/
 │   ├── Dockerfile
 │   └── app.py
 └── nginx/
     └── nginx.conf

4.2 compose.yaml

 services:
   web:
     build: ./web
     restart: unless-stopped
     environment:
       DB_HOST: db
       DB_PASSWORD: ${DB_PASSWORD}
       REDIS_HOST: redis
     depends_on:
       db:
         condition: service_healthy
       redis:
         condition: service_started
     networks:
       - app-net
 ​
   db:
     image: mysql:8.0
     restart: unless-stopped
     environment:
       MYSQL_ROOT_PASSWORD: ${DB_PASSWORD}
       MYSQL_DATABASE: myapp
     volumes:
       - db-data:/var/lib/mysql
     healthcheck:
       test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
       interval: 10s
       timeout: 5s
       retries: 5
     networks:
       - app-net
 ​
   redis:
     image: redis:7-alpine
     restart: unless-stopped
     networks:
       - app-net
 ​
   nginx:
     image: nginx:1.25
     restart: unless-stopped
     ports:
       - "80:80"
     volumes:
       - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
     depends_on:
       - web
     networks:
       - app-net
 ​
 networks:
   app-net:
 ​
 volumes:
   db-data:

4.3 .env

 DB_PASSWORD=your-secret-password

4.4 启动与验证

 # 一键启动整个应用栈
 docker compose up -d
 ​
 # 查看状态
 docker compose ps
 ​
 # 查看 web 服务日志
 docker compose logs -f web

4.5 案例要点解析

  • depends_on** 的两种条件**: service_healthy 表示等待 db 健康检查通过后才启动 web,比单纯的 service_started(仅等容器启动)更可靠,能避免"数据库还没就绪应用就连不上"的经典问题。

  • 数据卷 db-data:确保 docker compose down 后数据库数据不丢失。

  • 网络隔离:所有服务在自定义网络 app-net 内,通过服务名( dbredis)互访,Nginx 只对外暴露 80 端口。


五、最佳实践与常见排错

5.1 最佳实践

  1. 配置文件用 compose.yaml,与项目代码一起纳入版本控制。

  2. 敏感信息用 .env:数据库密码等不要硬编码在 YAML 里,用 ${VAR} 引用, .env 加入 .gitignore

  3. 生产显式指定 tag:避免 latest 带来的不确定性。

  4. 用好 depends_on** +** healthcheck:确保服务启动顺序和就绪状态。

  5. 数据持久化用命名卷:数据库、文件存储等服务务必挂载 volume。

5.2 常见问题排查

问题现象

排查思路

docker compose 命令不存在

检查 docker compose version;Docker Engine 版本过旧需升级

提示 docker-compose 已弃用

改用 docker compose(空格)

服务起不来、应用连不上数据库

检查 depends_onhealthcheck,确认 db 就绪后再启动应用

修改代码后容器没更新

docker compose up -d --build 重新构建

端口冲突

修改 ports 映射的宿主机端口

数据"莫名丢失"

确认该服务挂载了命名卷; docker compose down 默认不删卷, -v 才会删


总结与展望

Docker Compose 把"多容器应用的编排"从一堆手工命令,变成了一份可读、可版本化、可复现的 YAML 声明。掌握本指南的语法要点和常用命令,你就能覆盖绝大多数开发与测试场景:

  • compose.yaml** 描述应用栈**,而非手敲 docker run

  • depends_on** +** healthcheck** 管好启动顺序**。

  • .env** 和变量替换隔离敏感信息与多环境差异**。

随着项目规模增长,同一套 compose.yaml 还可以平滑迁移到 Docker Swarm 或 Kubernetes(借助 Kompose 等工具),学习成本不高,长期收益明显。

延伸阅读:Docker 镜像、容器、网络、存储等核心命令,请参阅《Docker 常用命令速查手册:镜像、容器、网络与存储》。


参考资料:

原创

Docker Compose 实战指南:从 compose.yaml 到多容器编排

本文链接: Docker Compose 实战指南:从 compose.yaml 到多容器编排

本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。

文章目录