跳转到内容

第 35 节 · Docker 速通:运行容器 + 写 Dockerfile

一句话回答

Docker = 把你的 Agent + 依赖 + 运行环境打成一个"集装箱"。 本地能跑只是第一步;要让 CI、CNB Pipeline 和 NPC 稳定运行,就必须把环境也一起交付。

为什么需要 Docker

为什么需要 Docker 打包

你 Day6 的 Agent 在本地能跑,但:

  • 队友电脑上 Python 版本不一样 → 跑不起来
  • CNB 流水线要启动你的 Agent → 不知道怎么装依赖
  • 你重装系统后 → 环境没了
  • NPC 要在云端响应评论 → 需要一个可重复启动的运行时

Docker 解法:代码、依赖、系统工具、入口脚本一起打进镜像里,到哪儿都一样。

5 个核心概念(大二够用)

概念一句话类比
镜像 Image打包好的"模板"做好的蛋糕模具
容器 Container镜像跑起来的一个实例用模具做出来的一个蛋糕
Dockerfile描述"怎么做这个模具"的说明书蛋糕配方
Registry存放镜像的仓库蛋糕模具商店
Volume容器里的持久化文件夹蛋糕店的冷柜

今天只需要掌握前三个:Dockerfile → image → container

Dockerfile 速通

我们的 Dockerfile 用两阶段构建(生产里很常见):

dockerfile
# ==== Stage 1: 构建 ====
FROM python:3.11-slim-bookworm AS builder
WORKDIR /build
COPY . /build
RUN pip install --no-cache-dir openai numpy pyinstaller
RUN pyinstaller --onefile --name my-agent main.py

# ==== Stage 2: 运行 ====
FROM debian:bookworm-slim AS runtime
RUN apt-get update \
    && apt-get install -y --no-install-recommends ca-certificates git bash curl jq \
    && rm -rf /var/lib/apt/lists/*
COPY --from=builder /build/dist/my-agent /usr/local/bin/my-agent
COPY npc-entrypoint.sh /usr/local/bin/npc-entrypoint
ENTRYPOINT ["/usr/local/bin/npc-entrypoint"]

为什么两阶段

阶段包含什么特点
builderPython + pip + pyinstaller + 全部源码适合编译,体积大
runtime只有运行所需二进制 + git / bash 等工具适合部署,体积小

最终推送到 Registry 的主要是 runtime 层——通常会明显更小,也少带很多不需要的构建工具。

2026 年 Python 镜像的几个实践

实践原因
优先用 slim,谨慎用 AlpinePython 生态里很多包有 C 扩展,Alpine 可能导致编译慢或兼容坑
apt-get install --no-install-recommends少装不必要依赖
安装完清理 /var/lib/apt/lists/*减少镜像层体积
pip install --no-cache-dir不要把 pip 下载缓存塞进镜像
.dockerignore不要把 .git、虚拟环境、缓存、日志复制进构建上下文
不要把 Secrets 写进镜像API key 应该运行时从平台 Secrets 注入
构建后 smoke test镜像能 build 不代表入口真的能跑

这些不是炫技,是为了让镜像小、快、可复现、少泄密

关键坑:glibc 版本必须对齐

builder 用 python:3.11-slim-bookworm,runtime 也尽量用 debian:bookworm-slim。 如果 builder 用了更新的 Debian(比如 trixie),编译出的二进制可能依赖更新 glibc, 但 runtime 里没有 → 运行时报 GLIBC_2.xx not found

这类问题最烦,因为 Docker build 阶段可能成功,真正跑 NPC 时才炸。所以课程模板刻意让 builder / runtime 都基于 bookworm。

我们的 NPC 镜像还多了什么

课程模板还会额外处理两件事:

dockerfile
FROM docker.cnb.cool/looc/git-cnb:latest AS gitcnb

FROM debian:bookworm-slim AS runtime
COPY --from=gitcnb /app/git-cnb /usr/local/bin/git-cnb
COPY --from=builder /build/dist/my-agent /usr/local/bin/my-agent
COPY npc-entrypoint.sh /usr/local/bin/npc-entrypoint
文件作用
my-agent你的 Coding Agent 二进制
git-cnb回写 Issue / PR 评论
npc-entrypoint把 CNB 事件翻译成 my-agent --solo exec

跑一下试试

bash
# 构建镜像(在包含 Dockerfile 的目录里执行)
docker build -t my-agent:latest .

# 跑一下看看 help
docker run --rm --entrypoint /usr/local/bin/my-agent my-agent:latest --help

# 用交互模式进容器看看里面有什么
docker run --rm -it --entrypoint bash my-agent:latest

如果镜像默认 ENTRYPOINTnpc-entrypoint,直接 docker run my-agent:latest --help 可能会走 NPC 逻辑;调试时可以用 --entrypoint 覆盖。

动手试试

  1. 用提供的 Dockerfile 模板,改一下 COPY . /build 路径(如果你的目录结构不同)
  2. 本地 docker build -t my-agent:latest . 构建一次
  3. --entrypoint /usr/local/bin/my-agent 确认二进制能跑
  4. --entrypoint bash 进容器确认 my-agentgit-cnbnpc-entrypoint 都在

不要从零写 Dockerfile——今天重点是 Skills + NPC,Docker 只是"交通工具"。

小结

  • Docker = 打包环境的"集装箱"
  • Dockerfile = 构建说明书,两阶段构建让 runtime 更小、更稳定
  • Python 镜像优先 slim;不要把 Secrets、缓存、虚拟环境打进去
  • 关键坑:builder 和 runtime 的 glibc 版本要对齐
  • NPC 镜像必须同时包含 Agent、回写工具和入口脚本

Released under the MIT License.