目录
Docker Compose 教程:用一个文件管理多个容器
一个真实的应用通常不止一个容器:网站、数据库、缓存……每个都要记住一长串 docker run 参数,还要先创建网络、Volume,并注意启动顺序。
Docker Compose 让你把这些配置写进一个 YAML 文件,然后用一条命令全部启动:
docker compose up -d
安装与版本
- Docker Desktop(Windows、macOS)已内置 Compose。
- Linux:按照安装 Docker中的步骤安装
docker-compose-plugin即可。
$ docker compose version
Docker Compose version v5.6.0
旧版独立程序叫
docker-compose(中间有连字符,v1),已经停止维护;现在请使用docker compose(空格)。Compose 的版本号从 v2 直接跳到 v5,用法没有改变。网上的旧教程会混用两者,命令和参数大致相同。
示例项目:网站 + 数据库 + 管理界面
创建文件夹 compose-demo,结构如下:
compose-demo/
├── compose.yaml
└── site/
└── index.html
在 site/index.html 中放一个简单的网页(内容随意)。compose.yaml:
services:
web:
image: nginx:1.30-alpine
ports:
- "8080:80"
volumes:
- ./site:/usr/share/nginx/html:ro
db:
image: postgres:18
environment:
POSTGRES_PASSWORD: example
volumes:
- pgdata:/var/lib/postgresql
adminer:
image: adminer
ports:
- "8081:8080"
depends_on:
- db
volumes:
pgdata:
三个服务:
| 服务 | 作用 |
|---|---|
web | nginx,把 ./site 文件夹用作网站,主机端口 8080 |
db | PostgreSQL 18,数据保存在名为 pgdata 的 Volume 中(注意 18 版挂载的是 /var/lib/postgresql,参见 Volume) |
adminer | 网页版数据库管理工具,主机端口 8081 |
如果用 docker run 编写相同的配置,需要先运行 docker network create、docker volume create,再执行三条很长的 docker run 命令。
启动:docker compose up
在 compose-demo 文件夹中运行:
$ docker compose up -d
[+] up 34/34
✔ Image nginx:1.30-alpine Pulled 7.8s
✔ Image adminer Pulled 8.7s
✔ Network compose-demo_default Created 0.1s
✔ Volume compose-demo_pgdata Created 0.0s
✔ Container compose-demo-web-1 Started 1.7s
✔ Container compose-demo-db-1 Started 0.8s
✔ Container compose-demo-adminer-1 Started 1.0s
一条命令就完成了:下载镜像(Pulled,只有第一次会出现)、创建网络和 Volume、启动三个容器。
$ docker compose ps
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
compose-demo-adminer-1 adminer "entrypoint.sh docke…" adminer 10 seconds ago Up 9 seconds 0.0.0.0:8081->8080/tcp, [::]:8081->8080/tcp
compose-demo-db-1 postgres:18 "docker-entrypoint.s…" db 10 seconds ago Up 10 seconds 5432/tcp
compose-demo-web-1 nginx:1.30-alpine "/docker-entrypoint.…" web 10 seconds ago Up 9 seconds 0.0.0.0:8080->80/tcp, [::]:8080->80/tcp
$ docker network ls --filter name=compose-demo
NETWORK ID NAME DRIVER SCOPE
a722da926fbd compose-demo_default bridge local
$ docker volume ls --filter name=compose-demo
DRIVER VOLUME NAME
local compose-demo_pgdata
- 容器名称的格式是
项目名称-服务名称-编号。项目名称默认是文件夹名称(compose-demo),因此不同文件夹中的项目不会互相干扰。 - Compose 自动创建了
compose-demo_default网络,三个服务都在其中,可以通过服务名称互相连接。 pgdataVolume 的实际名称是compose-demo_pgdata。db没有设置ports,因此 PORTS 列只有5432/tcp,外部无法访问它。
打开 http://localhost:8080:

使用 Adminer 管理数据库
打开 http://localhost:8081,就会看到 Adminer 登录界面。注意 System 默认是 MySQL:

按照以下设置登录:
| 字段 | 填写内容 |
|---|---|
| System | PostgreSQL(一定要修改,否则会尝试用 MySQL 的方式连接并失败) |
| Server | db(服务名称,通过 Compose 网络解析) |
| Username | postgres |
| Password | example(compose.yaml 中的 POSTGRES_PASSWORD) |

登录成功后,界面会显示 PostgreSQL 的版本和数据库列表:

点击左侧的 SQL command,输入 SQL:
CREATE TABLE guestbook (id serial PRIMARY KEY, name text, message text);
INSERT INTO guestbook (name, message) VALUES ('Docker', 'Hello from Compose!');
SELECT * FROM guestbook;

点击 Execute,三条命令会依次执行,最后的 SELECT 会列出刚才新增的数据:

查看日志
$ docker compose logs --tail 2
web-1 | 2026/10/13 00:14:23 [notice] 1#1: start worker processes
web-1 | 2026/10/13 00:14:23 [notice] 1#1: start worker process 30
db-1 | 2026-10-13 00:14:24.205 UTC [71] LOG: database system was shut down at 2026-10-13 00:14:24 UTC
db-1 | 2026-10-13 00:14:24.210 UTC [1] LOG: database system is ready to accept connections
adminer-1 | [Tue Oct 13 00:14:22 2026] PHP 8.4.26 Development Server (http://[::]:8080) started
docker compose logs 会合并显示所有服务的日志,每行前面都会标明对应的服务。--tail 2 只显示每个服务最后 2 行,-f 会持续跟踪,docker compose logs db 则只查看 db。
停止与启动
$ docker compose stop
[+] stop 3/3
✔ Container compose-demo-adminer-1 Stopped 0.4s
✔ Container compose-demo-web-1 Stopped 0.4s
✔ Container compose-demo-db-1 Stopped 0.3s
$ docker compose ps -a
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
compose-demo-adminer-1 adminer "entrypoint.sh docke…" adminer 53 seconds ago Exited (0) Less than a second ago
compose-demo-db-1 postgres:18 "docker-entrypoint.s…" db 53 seconds ago Exited (0) Less than a second ago
compose-demo-web-1 nginx:1.30-alpine "/docker-entrypoint.…" web 53 seconds ago Exited (0) Less than a second ago
$ docker compose start
[+] start 3/3
✔ Container compose-demo-db-1 Started 0.3s
✔ Container compose-demo-web-1 Started 1.0s
✔ Container compose-demo-adminer-1 Started 0.4s
stop 只会停止容器(Exited (0)),容器、网络和 Volume 都还在;start 可以重新启动它们。
down:删除容器,但保留数据
$ docker compose down
[+] down 4/4
✔ Container compose-demo-adminer-1 Removed 0.7s
✔ Container compose-demo-web-1 Removed 0.7s
✔ Container compose-demo-db-1 Removed 0.3s
✔ Network compose-demo_default Removed 0.1s
down 删除了容器和网络,但不会删除 Volume。重新运行 up,数据仍然在:
$ docker compose up -d
[+] up 4/4
✔ Network compose-demo_default Created 0.1s
✔ Container compose-demo-web-1 Started 0.7s
✔ Container compose-demo-db-1 Started 1.1s
✔ Container compose-demo-adminer-1 Started 1.6s
$ docker compose exec db psql -U postgres -c "SELECT * FROM guestbook;"
id | name | message
----+--------+---------------------
1 | Docker | Hello from Compose!
(1 row)
down -v:连数据一起删除
$ docker compose down -v
[+] down 5/5
✔ Container compose-demo-adminer-1 Removed 0.7s
✔ Container compose-demo-web-1 Removed 0.7s
✔ Container compose-demo-db-1 Removed 0.2s
✔ Volume compose-demo_pgdata Removed 0.1s
✔ Network compose-demo_default Removed 0.1s
加上 -v 会同时删除 compose-demo_pgdata Volume,数据库中的数据也就没了。在生产环境中请谨慎使用 down -v。
基本操作汇总
docker compose up -d # 创建并在后台启动所有服务
docker compose ps # 查看服务状态
docker compose logs -f # 跟踪所有服务的日志
docker compose logs -f db # 只查看 db
docker compose stop # 停止(保留容器)
docker compose start # 重新启动
docker compose down # 停止并删除容器和网络(保留 Volume)
docker compose down -v # 同时删除 Volume(数据会消失!)
修改 compose.yaml 后,再运行一次 docker compose up -d,Compose 只会重建有变化的服务(示例见 docker compose 命令)。
项目名称与文件名
- 项目名称默认是文件夹名称,也可以在
compose.yaml最上方指定name: myproject,或使用docker compose -p myproject。 - Compose 默认按顺序查找
compose.yaml、compose.yml、docker-compose.yaml、docker-compose.yml。新项目建议使用compose.yaml。 - 文件开头的
version: "3.8"是旧格式的写法,现在已经不需要了,写了只会出现警告。
下一步
- compose.yaml 语法详解:build、ports、volumes、environment、depends_on、healthcheck……
- docker compose 常用命令
- 实战:用 Compose 搭建 WordPress
重点回顾
- compose.yaml 描述多个服务、网络和 Volume,一条命令就能全部启动。
- Compose 会自动创建项目网络,服务之间通过服务名称连接。
docker compose down会保留 Volume;down -v会删除数据。- Docker Desktop 会将 Compose 项目显示为一组。
动手练习
练习 1:在本章的项目中,用一条命令只查看 db 服务最后 5 行日志。
答案
docker compose logs --tail 5 db
练习 2:运行 docker compose down 后再运行 up -d,Adminer 中创建的数据表还在吗?改用 down -v 呢?
答案
运行 down 后数据还在,因为 pgdata Volume 得到了保留;down -v 会删除 Volume,数据库重新初始化,数据表也就不见了。
常见问题
docker-compose 和 docker compose 有什么不同?
docker-compose(带连字符)是已停止维护的 v1 独立程序;现在使用 Docker CLI 的插件 docker compose(空格),本教程使用 v5。
compose.yaml 和 docker-compose.yml 都可以吗?
都可以,Compose 会按顺序查找。新项目建议使用 compose.yaml。
项目名称是怎么决定的?
默认是 compose.yaml 所在文件夹的名称,容器、网络、Volume 的名称都会加上它作为前缀。可以用 name: 或 -p 指定。
更新于 2026年10月14日