KEEL · 龙骨 · A CURRICULUM FOR THE AI ERA
02 · 跑起第一个交付包 — keel 龙骨
上一章说的「自带的包」,这一章给它一个实物。装它只有一条命令,就在包的根目录下敲:
上一章说的「自带的包」,这一章给它一个实物。装它只有一条命令,就在包的根目录下敲:
./install.sh
前置:手边要有一只解开的交付包。它由课程配套项目打出来(怎么打的在第 3 章);
这一章你要做的是把它跑起来,以及看懂它一路打出来的每一行。
会一点命令行就够,不需要会写代码。
一、它会一路打出什么
命令跑完,屏幕上是这样一串(节选,逐段都对得上):
==> 前置检查
==> docker 29.8.2 / 可用磁盘 58376932KB
==> 校验制品完整性
==> 全部制品校验通过
==> 导入镜像(不访问外网)
==> docker load < board__1.0.0.tar
Loaded image: board:1.0.0
==> docker load < postgres__16-alpine.tar
Loaded image: postgres:16-alpine
==> 生成现场配置
==> 已写入 .../.env(权限 600),数据库密码为现场随机生成
==> 启动
Container board-db-1 Started
Container board-db-1 Healthy
Container board-migrate-1 Exited
Container board-web-1 Started
Container board-worker-1 Started
==> 等待 web 就绪
==> web 已就绪
==> 自检
制品校验 通过
db running / healthy
web running / healthy
worker running / healthy
GET /healthz HTTP 200
GET /readyz HTTP 200
结构版本 2
这份输出把「成功的形状」写得非常清楚。看最后一屏自检就够做判断:
三个服务 running,两个探针 200,结构版本是一个数字 2。
(两个探针问的是两个问题:/healthz 回答「进程还活着吗」,/readyz 回答「它真能干活吗」;
结构版本是数据库结构当前在第几版,迁移一次就往前走一版。)
它像什么?像一个不联网的安装程序:带着自己要用的每一个零件上门,装完自己验一遍。
真实形态就是上面那几行——docker load 读的是包里的 board__1.0.0.tar,
没有一步去网上取东西。
二、这五步分别在做什么
顺序不能换,每一步失败时现场状态都不一样:
| 步 | 它在做什么 | 失败了说明什么 |
|---|---|---|
| 1 前置检查 | 确认 docker 在、daemon 活着、磁盘够 | 这台机器还装不了,一个容器都还没建 |
| 2 校验制品 | 用 MANIFEST.sha256 逐个比对哈希 |
包在搬运途中被改坏/搬家不完整,不要继续装 |
| 3 导入镜像 | docker load 把两只镜像 tar 灌进本机 |
制品没进来,后面 compose 会去 pull(见下一章) |
| 4 生成现场配置 | 照 env.example 生成 .env,密码现场随机生 |
密码只在现场产生,不来自我们、也不进任何制品 |
| 5 起栈并自检 | 起数据库 → 迁移 → web/worker,然后自检 | 半启动状态,得看自检哪条是 bad |
第 3 步里有一行值得单独记住: Container board-migrate-1 Exited。
它不是错误——migrate 是一次性进程,跑完库结构就该退出,它的成功形态就是「退出码 0 且不再运行」。
把它当成故障,是现场最常见的一次误判。
三、两种一定会撞上的报错
① 少了配置就启动。 交付包解开了、.env 还没生成时直接 docker compose up:
error while interpolating services.db.environment.POSTGRES_DB: required variable BOARD_DB_NAME is missing a value
error while interpolating services.migrate.image: required variable BOARD_IMAGE is missing a value
...(每个用到的地方各报一条)
注意它的时机:在解析期就失败了,一个容器都没创建。 这是刻意的设计——
宁可在起任何东西之前死,也不要起了一半再死。
② 包被改过。 交付包里的文件动过一处,校验那一关当场拦下:
env.example: FAILED
sha256sum: WARNING: 1 computed checksum did NOT match
[失败] 制品校验失败:镜像包与 MANIFEST 不一致。**不要继续安装** —— 用原始介质重新拷贝一次。
中止发生在任何有副作用的动作之前:镜像没被导入、配置没被写、容器没被起。
四、它不是什么
- 跑通
install.sh,不等于这套系统在你现场就跑对了。 它只证明「制品进来了、五步走完了」。
真正要看的还有自检里那个结构版本对不对得上——那是
《私有化交付工程 · 升级与回滚》里的事。 已存在,跳过不是失败。 再跑一遍install.sh,你会看到已存在,跳过:board__1.0.0.tar和.env 已存在,保持不动,密码与数据都不变——
它本来就设计成可以重复执行,手抖跑第二遍不会把第一遍弄坏。
读完你能做什么
- 用一条命令把整个交付包装起来、跑起来,并看懂屏幕上的五段各是什么;
- 认出「成功」的形状(三个服务 running、两个探针 200、一个结构版本号);
- 说清
Exited的那一行为什么是好消息,以及缺配置为什么会在起容器之前就失败。
下一步:包跑起来了,但它装的是我们的程序。下一章把它换成你自己的东西——
一条打包命令,加一个最容易看错的点。