Docker Compose 编排
Docker Compose 是一个用于定义和运行多容器 Docker 应用的工具。通过一个 compose.yml(旧称 docker-compose.yml)配置文件,你可以同时管理多个容器(例如 Web 服务、数据库、缓存等),并使用一条命令启动/停止整个应用栈。容器与网络基础见 容器、数据与网络。
一、安装
- Windows / macOS:Docker Desktop 默认已包含
docker compose(Compose V2,作为dockerCLI 的子命令),无需额外安装。 - Linux:
bash
# 通过官方 docker-ce 仓库安装时会自带 compose 插件 sudo apt update sudo apt install docker-compose-plugin -y # 或安装独立的旧版二进制(V1,命令为 docker-compose,官方已不再更新新特性) sudo apt install docker-compose -y
验证安装:
docker compose version
# Compose V2 写法,注意 compose 前没有连字符
docker-compose --version
# 旧版 V1 命令,很多教程和脚本里仍能看到
V1 与 V2 的区别:V2 是用 Go 重写、作为
docker子命令集成的新版本,命令是docker compose(空格);V1 是独立的 Python 程序,命令是docker-compose(连字符)。新项目应统一使用 V2,本文命令均以docker compose为主,多数场景下把空格换成连字符即对应 V1 写法。
二、compose.yml 基础示例
以下是一个包含 Nginx Web 服务和 Redis 缓存服务的 Compose 文件:
services: # 定义服务(容器)
web: # 服务名称
image: nginx # 使用的镜像
ports:
- "8080:80" # 端口映射 宿主机:容器
volumes:
- ./html:/usr/share/nginx/html # 挂载本地目录到容器
depends_on: # 依赖关系(启动顺序,不是等待就绪)
- redis
redis:
image: redis:alpine # 使用轻量版 Redis
ports:
- "6379:6379"
environment: # 环境变量
- REDIS_PASSWORD=mysecret
字段说明:
services:定义每个容器,名称可自定义,同一网络内可直接用服务名互相访问(Compose 会自动创建一个专属网络)。image:指定镜像(也可以使用build从 Dockerfile 构建)。ports:端口映射。volumes:数据卷或绑定挂载。environment:设置环境变量。depends_on:设置服务依赖(仅影响启动顺序,不保证服务已就绪,需配合健康检查)。
关于
version字段:Compose V2 已不再需要在文件顶部声明version: "3.8",写了也会被忽略(并给出弃用提示);新项目建议直接省略。
三、常用命令
所有命令需在 compose.yml 所在目录执行。
| 命令 | 说明 |
|---|---|
docker compose up -d | 后台启动所有服务(-d 守护模式) |
docker compose up -d --build | 启动前先重新构建镜像(build 字段的服务) |
docker compose down | 停止并删除容器、网络(默认保留数据卷) |
docker compose down -v | 同时删除数据卷(-v) |
docker compose logs -f | 跟踪所有服务的日志输出 |
docker compose logs -f web | 只跟踪指定服务 web 的日志 |
docker compose ps | 查看当前项目的服务状态 |
docker compose exec web bash | 进入 web 服务的容器中执行命令 |
docker compose build | 重新构建服务(用于 build 指令的镜像) |
docker compose restart | 重启所有服务 |
docker compose stop / start | 停止 / 启动已存在的服务(不删除容器) |
docker compose config | 验证并查看解析后的最终配置(合并多文件、变量替换后) |
docker compose pull | 拉取所有服务声明的镜像最新版本 |
docker compose top | 查看各服务容器内的进程 |
docker compose scale web=3 / docker compose up -d --scale web=3 | 将 web 服务扩展到 3 个实例(需服务不绑定固定宿主机端口) |
四、常用场景示例
1. 使用 Dockerfile 构建自定义镜像
services:
app:
build: . # 使用当前目录下的 Dockerfile
ports:
- "3000:3000"
environment:
- NODE_ENV=production
2. 链接多个服务(Node.js + MongoDB + Redis 多服务示例)
一个更接近真实项目的例子:Node 应用依赖 MongoDB 存储数据、Redis 做缓存,并通过环境变量文件和健康检查确保依赖服务就绪后才启动应用。
services:
web:
build: .
ports:
- "3000:3000"
env_file:
- .env # 从文件读取环境变量,避免敏感信息写入 compose.yml
environment:
- MONGO_URL=mongodb://mongo:27017/app
- REDIS_URL=redis://redis:6379
depends_on:
mongo:
condition: service_healthy # 等待 mongo 健康检查通过再启动
redis:
condition: service_started
restart: unless-stopped
mongo:
image: mongo:7
volumes:
- mongo-data:/data/db # 命名卷,持久化数据库文件
healthcheck:
test: ["CMD", "mongosh", "--eval", "db.adminCommand('ping')"]
interval: 10s
timeout: 5s
retries: 5
restart: unless-stopped
redis:
image: redis:7-alpine
volumes:
- redis-data:/data
restart: unless-stopped
volumes:
mongo-data: # 声明卷,由 Docker 管理
redis-data:
要点:
depends_on配合condition: service_healthy才能真正「等待服务就绪」,仅声明依赖名不会等待应用初始化完成。env_file把配置和密钥从版本控制中分离,配合.gitignore忽略.env文件。restart: unless-stopped让服务在宿主机重启或异常退出后自动恢复,但手动docker compose stop不会被自动拉起。
3. 多环境配置(开发 / 生产覆盖)
Compose 支持多文件叠加,常见做法是把公共配置放在 compose.yml,环境差异放在 compose.override.yml(默认自动加载)或显式指定的文件中。
# compose.yml(生产基线)
services:
web:
build: .
restart: always
# compose.override.yml(本地开发,默认自动与上面合并)
services:
web:
volumes:
- .:/app # 挂载源码实现热更新
environment:
- NODE_ENV=development
command: npm run dev
# 默认会自动加载 compose.yml + compose.override.yml
docker compose up -d
# 生产环境显式只用基线文件,忽略 override
docker compose -f compose.yml up -d
# 显式叠加多个文件(顺序即优先级,后者覆盖前者)
docker compose -f compose.yml -f compose.prod.yml up -d
4. 使用 .env 文件做变量替换
Compose 会自动读取同目录下的 .env 文件,用于替换 compose.yml 中的 ${VAR} 占位符(区别于 env_file,后者是把内容注入到容器环境变量)。
# .env
IMAGE_TAG=1.25
WEB_PORT=8080
services:
web:
image: nginx:${IMAGE_TAG}
ports:
- "${WEB_PORT}:80"
五、常见排错
| 现象 | 可能原因与排查方法 |
|---|---|
docker compose up 后容器立即退出 | 查看 docker compose logs <service> 看应用报错;确认镜像的 CMD/ENTRYPOINT 不是一次性任务(如未加 -d 前台运行的临时命令) |
| 服务之间无法互相访问 | 确认使用服务名而非 localhost 通信(Compose 内部通过服务名 DNS 解析);确认服务在同一个 Compose 项目/网络中 |
端口冲突:port is already allocated | 宿主机端口已被占用,改用其他宿主机端口,或用 docker ps / lsof -i:端口号 排查占用进程 |
修改了 compose.yml 但不生效 | 需要重新 docker compose up -d(会重建有变化的服务);镜像本身变化需先 docker compose build 或加 --build |
| 数据卷里是旧数据 | 卷的生命周期独立于容器,docker compose down 默认不会删除卷;确认是否需要 -v 一并清理,或直接 docker volume rm |
depends_on 似乎没等服务就绪 | 默认 depends_on 只保证启动顺序,不保证应用初始化完成,需配合 healthcheck + condition: service_healthy,或在应用层做重试连接逻辑 |
| 权限错误,容器内无法写挂载目录 | 检查宿主机目录权限与容器内运行用户的 UID/GID 是否匹配,或以 --user $(id -u):$(id -g) 运行 |
docker compose 命令找不到 | Compose V2 未安装为插件;确认 docker compose version 是否有输出,或改用 docker-compose(V1,需单独安装) |
| 构建后容器仍使用旧代码 | docker compose build 时缓存了旧的层;用 docker compose build --no-cache 或调整 Dockerfile 中 COPY 顺序(见 镜像与 Dockerfile) |
排错的通用思路:先用 docker compose ps 确认哪个服务状态异常,再用 docker compose logs -f <service> 看具体报错,配合 docker compose config 检查变量替换和多文件合并后的最终配置是否符合预期。
六、总结
- Docker Compose 简化了多容器应用的编排,适合开发、测试和中小规模生产部署。
- 通过一个
compose.yml文件定义服务、网络、数据卷,使用一条命令即可管理整个应用栈。 - 常用命令:
up、down、logs、exec、build等,结合-d可实现后台运行;depends_on+healthcheck才能真正保证依赖服务就绪。 - 多文件叠加(
compose.override.yml、-f多文件)与.env变量替换,可以优雅地管理开发/生产等多环境差异。 - Compose 可与单机 Docker 无缝配合,但不适用于跨多主机的集群(需要使用 Docker Swarm 或 Kubernetes)。
掌握 Docker Compose,可以高效地管理复杂应用的多容器依赖,提升开发和部署效率。
参考文献
| 资料 | 说明 |
|---|---|
| Docker Compose 文档 | 官方 |
| Compose 文件参考 | 完整字段说明 |
| Compose 健康检查依赖 | depends_on + healthcheck |
| 运维导读 | 学习路径 |
相关文章
镜像与 Dockerfile
镜像(Image)是 Docker 容器的只读模板,Dockerfile 则是构建镜像的蓝图。本文完整覆盖镜像的搜索、拉取、查看、删除、打标签、推送,以及 Dockerfile 常用指令、多阶段构建与体积优化技巧。
Docker 基础概念、安装与命令速查
Docker 是一个开源的容器化平台,能将应用程序及其所有依赖打包成轻量级、可移植的容器。本文介绍核心概念、底层原理、跨平台安装配置,并附完整的命令速查表,是学习 Docker 的第一篇。
容器、数据与网络
容器是镜像的运行实例,掌握容器的创建、管理、日志查看,配合数据卷持久化与自定义网络通信,是使用 Docker 的日常核心,也是生产部署前必须掌握的三大基础能力。
运维与协作导读
本目录覆盖日常开发运维中的 Git 版本控制、Docker 容器化与 Nginx 服务网关,与 工程化 · Git、部署相关 等章节互补,提供完整的十阶段学习路径。
后端入门概览
本目录覆盖 JavaScript/TypeScript 服务端运行时与框架、数据存储,以及 Rust 系统编程入门,提供从零到部署的完整学习路径。前置建议:JavaScript 基础、工程化 · 环境变量。
Bun 基础与核心命令
Bun 是用 Zig 编写的 JavaScript 运行时,内置包管理(bun install)、打包(bun build)、测试(bun test)等,并持续兼容 Node.js API。本文介绍核心特点、安装方式,以及日常最常用的命令与包管理功能。见 运行时对比。
Series
docker
1 / 4