首页 / Docker 入门教程 / Docker Compose 入门

Docker 入门教程

Docker Compose 入门

本教程共 25 篇 · 第 20 篇 · 更新于 2026-07-26 · 约 6 分钟阅读

DockerDocker 入门教程Docker Composecompose.yaml多容器服务编排YAML

20. Docker Compose 入门

本节目标:搞清楚 Compose 到底解决什么问题,看懂 compose.yaml 的骨架,能照着模板写出第一个多服务编排文件并跑起来。

为什么需要 Compose

前面几章你跑容器全靠 docker run,一两个容器还好。一旦要同时启动应用、数据库、缓存,命令就开始又长又难记。

举个真实场景:一个 Node 应用要连 MySQL,命令大概长这样。

docker run -dp 3000:3000 \
  -w /app -v "$(pwd):/app" \
  --network todo-app \
  -e MYSQL_HOST=mysql \
  -e MYSQL_USER=root \
  -e MYSQL_PASSWORD=secret \
  -e MYSQL_DB=todos \
  node:22-alpine \
  sh -c "yarn install && yarn run dev"

这还只是应用本身,MySQL 还得再来一长串。换台机器部署?把这几条命令记到文档里,照着敲一遍,磕磕绊绊。

Docker Compose 就是为这事生的。它让你把所有容器和它们的配置写进一个 YAML 文件,一条命令拉起整套环境,一条命令拆掉。

Tip

Compose 是声明式工具:你只管定义「要什么样」,剩下交给它去协调。改了文件再跑一次 docker compose up,它会智能地只更新变化的部分。

Compose 是什么

Docker Compose 是一个定义和运行多容器应用的工具。核心就两件事:

  1. 用 YAML 文件描述应用栈(哪些服务、怎么连、用什么镜像)。
  2. 用一条命令把这些服务全部启动或停止。

它的工作场景覆盖开发、测试、CI,甚至轻量生产。不过最常见的还是本地开发环境——同事 clone 你的仓库,跑一条命令就能把整套依赖起来。

Note

Dockerfile 和 Compose 文件别搞混。Dockerfile 教 Docker 怎么「造镜像」,Compose 文件描述「怎么跑容器」。很多项目里 Compose 文件会引用 Dockerfile 来构建某个服务的镜像。

compose.yaml 文件结构

Compose 文件默认叫 compose.yaml(也认 docker-compose.yml,老命名)。顶层有几个固定元素,最常用的三个:

  • services:定义有哪些服务(容器),必填。
  • volumes:声明命名数据卷,可选。
  • networks:声明自定义网络,可选。

一个最小骨架长这样。

services:
  web:
    image: nginx:alpine

  db:
    image: mysql:8.0

这就定义了两个服务 webdb,分别用官方的 nginx 和 mysql 镜像。是不是比刚才那串命令清爽多了?

Note

Compose 文件格式一直在演进,现在的版本不再需要在顶部写 version: "3"。Docker Engine 29.x 配套的 Compose 会自动识别 schema,写了反而报警告,直接从 services: 开始就好。

服务定义的常用字段

服务下面挂的就是各种配置项,它们基本都能在 docker run 里找到对应参数。下面这张表先混个眼熟,后面章节会挨个细讲。

字段作用对应 docker run 参数
image用哪个镜像镜像名
build现场用 Dockerfile 构建docker build
command覆盖默认启动命令镜像名后的命令
ports端口映射-p
volumes挂载数据卷或目录-v
environment环境变量(键值对)-e
env_file从文件加载环境变量--env-file
working_dir容器内工作目录-w
depends_on依赖哪些服务先启动无直接对应
restart重启策略--restart
networks加入哪些网络--network

第一个 compose 文件

来写一个真实能跑的。还是那个 Node + MySQL 的例子,把它整个搬到 Compose 里。

services:
  app:
    image: node:22-alpine
    command: sh -c "yarn install && yarn run dev"
    ports:
      - 3000:3000
    working_dir: /app
    volumes:
      - ./:/app
    environment:
      MYSQL_HOST: mysql
      MYSQL_USER: root
      MYSQL_PASSWORD: secret
      MYSQL_DB: todos

  mysql:
    image: mysql:8.0
    volumes:
      - todo-mysql-data:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: secret
      MYSQL_DATABASE: todos

volumes:
  todo-mysql-data:

逐段看一下:

  • app 服务用 node:22-alpine 镜像,启动时先装依赖再跑 dev。端口把容器 3000 映射到宿主机 3000。
  • working_dir 指定容器内工作目录,volumes 把当前目录挂进去,方便热重载。
  • environment 注入数据库连接信息,注意 MYSQL_HOST 的值是 mysql——这就是下面那个服务的名字。
  • mysql 服务用 mysql:8.0,把数据目录挂到命名卷 todo-mysql-data,避免容器删了数据就没了。
  • 顶层的 volumes 声明那个命名卷,Compose 才会自动帮你创建。
Tip

Compose 有个贴心特性:服务名会自动成为网络别名。app 想连数据库,直接用主机名 mysql 就行,不用记 IP。这是 Compose 自动建网络带来的好处。

自动建网络这个事

注意上面文件里我没写 networks。Compose 默认会为整个项目建一个 bridge 网络,把所有服务都塞进去。

这意味着:

  • 服务之间能用服务名互相访问(自动 DNS 解析)。
  • 外部默认访问不到内部服务,除非你显式 ports 暴露端口。

跑起来后用 docker network ls 能看到一个叫 <项目名>_default 的网络。项目名默认是 compose.yaml 所在目录的名字(小写、连字符处理过)。

一条命令拉起

文件准备好,进入文件所在目录,跑:

docker compose up -d

-d 表示后台运行。你会看到类似输出:

[+] Running 3/3
 ✔ Network app_default         Created   0.0s
 ✔ Container app-mysql-1       Started   0.4s
 ✔ Container app-app-1         Started   0.4s

一条命令,网络、卷、两个容器全到位。比之前一长串 docker run 爽多了。

用完想拆掉,同样一条命令:

docker compose down
[+] Running 3/3
 ✔ Container app-mysql-1  Removed   2.9s
 ✔ Container app-app-1    Removed   0.1s
 ✔ Network app_default    Removed   0.1s
Warning

docker compose down 默认只删容器和网络,不会删命名卷。这是有意为之——万一你想再启动,数据还在。如果你确定连数据一起清掉,加 --volumes(简写 -v):

docker compose down --volumes

v2 语法别用错

这点要单独强调,因为网上很多老教程会带偏你。

Docker Compose 现在是 v2,命令是 docker compose(两个词,中间空格),集成在 Docker CLI 里。不是旧的 docker-compose(带连字符的独立 Python 脚本)。

# 正确(v2,推荐)
docker compose up -d

# 错误(v1,已淘汰)
docker-compose up -d

Docker Desktop 和新版 Docker Engine 都自带 v2,开箱即用,不用单独装。如果你敲 docker-compose 还能用,说明系统里残留了老的 Python 版本,建议卸了,统一用 docker compose

小结

Compose 把多容器应用的「怎么跑」从一串命令挪到了一个 YAML 文件里。好处显而易见:

  • 一条命令起、一条命令停。
  • 文件进版本控制,团队共享同一套环境定义。
  • 改了配置重跑,Compose 只动变化的部分。

下一章我们挨个过一遍 Compose 的常用命令和服务配置项,把这张表填满。