Docker Compose 是一个用于定义和运行多容器 Docker 应用的工具。通过一份 YAML 文件(默认 docker-compose.yml),配置应用的所有服务,然后用一条命令就能启动或停止整套应用。
| Compose v1 | docker-compose | 已弃用 |
| Compose v2 | docker compose | 当前推荐 |
💡 从 Docker Desktop 3.4+ 起,v2 已内置;新项目全部用 v2。本文所有命令都是 docker compose(带空格)。
二、安装 Compose
Linux安装
# 创建插件目录
mkdir -p ~/.docker/cli-plugins
# 下载 v2(用你架构对应的名字)
curl -SL https://github.com/docker/compose/releases/latest/download/docker-compose-linux-x86_64 \
-o ~/.docker/cli-plugins/docker-compose
# 加执行权限
chmod +x ~/.docker/cli-plugins/docker-compose
# 验证
docker compose version
# Docker Compose version v2.x.x三、docker-compose.yml 文件结构总览
一份完整的 docker-compose.yml 长这样:
# 选填,版本号(v2 已不强求)version: "3.9"
服务(核心)
services:
web:
build: .
ports:
- "8080:80"
depends_on:
- db
environment:
- DB_HOST=db
networks:
- backend
db:
image: mysql:8.0
volumes:
- db-data:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD=secret
networks:
- backend
网络
networks:
backend:
卷
volumes:
db-data:

四、核心字段详解(速查表)
4.1 services 下的服务定义
每个服务都对应一个容器,常用字段:
image | image: nginx:1.25 | |
build | build: ./webbuild: { context: ., dockerfile: Dockerfile.dev } | |
ports | "8080:80""127.0.0.1:8080:80" | |
environment | KEY=value- .env | |
env_file | env_file: ./app.env | |
volumes | ./src:/appdb-data:/var/lib/mysql | |
depends_on | depends_on: [db, redis] | |
restart | restart: alwaysunless-stopped / on-failure | |
networks | networks: [backend] | |
command | command: python manage.py runserver | |
healthcheck | test: ["CMD", "curl", "-f", "http://localhost"] | |
deploy.resources | limits: { cpus: '0.5', memory: 256M } | |
logging | driver: json-fileoptions: { max-size: 10m } |
4.2 顶层三大块
services: # 服务列表(必填)networks: # 自定义网络(选填)
volumes: # 数据卷(选填)
configs: # 配置(选填,Swarm mode 才有用)
secrets: # 密钥(选填,Swarm mode 才有用)
💡 networks和volumes在顶层定义后,服务里才能引用。 同名 volume 会被自动创建为命名卷。
五、实战案例
5.1:WordPress + MySQL
这是 Docker 官方教程的经典例子:
# docker-compose.ymlservices:
db:
image: mysql:8.0
volumes:
- db_data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: rootpass
MYSQL_DATABASE: wordpress
MYSQL_USER: wp
MYSQL_PASSWORD: wppass
restart: unless-stopped
networks:
- wp-net
wordpress:
image: wordpress:latest
depends_on:
- db
ports:
- "8080:80"
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wp
WORDPRESS_DB_PASSWORD: wppass
WORDPRESS_DB_NAME: wordpress
volumes:
- wp_data:/var/www/html
restart: unless-stopped
networks:
- wp-net
volumes:
db_data:
wp_data:
networks:
wp-net:
driver: bridge
启动:
docker compose up -d浏览器访问 http://localhost:8080,WordPress 安装向导出现了。

几个关键点解释
depends_on: db—— wordpress 容器会先于 db 启动?错!实际上是 db 先启动,wordpress 后启动。 depends_on控制的是启动顺序,不是等就绪。
db是一个"服务名"—— compose 会自动为每个服务注册 DNS 名称。所以 wordpress 里写 WORDPRESS_DB_HOST: db:3306,db就是 MySQL 容器的别名,db:3306会自动解析成它的 IP + 端口 3306。
db:3306而不是localhost:3306—— 因为 WordPress 容器和 MySQL 容器不在同一台机器(只是共享网络 namespace),要用服务名 db来解析 MySQL。
- 顶层的
volumes: db_data:—— 声明一个命名卷。Docker 会自动创建。第一次启动后,WordPress 的文章、上传的图都存在里面。
5.2:FastAPI + Redis + Postgres 三件套
后端项目的场景:
# docker-compose.ymlservices:
api:
build: ./api
ports:
- "8000:8000"
environment:
DATABASE_URL: postgresql://app:app@db:5432/app
REDIS_URL: redis://redis:6379/0
depends_on:
db:
condition: service_healthy # 等 db 健康再起
redis:
condition: service_healthy
restart: unless-stopped
networks:
- backend
db:
image: postgres:16-alpine
volumes:
- pg_data:/var/lib/postgresql/data
environment:
POSTGRES_USER: app
POSTGRES_PASSWORD: app
POSTGRES_DB: app
healthcheck:
test: ["CMD-SHELL", "pg_isready -U app -d app"]
interval: 10s
timeout: 5s
retries: 5
networks:
- backend
redis:
image: redis:7-alpine
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 3s
retries: 5
networks:
- backend
# 可选:Adminer 数据库管理界面
adminer:
image: adminer:4
ports:
- "8081:8080"
depends_on:
- db
networks:
- backend
volumes:
pg_data:
networks:
backend:
driver: bridge

这份配置的高级点
condition: service_healthy—— 解决了"depends_on 不等服务就绪"的老问题。 api会真等db和redis的 healthcheck 通过后才启动。
pg_isready/redis-cli ping—— 两个服务都内置了健康检查命令。Postgres 和 Redis 都是这样查活的。
- 服务名做 DNS
—— api里写DATABASE_URL=postgresql://app:app@db:5432/app,这个db不是 IP,是 docker-compose 自动注册的 DNS。
adminer—— 顺手再加一个数据库 Web UI,访问 http://localhost:8081就能可视化看 Postgres 里的表。调试神器。
六、.env 文件 + 环境变量分层
# .env(项目根,Compose 自动读取)POSTGRES_USER=app
POSTGRES_PASSWORD=secret
POSTGRES_DB=app
API_PORT=8000
ADMINER_PORT=8081
# docker-compose.yml语法:services:
db:
image: postgres:16-alpine
environment:
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: ${POSTGRES_DB}
ports:
- "${POSTGRES_PORT:-5432}:5432"
api:
build: ./api
ports:
- "${API_PORT}:8000"</code></pre><blockquote style="box-sizing: border-box;margin: 18px 0px;padding: 14px 18px;background: rgb(248, 250, 252);border-radius: 10px;border-left: 3px solid var(--light);color: var(--sub);font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Microsoft YaHei", "PingFang SC", sans-serif;font-size: medium;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;white-space: normal;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-style: initial;text-decoration-color: initial;"><section><span leaf="">💡 </span><code style="box-sizing: border-box;font-family: Consolas, "SF Mono", monospace;"><strong style="box-sizing: border-box;"><span leaf="">${VAR:-default}
VAR没设置就用default。很实用。七、
docker compose完整命令速查# 启动(-d 后台,--build 强制重建镜像)docker compose up -d --build
看运行中的容器
docker compose ps
看日志(-f 实时跟踪)
docker compose logs -f
docker compose logs -f api # 只看 api 服务
进容器
docker compose exec api bash
docker compose exec db psql -U app # 直接进 Postgres CLI
停止(不删容器)
docker compose stop
启动已存在的容器
docker compose start
重启某个服务
docker compose restart api
重新构建镜像
docker compose build api
docker compose build --no-cache # 不用缓存
拉镜像
docker compose pull
查看配置(合并 .env 后的最终配置)
docker compose config
优雅停掉并删除容器、网络
docker compose down
删容器、网络、卷(数据没了!)
docker compose down --volumes
删容器、网络、卷、镜像(全清!)
docker compose down --volumes --rmi all
验证 compose 文件语法
docker compose config -q # -q 只输出错误
一个常用的"一键重启服务"组合
# 改了代码 → 重新构建 → 重启该服务 → 看日志docker compose up -d --build api && docker compose logs -f api
八、docker compose: 资源限制 + 日志轮转
资源不限制 → 单容器能跑满整台机器 → 其他服务全卡死。
services:api:
build: ./api
deploy:
resources:
limits:
cpus: '1.0'
memory: 512M
reservations:
cpus: '0.25'
memory: 128M
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"
cpus: 1.0—— 最多用 1 个 CPU memory: 512M—— 最多用 512MB 内存(超了就 OOM kill) logging.max-size—— 单个日志文件最大 10MB,保留 3 个
九、Compose && Swarm && Kubernetes 的工作场景对比
| 单机、多容器、开发/测试环境 | |
💡 一句话定位:- Compose = 单机编排神器(开发、自托管、小团队)- Swarm = Docker 自带的轻量级集群(逐渐被边缘化)- K8s = 工业级容器编排标准(生产大集群)
评论 (0)