确认 Compose、变量示例、应用文件、配置、部署、验收和清理脚本都在同一发布目录。
外观
外观
约 2569 字大约 9 分钟
Docker Compose标准化配置展开环境变量
2026-07-30
[Windows PowerShell] wsl ~:打开本机默认的 WSL2 Ubuntu;出现 用户名@主机名:~$ 后再执行标为 [WSL] 的命令。[WSL] ssh root@你的ECS公网IP:从 WSL 连接自己的 ECS;如果登录用户不是 root,请换成控制台显示的实际用户,看到远端提示符后再执行标为 [ECS] 的命令。第 6 次课已经用 Compose 组织过 Web 与 API。今天不再追求“多启动一个容器”,而是把项目整理成其他人拿到后也能看懂、部署、验收和清理的标准包。
关键提醒
标准化交付不是只有 compose.yaml。完整发布包还要说明配置来源、运行边界、健康条件、验收路径、故障恢复、清理方法和不能打包的敏感文件。
学完这一课,做到五件事:
docker compose config 查看变量插值后的真实配置。running、healthy 和用户路径可用。deploy.sh、verify.sh 和 cleanup.sh。拿到目录的人应该能直接找到配置入口、公开变量模板、部署脚本、验收脚本和清理方法。实际变量留在本地,敏感文件不进入发布包。
接下来的检查围绕四件事展开:配置能否完整展开、服务是否真正健康、相同输入能否安全重复部署、清理是否只移除本项目。
本课的交付工程规范结构如下:
lab-14/
├── compose.yaml
├── .env.example
├── .gitignore
├── deploy.sh
├── verify.sh
├── cleanup.sh
├── api/status.json
├── web/index.html
└── nginx/default.conf| 文件 / 目录 | 承担职责 | 准入交付包规范 |
|---|---|---|
compose.yaml | 声明服务定义、依赖关系、健康检查、端口与挂载目录 | 是 |
.env.example | 提供公开的变量占位符与教学默认值 | 是 |
.env | 保存当前部署环境的实际变量值 | 否,仅在部署时由本地复制生成 |
.gitignore | 防止 .env 与日志/证据材料被提交至代码库 | 是 |
deploy.sh | 自动化脚本:先做配置检查,再启动并等待健康就绪 | 是 |
verify.sh | 自动化脚本:分层校验静态配置、运行态、端口与 HTTP 接口 | 是 |
cleanup.sh | 自动化脚本:仅清理本项目专属的容器与网络 | 是 |
api/、web/、nginx/ | 提供项目基础数据与代理入口配置文件 | 是 |
观看时留意:服务、网络、卷和配置分别应该出现在 Compose 文件的哪一层?
与本课的关系:视频用于回顾 YAML 结构。课程统一使用 Compose V2,并以 docker compose config 的展开结果为准。
如果代码仍依赖“本地电脑里某个没有打包的隐藏文件”,接收者就无法复现部署。私钥、.env 实际值、数据库原始卷和全局日志不应进入交付包。
Compose 支持 ${VARIABLE} 插值。最终值可能来自 shell、--env-file 或项目 .env,因此只读 compose.yaml 还看不到真实模型。
name: ${COMPOSE_PROJECT_NAME:-cloud-course-lab-14}
ports:
- 127.0.0.1:${COURSE_PORT:?copy .env.example to .env}:80第一行给项目名一个默认值。端口使用 :? 必填形式:没有 COURSE_PORT 时直接报错,避免空值悄悄变成错误配置;127.0.0.1 把入口限制在宿主机回环地址。
进入 ECS 本课目录:
[ECS] cd /opt/xpk-course-demos/lesson-14/release进入课程专用发布目录。使用个人环境时,换成课程分配的路径。
[ECS] cp .env.example .env创建当前部署的实际变量文件。复制后先检查项目名和端口,避免与同学或已有服务冲突。
[ECS] docker compose --env-file .env config --environment \
| grep -E '^(COMPOSE_PROJECT_NAME|COURSE_PORT)='只保留本课允许展示的两个插值变量。不要直接截图未经筛选的 config --environment 完整输出:它还可能带出当前 Shell 的 SSH_CLIENT、SSH_CONNECTION 或其他环境变量。
[ECS] docker compose --env-file .env config合并文件、解析变量并展开简写,输出 Docker Engine 将接收的规范化模型。官方文档把它定义为“parse, resolve and render”。
2026-07-28 在云主机 B 的隔离项目中实际展开:
云主机 B 隔离项目 · 2026-07-28 真实运行
root@SYG680400:/opt/xpk-course-demos/lesson-14/release$ docker compose config --servicesapiweb“展开服务清单”保留了完整命令和与它相邻的输出。判断时应直接引用输出中的字段或状态,不要把步骤名称当成结论。
这一步是“配置展开后包含 api/web、项目名、端口、service_healthy、healthcheck 与 127.0.0.1:18014”证据链中的一环。
配置可展开不代表容器已启动、健康或 HTTP 可用

整页截图与上方分步卡片来自同一条记录;敏感字段已经遮盖,较长命令可能经过换行排版。
观看时留意:声明了 depends_on 后,为什么仍要检查依赖服务是否真正就绪?
与本课的关系:配置展开、启动顺序和应用就绪是三层不同证据,本课会逐层验收。
沿目录、变量、配置展开、健康、用户路径和清理顺序检查一个 Compose 标准包。
确认 Compose、变量示例、应用文件、配置、部署、验收和清理脚本都在同一发布目录。
Compose 中两个服务都定义健康检查:
healthcheck:
test:
- CMD-SHELL
- wget -q -O - http://127.0.0.1/healthz | grep -q web-ok
interval: 5s
timeout: 3s
retries: 6
start_period: 5s容器内每 5 秒访问一次 /healthz;3 秒无结果算失败,启动前 5 秒为宽限期,连续失败会进入 unhealthy。检查命令必须真实覆盖应用就绪条件,不能只写永远返回 0 的占位命令。
depends_on:
api:
condition: service_healthyweb 等待 api 进入 healthy 后再启动。它优化了启动顺序,但不意味着运行期间 api 故障时 web 会自动重启或业务一定可用。
观看时留意:running、healthy 和用户实际可用为什么不能写成同一个状态?
与本课的关系:健康检查通过后还要访问主页和接口,确认交付内容与预期版本一致。
[ECS] ./deploy.sh脚本先执行 config --quiet,随后使用 up -d --wait --wait-timeout 60。Docker 官方说明 --wait 会等待服务达到 running 或 healthy,并自动使用后台模式。
[ECS] docker compose --env-file .env ps查看容器状态和端口。Up (healthy) 是容器健康的证据,还要继续验证用户入口。
[ECS] curl --max-time 5 -fsS http://127.0.0.1:18014/检查主页是否返回预期标题。--max-time 限制等待,-f 让 HTTP 错误返回失败,-sS 保持输出简洁但显示错误。
[ECS] curl --max-time 5 -fsS http://127.0.0.1:18014/api/status.json通过 web 代理访问 API。预期包含 "status":"ok",它覆盖了入口 Nginx、项目网络、API 容器和静态状态文件。
云主机 B 隔离项目 · api 与 web 真实健康检查
...$ docker compose psSERVICE IMAGE STATUS PORTSapi nginx:1.27-alpine Up 31 seconds (healthy) 80/tcpweb nginx:1.27-alpine Up 25 seconds (healthy) 127.0.0.1:18014->80/tcp这条命令读取运行状态。应关注服务名称、健康状态、就绪数量和端口映射,不要只凭命令返回了表格就判断业务正常。
这一步是“api/web 均 healthy,课程端口只绑定回环地址,主页和代理 API 返回预期,自动验收通过”证据链中的一环。
只证明捕获时刻的本机用户路径,不证明公网开放或长期稳定

整页截图与上方分步卡片来自同一条记录;敏感字段已经遮盖,较长命令可能经过换行排版。
部署脚本不是只能成功一次。第二次运行前,先记录容器 ID:
[ECS] docker compose --env-file .env ps -q api显示 api 容器完整 ID。对 web 再执行一次并记录前 12 位即可,报告不需要提交完整 ID。
[ECS] ./deploy.sh再次执行同一个部署脚本。配置和镜像没有变化时,Compose 保持现有容器并等待健康;若配置发生变化,up 可能重建受影响的服务。
[ECS] ./verify.sh按第一次的路径再次验收。重复部署通过的判断包括:
同一发布目录重复执行 deploy.sh · 真实运行
...$ find . -maxdepth 2 -type f -printf '%P\n' | sort.env.example .gitignore compose.yamlapi/status.json cleanup.sh deploy.shnginx/default.conf verify.sh web/index.html“列出目标文件”保留了完整命令和与它相邻的输出。判断时应直接引用输出中的字段或状态,不要把步骤名称当成结论。
这一步是“同一标准包第二次部署保持两项容器 ID,服务再次达到 healthy,自动验收继续通过”证据链中的一环。
不能证明配置或镜像变化时无需重建,也不能替代升级与回滚验证

整页截图与上方分步卡片来自同一条记录;敏感字段已经遮盖,较长命令可能经过换行排版。
.env本课故障只操作发布目录中的变量文件:
[ECS] mv .env .env.saved把当前 .env 保存为 .env.saved,保留原值以便恢复。不要打开后随意改端口,也不要删除文件。
[ECS] ./deploy.sh预期脚本立即提示“缺少 .env”并退出,不会改变正在运行的容器。这是“尽早失败”:在配置边界不清楚时拒绝继续。
[ECS] mv .env.saved .env恢复原变量文件。
[ECS] ./deploy.sh && ./verify.sh重新部署并按原路径验收。预期容器健康、主页和 API 通过。
安全边界
不要通过创建空 .env、临时改成已有业务端口或删除未知容器来“消除报错”。先恢复经过验证的原文件,再重新展开配置。
打包前按顺序检查:
| 检查项 | 合格证据 | 常见问题 |
|---|---|---|
| 目录完整 | find 能列出 Compose、配置、脚本和应用文件 | 漏掉 Nginx 配置或状态文件 |
| 配置可展开 | docker compose config --quiet 退出 0 | 变量缺失、路径失效 |
| 敏感文件排除 | .gitignore 与压缩包清单都不含 .env | 把实际端口或密钥当示例提交 |
| 健康检查有效 | api/web 均 healthy | 检查命令永远成功 |
| 入口最小暴露 | host_ip: 127.0.0.1 | 写成 0.0.0.0 |
| 重复部署 | 第二次部署和验收通过 | 脚本只适合首次运行 |
| 清理可控 | 只 down 当前项目 | 按镜像名或全局删除容器 |
输入脱敏后的目录、config、ps、health、HTTP 或第二次部署证据,让助教判断交付是否完整。
本实验的原始聊天仅保存在当前标签页,不会写入全局课程助教上下文。
[ECS] ./cleanup.sh脚本读取本目录 .env,只执行当前 Compose 项目的 down --remove-orphans,随后确认没有项目容器。它不删除镜像、命名卷或其他项目。
[ECS] ss -lnt 'sport = :18014'检查本课回环端口是否释放。预期只有表头,没有监听行。
[ECS] docker ps --format '{{.Names}} {{.Ports}}'复核既有业务容器仍在运行。只核对本人环境或课程指定范围,不停止未知容器。
完整步骤见实训 14:Compose 标准发布包与重复部署。
提交:
班级_学号_姓名_第14次课_Compose标准化交付报告.docx只提交一个 Word 到智慧职教“第14次课”。不提交 .env、日志全集、容器导出包、密钥或服务器地址。
检查发布目录、配置展开、健康、重复部署、故障恢复、清理和隐私边界。
用 6 道题检查配置展开、环境变量、健康、重复部署、故障恢复和清理。
docker compose config 展示变量与简写解析后的真实模型。.env 时应尽早失败,恢复原值后重新展开和验收。下一次课将把声明式思想带到 K3s,认识节点、Pod、Deployment 与 Service。
以下资料在 2026-07-28 核对:
助教会读取当前课程页面和结构化学习记录,但不会读取正文实验框里的原始聊天。