127.0.0.1:18006 通过 SSH 隧道到达 ECS 回环端口,再映射到 web:80。
外观
外观
约 2532 字大约 8 分钟
分布式系统Docker Compose服务依赖容器网络
2026-07-30
[Windows PowerShell] wsl ~:打开本机默认的 WSL2 Ubuntu;出现 用户名@主机名:~$ 后再执行标为 [WSL] 的命令。[WSL] ssh root@你的ECS公网IP:从 WSL 连接自己的 ECS;如果登录用户不是 root,请换成控制台显示的实际用户,看到远端提示符后再执行标为 [ECS] 的命令。第五次课的 WordPress 已经包含 Web、PHP 和数据库,但如果只会照着启动,还看不清服务为什么能互相找到,也很难判断某个容器退出后请求停在哪里。
本课把学习站简化成两个容易观察的服务:
web:接收浏览器请求,返回首页,并把 /api/ 转给内部 API;api:只在 Compose 网络中提供 status.json,不映射宿主机端口。页面能显示“API 状态:ok”时,两项服务和内部请求链路才算真正跑通。
安全边界
所有启停命令都要在 ~/cloud-course/lab-06 中执行,并先用 docker compose ls、docker compose ps 确认项目名。不要运行会停止整台服务器所有容器的命令。
分布式系统(多个相互通信的进程或服务共同完成一项业务的系统) 既可以跨多台物理机运行,也能在一台宿主机的多个容器间模拟演练。
把应用拆成多服务后,系统的运行特点也跟着变了。
解耦带来的优势:
随之而来的挑战:
关键提醒
拆分服务不会消灭故障,只会转移故障边界。验收时既要看单个容器的存活,更要验证从浏览器到最深层 API 的完整请求链。
Compose 习惯把几类关键 Docker 对象打成一个项目:
本课涉及两条不同的请求路径:
浏览器 -> ECS 127.0.0.1:18006 -> web:80
web -> Compose 内部网络 -> api:80web:80 和 api:80 能够同时存在,是因为它们分别处于各自独立的容器网络空间里。宿主机只暴露了一个 18006 端口,完全不会触发“80 端口冲突”。
观看时留意:容器之间通信、宿主机端口映射和浏览器访问分别发生在哪一层?
与本课的关系:视频用于回顾网络边界。实际端口和服务名以本课 compose.yaml 为准。
进入 ECS 上的实验目录后,先准备好环境变量文件:
[ECS] mkdir -p ~/cloud-course/lab-06
[ECS] cd ~/cloud-course/lab-06
[ECS] cp starter/.env.example .env
[ECS] chmod 600 .env这里的 .env 仅用来设定入口端口,不放密钥。接着用三条命令做静态检查:
docker compose config --services:列出项目定义的服务名;docker compose config --images:列出各服务依赖的镜像;docker compose config --quiet:检查语法格式与变量展开。[ECS] docker compose config --services
[ECS] docker compose config --images
[ECS] docker compose config --quiet顺利的话会看到 api 和 web。静态检查成功只能说明配置文件写法无误,容器还没跑起来。
需要特别注意 depends_on:它只能控制启动优先顺序(比如在 Web 前等待 API 变得健康),并不是持续的守护进程。如果 API 在后续运行中意外挂掉,Compose 并不会自动杀掉 Web。此时 Web 容器虽然还在,但整个业务其实已经断了。
观看时留意:Compose 文件怎样把多个服务、依赖和启动顺序写在一起?
与本课的关系:视频可能使用旧的 docker-compose 命令。课程命令统一使用 Docker Compose V2 的 docker compose。
启动前检查资源、现有项目和端口:
[ECS] free -h
[ECS] docker compose ls
[ECS] ss -lnt 'sport = :18006'确认 18006 端口未被占用后,再启动:
[ECS] docker compose up -d检查容器:
[ECS] docker compose psapi 不应显示宿主机端口;web 应显示 127.0.0.1:18006->80/tcp。随后检查项目网络中的服务名:
[ECS] docker compose exec web getent hosts api
[ECS] docker compose exec web wget -qO- http://api/status.json第一条确认 api 能被内部 DNS 解析,第二条直接从 Web 容器访问 API。输出 JSON 时,说明内部链路可用。
云主机 B 隔离 Compose 项目 · 2026-07-28 真实运行
root@SYG680400:/opt/xpk-course-demos/lesson-06$ docker compose config --servicesapiweb“展开服务清单”保留了完整命令和与它相邻的输出。判断时应直接引用输出中的字段或状态,不要把步骤名称当成结论。
这一步是“Compose 服务、镜像、健康状态、回环端口、内部 DNS 和 API JSON”证据链中的一环。
只证明捕获时刻的两服务隔离项目,不证明学生环境相同

整页截图与上方分步卡片来自同一条记录;敏感字段已经遮盖,较长命令可能经过换行排版。
把宿主机端口映射与 Compose 服务名通信放到一条请求链中。
127.0.0.1:18006 通过 SSH 隧道到达 ECS 回环端口,再映射到 web:80。
在 WSL 建立 SSH 隧道:
[WSL] ssh -N -L 18006:127.0.0.1:18006 你的ECS登录目标Windows 浏览器打开 http://127.0.0.1:18006/。页面脚本会请求 /api/status.json,Nginx 再将其转发给 api:80。

浏览器页面比单独的 docker compose ps 多验证了一层:不仅证明两个进程在运行,还证明前端真实请求拿到了 API 数据。
docker compose 的常用命令不能混用:
up -d:按当前配置创建或更新并启动服务。ps:查看本项目容器状态和端口。logs:读取本项目服务日志,不改变运行状态。stop api:停止指定服务,容器仍保留。start api:启动已经存在的 API 容器。down:停止并删除本项目容器与网络,默认保留命名卷。只查看最近日志:
[ECS] docker compose logs --tail 20 web api持续跟随日志会占住终端,可用 Ctrl+C 结束查看;这不会停止容器。
故障演练前,先确认当前服务正常:
[ECS] curl -sS http://127.0.0.1:18006/api/status.json只停止当前项目的 API:
[ECS] docker compose stop api分别观察“容器状态”和“业务状态”:
[ECS] docker compose ps
[ECS] curl --max-time 8 -sS -o /dev/null -w 'http=%{http_code}\n' \
http://127.0.0.1:18006/api/status.json
[ECS] docker compose logs --since 30s --tail 8 webWeb 仍可能显示 Up,但 API 请求返回 502/504,日志出现上游连接失败或超时。这正是“单个服务活着,整体业务仍然失败”的例子。
恢复后回归验证:
[ECS] docker compose start api
[ECS] docker compose ps
[ECS] curl -sS http://127.0.0.1:18006/api/status.json云主机 B 隔离 Compose 项目 · 2026-07-28 真实故障演练
...$ curl -sS http://127.0.0.1:18006/api/status.json{"status":"ok","service":"course-api","version":"v2"}这条命令沿实际访问路径发起请求。状态码、响应头或正文是本步的判断依据;只看到一次响应,还不能说明服务长期稳定。
这一步是“Web 保持运行时 API 请求返回 504、日志显示上游超时、API 恢复后重新返回 JSON”证据链中的一环。
只说明本次依赖服务停止故障;其他 504 需要另行定位

整页截图与上方分步卡片来自同一条记录;敏感字段已经遮盖,较长命令可能经过换行排版。
观看时留意:容器进程仍在运行时,里面的应用为什么仍可能不能工作?
与本课的关系:健康检查只覆盖它实际执行的测试。浏览器路径和业务结果还要另外验证。
输入脱敏后的服务、端口、HTTP 或日志,让助教区分配置、容器、内部网络和完整业务链。
本实验的原始聊天仅保存在当前标签页,不会写入全局课程助教上下文。
本课使用三种挂载:
./web:学习站静态页面;./api:API 演示数据;./gateway.conf:网关配置。它们都在项目目录中,适合教学时直接阅读。生产环境还需要考虑镜像版本、只读文件系统、配置发布和权限,本课先把“配置来源”和“容器内位置”对应起来。
.env.example 只描述变量接口。后续涉及密码时:
.env 只在个人环境中保存并限制权限;.env.example 不放有效值;完整步骤见实训 06:部署并排查多服务站点,其中可以下载 compose.yaml、.env.example 和应用文件。
保底任务
config --services、镜像与端口识读;ps、HTTP 和日志判断故障层。标准任务
挑战任务
status.json 的版本号并观察是否需要重建容器;depends_on 不能代替持续健康监控。提交:
班级_学号_姓名_第06次课_DockerCompose多服务报告.docx只上传一个 Word 到智慧职教“第06次课”,不上传 .env、公网地址、SSH 配置或整个容器数据目录。
检查项目范围、内部通信、端口、依赖故障、恢复和清理证据。
完成后可立即查看反馈和解析。
depends_on 解决启动顺序,不保证运行期间依赖永远健康。ps、HTTP 响应和日志结合起来,才能完整反映容器与业务的真实状态。下一次课将把关注点转向数据库,比较复制、备份和恢复三种不同的数据保护能力。
以下资料在 2026-07-28 核对:
助教会读取当前课程页面和结构化学习记录,但不会读取正文实验框里的原始聊天。