Docker Compose 安装与多容器编排
在 Ubuntu 22.04 安装 Docker Compose V2,编写 docker-compose.yml 编排 nginx+redis+mysql 多容器应用,执行 docker compose up -d 启动并联调容器。含 compose 版本确认、服务/网络/卷定义、port/volumes/environment/depends_on、以及 ps/logs/exec/down 等常用命令详解(含真实回显)
Docker Compose 安装与多容器编排
目标:在 Docker Engine 基础上安装 Compose V2,编写
docker-compose.yml一键编排 nginx + redis + mysql 三个容器组成的应用,用docker compose up -d启动并验证服务互通与常用命令。本文在 Docker 29.8.1 + Compose v5.5.1(Ubuntu 22.04)实测。
环境信息
- 系统:Ubuntu 22.04.5,Docker 29.8.1
- Compose:
docker compose(V2,Docker Compose version v5.5.1) - 编排应用:
myapp= nginx(web) + redis(缓存) + mysql(数据库) 三容器 - 网络:自定义 bridge
myapp-net;卷:db-data(mysql 数据持久化)
一、安装 Compose V2
Compose V2 已随 docker-compose-plugin 一并安装(见 yaml 里 docker-compose-plugin 项)。若需单独确认:
docker compose version
回显:
Docker Compose version v5.5.1
说明:V2 使用
docker compose(空格)子命令,替代旧版独立的docker-compose二进制。which docker-compose在新版可能为空,属正常。
二、编写 docker-compose.yml
在项目目录 /srv/myapp 编写编排文件:
services:
web:
image: nginx:1.27-alpine # 前端 Web
container_name: myapp-web
restart: always
ports:
- "8080:80" # 宿主机8080 -> 容器80
volumes:
- ./html:/usr/share/nginx/html:ro # 挂载静态站(只读)
depends_on: # 启动顺序:先 redis/db
- redis
- db
networks:
- myapp-net
redis:
image: redis:7.2-alpine # 缓存
container_name: myapp-redis
restart: always
command: ["redis-server", "--appendonly", "yes"]
ports:
- "6379:6379"
networks:
- myapp-net
db:
image: mysql:8.0 # 数据库
container_name: myapp-db
restart: always
environment: # 初始化 root 密码/数据库
MYSQL_ROOT_PASSWORD: q1w2e3r4
MYSQL_DATABASE: appdb
ports:
- "3306:3306"
volumes:
- db-data:/var/lib/mysql # 数据持久化卷
networks:
- myapp-net
volumes:
db-data: # 命名卷声明
networks:
myapp-net:
driver: bridge # 自定义 bridge 网络
关键概念:
| 关键字 | 作用 |
|---|---|
services | 定义一组容器(每个 services 子项即一个服务/容器) |
image | 指定镜像,本地没有会自动拉取 |
container_name | 可选的固定容器名(不写则由 compose 自动命名) |
ports | 宿主机端口:容器端口映射,用于对外暴露 |
volumes | 目录/卷挂载;./html:/usr/share/nginx/html 为 bind,db-data:/var/lib/mysql 为命名卷 |
environment | 注入环境变量,mysql 镜像用它初始化数据库 |
depends_on | 指定启动先后顺序(仅等就绪,不保证完全可连) |
networks | 让服务同处一个自定义网络,可用服务名互访 |
restart | 容器退出时的重启策略(always 常驻) |
三、一键启动:docker compose up -d
cd /srv/myapp
docker compose up -d
首次执行会先拉取三个镜像,再自动创建网络、卷和容器并后台启动。回显(节选):
Network myapp_myapp-net Creating
Volume myapp_db-data Creating
Container myapp-redis Creating
Container myapp-db Creating
Container myapp-redis Created
Container myapp-db Created
Container myapp-web Creating
Container myapp-web Created
Container myapp-db Starting
Container myapp-redis Starting
Container myapp-db Started
Container myapp-redis Started
Container myapp-web Starting
Container myapp-web Started
-d表示 detached 后台运行,不占用终端。查看由 compose 管理的服务与生成的容器:
docker compose ps
回显:
NAME IMAGE SERVICE STATUS PORTS
myapp-db mysql:8.0 db Up 10 seconds 0.0.0.0:3306->3306/tcp, 33060/tcp
myapp-redis redis:7.2-alpine redis Up 11 seconds 0.0.0.0:6379->6379/tcp
myapp-web nginx:1.27-alpine web Up 12 seconds 0.0.0.0:8080->80/tcp
也可以直接用原生 docker ps 查看全部容器(包含端口映射信息)。
四、验证服务互通
4.1 访问 Web(nginx)
curl -s http://127.0.0.1:8080/
回显(对应挂载的 html/index.html 内容):
<h1>Hello Docker Compose</h1>
4.2 读容器日志
docker compose logs --tail=5 web
回显(节选):
myapp-web | [notice] 1#1: start worker process 36
myapp-web | 172.19.0.1 - - [29/Sep/2026:05:16:16 +0000] "GET / HTTP/1.1" 200 30 ...
logs聚合查看服务日志,-f跟踪(--tail=N只看末尾 N 行)。
4.3 在两个容器中执行命令(docker exec)
直接往 redis 写入读取:
docker exec myapp-redis redis-cli ping # PONG
docker exec myapp-redis redis-cli set name "compose-test"
docker exec myapp-redis redis-cli get name # compose-test
对 mysql 建表并插入数据:
docker exec myapp-db mysql -uroot -pq1w2e3r4 -h127.0.0.1 appdb \
-e "CREATE TABLE items(id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(50));"
docker exec myapp-db mysql -uroot -pq1w2e3r4 -h127.0.0.1 appdb \
-e "INSERT INTO items(name) VALUES('compose-mysql'); SELECT * FROM items;"
回显:
+----+---------------+
| id | name |
+----+---------------+
| 1 | compose-mysql |
+----+---------------+
说明:容器内 mysql 的 socket 位置可能因存储驱动而异(本文环境为
/var/lib/mysql/mysql.sock),用-h127.0.0.1走 TCP 更稳妥。
五、常用命令详解
| 命令 | 作用 |
|---|---|
docker compose up -d | 首次构建并后台启动全部服务 |
docker compose up -d redis | 只启动指定服务 |
docker compose ps | 查看服务运行状态与端口 |
docker compose config --services | 仅列出编排文件中的服务名 |
docker compose logs -f web | 跟踪某服务日志 |
docker compose exec redis redis-cli ping | 进入运行中容器执行命令 |
docker compose restart | 重启服务 |
docker compose build | 重新构建镜像(配合 build: 使用) |
docker compose down | 停止并删除容器/网络(默认保留命名卷) |
docker compose down -v | 停止并删除容器/网络/卷(数据一并删除,慎用) |
docker compose exec是已创建容器的操作入口,等价于docker exec,适合联调调试;exec需要在容器运行中执行,run则临时起新容器。
六、验证清单
| 检查项 | 预期 |
|---|---|
docker compose version | 输出 Compose v5.5.1 |
docker compose config --services | db、redis、web |
docker compose up -d | 三容器均 Started |
curl http://127.0.0.1:8080/ | 返回挂载的网页内容 |
| redis / mysql 读写 | 写入并读取成功 |
docker compose down | 容器与网络被清理 |
七、常见问题 / 踩坑
depends_on只保证顺序不保证就绪:mysql 首次启动初始化较慢,立即连会报Can't connect,等初始化完成后重试,或用健康检查(healthcheck)配合condition: service_healthy。- 端口冲突
address already in use:宿主端口已被占用,改ports映射或在docker compose up前ss -lntp排查。 cannot connect to the Docker daemon:compose 命令行需能访问 dockerd,确认docker info可用,权限不足时加sudo或加入 docker 组。storage-driver受限环境拉/跑镜像报invalid argument:同 Docker Engine 一篇,需把 daemon.json 存储驱动临时切换为vfs。down后数据还在:命名卷默认保留以便复用;确认要清空再加-v。
八、卸载
停止并移除 compose 管理的容器与网络(默认保留命名卷):
cd /srv/myapp
docker compose down
连命名卷一并删除(数据一并删除,慎用):
docker compose down -v
确认无残留:
docker compose ps
提示:如需彻底清理 Docker 占用(停止全部容器、删除所有镜像/卷/网络/构建缓存),可用
docker system prune -a,该命令删除范围大,生产环境慎用。
九、参考链接
- Docker Compose 官方文档:https://docs.docker.com/compose/
- Compose 文件规范:https://docs.docker.com/reference/compose-file/