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 等常用命令详解(含真实回显)

DockerDockerdocker-compose2026/09/29

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 --servicesdb、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,该命令删除范围大,生产环境慎用。


九、参考链接