Day 20 / 共 20 天 · 结业 🎓

部署与收官(七框架对比)

昨天(Day 19)把产品造出来、验好货;今天让它正式上岗营业——怎么把 OpenClaw 部署上线(Docker/compose/fly/render/podman),怎么安全地开门(绑定与鉴权)。然后回顾 20 天全程,并把你学过的七大框架横向对比收官。

📍 你在整门课的位置(第 4 周收官 · 结业 🎓)
D16 沙箱 D17 安全 D18 原生App D19 构建SDK D20 部署收官 🎓
🤔 痛点:部署最容易踩的坑——"图省事把它开到公网" 本地跑通了,想让手机随时能连,于是随手把网关绑到公网、还嫌配 token 麻烦省了。结果:一个连着你所有聊天账号、能执行命令的服务,就这么裸奔在互联网上,谁都能来敲门。部署不是"能连上就行",而是"怎么在能用和安全之间画对那条线"。今天几种部署方式的差异、以及默认只听本机的设计,全是在帮你避开这个坑。
💡 用一个类比兜住整天(「助理开门营业」世界观) 今天全程一个画面:让你的 AI 助理"开店上岗"多阶段 Dockerfile = 后厨装修归装修(一堆工具编译),但只把做好的菜(dist + 生产依赖)端进干净的门店,装修队和料头不进店(镜像小、攻击面小)。compose / fly / render / podman = 四种"开店方式":家里自建、租云铺面、托管一条龙、以普通身份开的安全小店(rootless)。绑定与鉴权 = 门怎么开:默认只对内营业(loopback,只听本机),要对外迎客(lan)就必须先装门锁(配 token)——延续第 4 周"默认最严、按需放开"的一贯姿态。七框架对比 = 上岗前的"同行考察":看清 OpenClaw 在整条街里最不一样的定位。记住"让助理安全开门营业",今天全通。
L01

多阶段 Dockerfile

Dockerfile(249 行)多阶段构建:

  • ext-deps:27):只抽 opted-in 扩展的 package.json(避免扩展改动使主层缓存失效)。
  • build:40):node:24-bookworm,pnpm install --frozen-lockfile(带 store cache),pnpm build:docker + ui:build
  • runtime-assetspnpm prune --prod + 删 .d.ts/.map。
  • runtime:114):非 root USER node,只 COPY dist/node_modules/extensions/skills;HEALTHCHECK /healthzCMD node openclaw.mjs gateway --allow-unconfigured
"多阶段构建"省什么? 构建时需要一堆工具(编译器、全部依赖),但运行时不需要它们。多阶段构建:在"build 阶段"用全套工具编译,然后只把产物(dist + 生产依赖)拷进干净的"runtime 阶段"。最终镜像小、攻击面小、不含源码和构建工具。非 root 用户运行、健康检查、缓存优化(ext-deps 单独抽出减少缓存失效)都是生产级 Docker 的标准实践。
多阶段构建:装修队不进门店,只端成品进去 build 阶段全套工具链+全依赖pnpm build:docker(体积大,不上线) runtime-assetsprune --prod删 .d.ts/.map(只留生产件) runtime 阶段(上线镜像)USER node(非root)只 COPY dist/依赖/skillsHEALTHCHECK /healthz 最终镜像不含源码/编译器/开发依赖 → 小、快、攻击面小
图注:编译在"重"阶段做,产物搬进"轻"的 runtime 阶段——门店里没有装修队和料头。
L02

docker-compose

# docker-compose.yml —— 两个服务
openclaw-gateway:   # gateway --bind lan --port 18789,映射 18789/18790,healthcheck
openclaw-cli:       # network_mode: service:openclaw-gateway(共享网络)
                    # cap_drop: [NET_RAW, NET_ADMIN], security_opt: no-new-privileges
# 挂载 OPENCLAW_CONFIG_DIR → /home/node/.openclaw
#      OPENCLAW_WORKSPACE_DIR → …/workspace
# 注释掉的 docker.sock 挂载 = 可选开启沙箱隔离(Day 16)
读法:compose 一键起"网关 + CLI"两个容器。注意默认不挂 docker.sock(Day 16 说过危险)——只有你显式要沙箱隔离才挂。辅助脚本 docker-setup.sh(20KB)读 token、装 compose、按需配 docker.sock。
L03

fly / render 云部署

平台要点
fly.toml进程 gateway --port 3000 --bind lan,force_https,min_machines_running=1 + auto_stop_machines=false(保持长连接),openclaw_data → /data
render.yamldocker web 服务,healthCheckPath:/healthOPENCLAW_GATEWAY_TOKEN: generateValue:true(自动生成),1GB 磁盘挂 /data
读法:auto_stop_machines=false 很关键:OpenClaw 靠长连接(渠道 WebSocket、node 设备),机器不能自动休眠,否则连接断。持久数据挂 /data(配置/工作区/记忆)。render 自动生成网关 token(免手配)。
L04

rootless podman(生产推荐)

setup-podman.sh(11KB)一次性宿主配置:创建非登录 openclaw 用户、loginctl enable-linger(让 rootless podman 无需登录常驻)、生成 OPENCLAW_GATEWAY_TOKEN(chmod 600)、podman build + 装 launch 脚本或 systemd Quadlet。

为什么生产推荐 rootless podman? Docker 守护进程通常以 root 跑——一旦被攻破影响大。rootless podman 让容器以普通用户身份运行,没有 root 守护进程,安全性更高。enable-linger 让这个普通用户的服务开机自启、常驻(不用他登录)。对一个 7×24 在线、连着你所有账号的个人助理,"以最小权限跑"是明智的——这延续了整个第 4 周"默认最安全"的姿态。systemd Quadlet 则让容器像系统服务一样被管理(开机启动、崩溃重启)。
L05

绑定与鉴权

部署最关键的安全点(.env.example + SECURITY.md):

  • env 优先级:process env → ./.env → ~/.openclaw/.env → openclaw.json env 块
  • gateway.bind 默认 loopbacksrc/gateway/call.ts:152)——只监听本机。
  • 绑定超出回环(lan)时必须OPENCLAW_GATEWAY_TOKEN(或 password)。
  • Web/Control UI 仅本地用;远程走 SSH 隧道或 Tailscale,勿直接暴露公网
  • 健康探针:/healthz(liveness)、/readyz(readiness)。
读法:默认只听本机(loopback)是最安全的起点;要让手机/其他设备连,才开到 lan 并强制配 token。这又是"默认最严、按需放开"(Day 16/17 一以贯之)。绝不建议裸奔公网——个人助理连着你的一切,暴露公网风险极高。
📝 举个例子:从"只对内"到"让手机连"要改什么 默认(gateway.bind=loopback:只监听 127.0.0.1,同一台机器上的 CLI/Web UI 能用,外部设备连不上——最安全的起点。
要让手机(Day 18 的 node)连进来:① 改 bind=lan(监听局域网);② 此时系统强制你配 OPENCLAW_GATEWAY_TOKEN(或 password),没配直接拒绝启动;③ 远程访问别开公网,走 SSH 隧道或 Tailscale。→ 开一扇门就必须同时装一把锁,系统不给你"开了门忘了锁"的机会。

👶 小白:云平台不是都爱"没请求就自动休眠省钱"吗?为什么 fly 要特意关掉 auto_stop_machines

👨‍🏫 老师:因为 OpenClaw 靠的是长连接——各渠道的 WebSocket、你手机 node 的连接,都是"一直挂着"的。普通网站没请求时休眠没事,来请求再唤醒。但 OpenClaw 一旦休眠,这些长连接全断了,Telegram 消息推不进来、手机也掉线,助理就"失联"了。所以必须 min_machines_running=1 + auto_stop=false 让它 7×24 醒着。这也解释了为什么它更像"一个常驻服务"而不是"一个按需网站"。

L06

20 天全景

主题核心收获
W1入门与全景个人助理定位、Gateway 控制平面、消息旅程、配置(本周单独成篇)
W2Agent 大脑内嵌 Pi 内核、两层故障转移、执行循环、提示词、两套记忆
W3技能与渠道skills 渐进披露、extensions 注入、渠道抽象/实现、消息归一化
W4运行时/安全/部署Docker 沙箱、安全纵深、原生 App、构建 SDK、部署
如果只记一件事:OpenClaw = "控制平面 + 渠道 + 大脑 + 技能 + 沙箱"五件套。
消息从渠道进 → Gateway 归一化+路由 → 大脑(内嵌 Pi + 编排外壳)想+做 → 用技能扩本领、在沙箱里安全执行 → 答复原路返回。它的独特价值不在"造了个 Agent 引擎"(那是 Pi),而在"把一个 Agent 变成可靠、安全、随处可达的个人产品"的全套工程。
L07

七框架终极对比

框架语言定位你带走的核心思想
einoGo强类型编排框架组件 + 编排、编译期准备
OpenHandsPy/TS软件工程 Agent事件流 + Runtime 解耦
crewAIPython多智能体协作角色分工 + 事件总线
AutoGPTPython可视化工作流平台Block 图 + 低代码
SuperAGIPythonAgent 运行平台循环在 DB/队列、GUI 调度
LangGraphPy/JS状态图运行时图 + 通道 + 每步检查点
OpenClawTS个人 AI 助理产品控制平面 + 多渠道 + 编排外壳
OpenClaw 在这七个里最"不一样"的点 前六个都是给开发者的框架/库/平台——你用它们 Agent。OpenClaw 是唯一一个"面向个人用户的成品"——它本身就是一个能用的助理。而且它不自造 Agent 引擎(内嵌 Pi),把精力全花在"产品级工程"上:多渠道接入、故障转移、安全纵深、原生 App、一键部署。这教会你一个重要区分:做"Agent 引擎"和做"Agent 产品"是两回事——后者 90% 的工作是引擎之外的编排、韧性、安全、集成。这也是从"能跑的 demo"到"能用的产品"之间的鸿沟。
七个框架的共同设计哲学(这才是最大的收获):接口/实现分离(ChatModel/Block/ChannelPlugin/streamFn 无处不在)、统一抽象(把异构收敛成一个接口)、编译期/加载期准备、运行期高速默认最小权限 + 纵深防御优雅降级/故障转移。这些跨语言、跨框架、跨时代通用——具体 API 会过时,这些思想不会。
L08

结业寄语 🎓

🎉 恭喜完成 OpenClaw 20 天!

你从"个人 AI 助理是什么",走到了它的每一层:Gateway 控制平面、内嵌 Pi 的大脑、故障转移与记忆、技能与扩展、二十多个渠道的统一抽象、Docker 沙箱与安全纵深、原生 App 协议、构建与部署。

更重要的是——这是本系列的第 7 个框架。你现在看任何一个 AI 系统,都能条件反射地问:它用什么抽象?怎么编排?状态存哪?怎么保证韧性和安全?信任边界画在哪?它是"引擎"还是"产品"?这套从源码里提炼架构与设计哲学的眼光,比记住任何一个 API 都值钱。

框架会更新,明星项目会更替,但你建立的"看穿一个系统"的能力会一直陪着你。继续读源码,继续动手造。下一个项目见!🦞🚀

✋ 动手

cd /Users/bitmart/work/codes/github/openclaw
sed -n '1,50p' Dockerfile | head -40
cat docker-compose.yml | head -40
grep -n 'gateway.bind\|loopback' src/gateway/call.ts | head
🏁 OpenClaw 教程全部完成——回到 20 天总目录学习主页 探索更多框架。
← Day 19 构建 返回总目录 →