KEEL · 龙骨 · A CURRICULUM FOR THE AI ERA
Docker 应用课:把容器用对 — keel 龙骨
Docker 应用课:把容器用对 的参考信息:Docker 应用课:把容器用对
课程总览 · 从「会敲 docker run」到「能对着一份 Dockerfile 和一份 compose 文件说出它哪里会出事」
容器这个词已经不新鲜了。真正的分水岭不是会不会用,而是能不能预判:这份 Dockerfile 构建出来多大、改动一行代码要等多久、这份 compose.yml 里哪个值会在生产环境不生效、容器收到停止信号时正在处理的请求会不会被切断。
这三类问题有同一个特点:本地跑得通,出事在生产。 本地单机、几秒钟启动、随手 Ctrl-C,把该暴露的问题全遮住了。
三个现场
现场一:改了业务代码,构建却重装了一遍依赖。
一条 COPY . . 之后才 RUN npm install,于是业务代码每改一行,依赖清单那一层就作废一次。本地看不出代价——反正依赖已经缓存了;CI 上每跑一次就是几分钟。这不是"配置调优",是 Dockerfile 的指令顺序在决定层缓存的命中面。
现场二:一份 compose 文件在开发机上好好的,到了测试环境数据库连不上。
depends_on 写了,但用的是默认语义——只保证容器被启动,不保证里面的进程已经能接受连接。数据库还在初始化,api 已经带着连接串冲上去了。要修的不是"加个 sleep",而是把依赖关系表达成可判定的条件。
现场三:发布时容器停了三秒就被强杀,日志里留下半条未提交的订单。
docker stop 先发 SIGTERM,等一段时间再发 SIGKILL。问题是你写在应用里的优雅退出逻辑有没有收到那个信号——这取决于你的 CMD 是哪种形式,以及编排层的等待时间有没有短于应用自己需要的排空时间。
三个现场都不需要 Kubernetes 才能理解,也不需要背命令。它们要的是同一层认知:容器边界在哪里,什么在里面、什么在外面,信号和数据怎么跨过去。
这门课回答什么
| 你可能正在纠结的问题 | 在哪一章 |
|---|---|
docker build . 里那个 . 到底传了什么给谁?为什么构建这么慢? |
01 |
| 层的缓存按什么失效?Dockerfile 指令为什么必须按这个顺序排? | 02 |
多阶段构建怎么落地?npm ci 和 npm install 该选哪个? |
03 |
多个容器怎么编排?depends_on 写了为什么还是连不上? |
04 |
| 配置和密钥怎么进容器才不会被烤进镜像? | 05 |
| 容器停止时,信号到底发给了谁?为什么优雅退出不生效? | 06 |
| 容器被杀但日志什么都没写,从哪查起?什么场景不该用容器? | 07 |
这门课不回答什么
- 不重复镜像供应链那套(按 digest 固定基础镜像、SBOM、
cosign签名、 provenance)。那是《构建打包与部署上线》 第 02 章的落点,本课只在需要处指过去,不重写一遍。 - 不讲 Kubernetes。K8s 的对象模型、调度、声明式收敛是另一门课的内容。本课有意停在单机容器与 Compose 这一层——它是 K8s 的前置,不是它的简化版。
- 不讲容器底层实现原理(namespace、cgroup、OverlayFS 的内核细节)。知道"容器是共享内核的进程"就够了;再往下属于内核文档。本课关心的是使用这一层会遇到的判断。
与相邻课程的分工
| 课程 | 视角 | 本课与它的关系 |
|---|---|---|
| 《构建打包与部署上线》 | 镜像作为发布产物:版本策略、供应链、部署策略、回滚 | 那边管"发出去",本课管"这个产物在盒子里怎么活"。它的 02 章假定你已经会读 Dockerfile |
| 《CI 流水线与质量门禁》 | 流水线闸门与放行判断 | 本课 03 章的构建可重复性,是那边"构建结果一致"要求的前置 |
| 《PostgreSQL 应用课》 | 数据层怎么被正确使用 | 本课 04 章的多服务编排里,数据库是一个真实的依赖方;两边共用同一套 healthcheck 判断 |
阅读顺序上,本课可以独立读。如果你已经在上线流程里干活,建议先读 04–06 三章(编排、配置、停机),它们对现网问题最直接;如果你正准备写第一个生产镜像,按 01→07 顺序走。
学完以后你能做什么
- 拿到一份 Dockerfile,能说出每一行在决定什么,以及哪几行顺序放错了会拖慢构建或把密钥带进镜像;
- 拿到一份
compose.yml,能用解析工具把它展开成实际生效的配置,判断哪个变量会在缺省环境里让服务起不来; - 能解释容器停止的三段时序(TERM → 等待 → KILL),并指出一个优雅退出失效的根因是在哪一层断掉的;
- 知道容器里看不到什么、
exit code 137该往哪个方向查、以及哪些问题根本不该用容器解决。
关于证据口径
这门课里的命令输出分两类,正文会逐处标注:
- 本机真跑的输出:
docker compose ... config系列全部来自本机 Docker CLI 29.2.1 的纯客户端解析(不需要 daemon),npm ci的报错来自本机 Node 22.22.2。这些是原始留档。 - 静态走读:本机 Docker daemon(Docker Desktop)未运行,所以
docker build、docker run、docker stop的执行结果没有实测。凡涉及容器内运行时行为(PID 1 收信号、OOMKill、exit 137),正文按证据强度写成"官方文档 + 逐行走读",不伪装成实测。
这条口径本身也是课程内容的一部分:能分清"我验证过"和"我读到的",是运维判断的起点。
课程导读(起点自检、章节地图、前置要求)见 course/README.md。