mem_limit · healthcheck 与 start_period · restart 退避 · json-file 轮转与磁盘巡检
在 VPS 24/7 跑 OpenClaw 的团队常被三类问题打穿:Gateway 首轮冷启动被过短的 healthcheck 判死、mem_limit 低于 WASM 峰值触发 Exit 137、以及默认 json-file 日志把宿主机磁盘写满。本文给出开发 compose 与生产 compose 的最小差异集、六步可复现基线与抖动重启的人工介入条件,并与Exit 137 与 allowedOrigins 排障长文、镜像钉扎与回滚互链阅读。
开发机上的 compose 往往关闭资源上限、缩短健康检查窗口、并把日志打到控制台;这些设置在长期无人值守场景会叠加成重启风暴:容器在 Gateway 尚未就绪时被判定 unhealthy,restart: always 以秒级频率拉起,日志文件在退避前就把 inode 或磁盘配额打满。
与纯应用容器不同,OpenClaw 的首轮编译与模型加载会抬高 RSS 峰值;若你只按「稳定运行后」的均值设 mem_limit,会在凌晨被 OOM killer 静默处决。本文刻意把可观测信号写进基线:每条参数都能在工单里对应到 docker inspect 或宿主指标。
start_period 过短:健康探针在 Gateway 监听 18789 之前就失败,面板显示「一直重启」。
mem_limit 与峰值脱节:首轮 WASM 或依赖安装尖峰超过 cgroup 上限,退出码 137 却无明确应用日志。
json-file 默认无限增长:通道回调与模型调试日志在高流量 PR 验证期把根分区写只读。
restart 无退避:配置错误与健康误判叠加,形成 CPU 与 IO 双重饥饿。
开发卷挂载进生产:热重载目录与宽松权限把密钥面暴露在备份脚本之外。
下列对照以同一仓库两份 override为前提:docker-compose.yml 保留通用服务定义,docker-compose.prod.yml 仅追加生产差异,避免复制粘贴漂移。
| 维度 | 开发默认 | 生产基线建议 |
|---|---|---|
| 内存 | 不设上限或仅宿主机物理上限 | 显式 mem_limit,并预留首轮尖峰余量;与 Exit 137 文交叉复核 |
| 健康检查 | 短 interval、无 start_period | start_period 覆盖冷启动;retries 与 timeout 与 SLA 对齐 |
| 重启 | unless-stopped 或无 | on-failure 或带上限的 always,并配宿主级告警 |
| 日志驱动 | json-file 默认或 local | max-size + max-file;禁止依赖手工 truncate |
| 卷与密钥 | 绑定挂载源码目录 | 只读挂载配置;密钥来自 env_file 或 secret,不进镜像层 |
生产 compose 的差异应能逐条在 Grafana 或工单系统里找到对应指标,否则只是愿望清单。
以下步骤假设镜像已按钉扎策略固定标签;若仍使用 :latest,请先在 staging 实例完成一次完整冷启动采样再迁移到生产 override。
采样峰值:在 staging 跑 docker stats --no-stream 与容器内 ps,记录 Gateway 首次 Ready 前后 10 分钟的 RSS 峰值。
写入 mem_limit:将峰值乘以约定安全系数写入 compose;同时在宿主保留 swap 策略说明,避免 silent OOM。
定义就绪探针:使用与 Gateway 监听同环回地址的 HTTP 或 CMD,避免探测走公网链路。
设置 start_period:覆盖首轮依赖安装与 WASM 编译窗口;数值应大于 p95 冷启动时长而非均值。
收紧 json-file:为每个服务声明 logging 块并设 max-size 与 max-file;在磁盘巡检脚本中校验日志目录增长率。
演练重启:人为注入一次失败探针,确认重启间隔、退避与告警路由符合值班手册。
services:
openclaw:
mem_limit: "2g"
logging:
driver: json-file
options:
max-size: "20m"
max-file: "5"
healthcheck:
test: ["CMD", "curl", "-f", "http://127.0.0.1:18789/health"]
interval: 30s
timeout: 5s
retries: 5
start_period: 180s
restart: on-failure:5
提示:具体健康路径以你镜像内实际路由为准;若仅 TCP 监听可用,可改用 CMD-SHELL 与 nc 探测,但要在工单中写明与 HTTP 探针的差异与误报面。
当 docker events 显示同一服务在 5 分钟内重启超过值班手册阈值,应优先怀疑配置错误与健康误判而非单纯「内存不够」。此时继续依赖自动重启只会放大日志写放大效应。
若根分区已进入只读模式,先切流量或停反代,再按Exit 137 长文中的顺序释放空间;切勿在未确认磁盘健康时强行 compose up -d 覆盖数据卷。
注意:降低 max-file 会加快旧日志轮转丢失速度;若合规要求保留更久,应同步把冷日志推到对象存储或独立日志宿主,而不是无限增大单文件。
冻结发布:连续重启超过阈值时先禁用自动部署流水线入口。
抓取现场:导出 inspect 中 Health 与 OOM 相关段落与最近 200 行日志。
回滚配置:恢复到上一版 compose override 并保留复现包供复盘。
下列数值为立项与值班手册起点,须用你们真实冷启动直方图与磁盘增长率替换;不得直接宣称为对客 SLA。
当同一 VPS 还承担反代或小型数据库时,mem_limit 与日志 IO 会与邻居争用;评审时应要求负责人同时给出容器 RSS、宿主可用内存与磁盘写延迟三条曲线。
| 宿主规格信号 | 日志策略起点 | 与镜像钉扎关系 |
|---|---|---|
| 2 vCPU / 4 GB | 更小 max-size、更短保留、更积极外发 | 必须钉 digest 避免隐性升级拉长冷启动 |
| 4 vCPU / 8 GB | 可适度放宽 max-file,仍禁止关闭轮转 | staging 与 prod 使用不同 tag 但同源 digest 验证 |
| 混合负载 | 独立数据盘或单独日志卷,避免与数据库同分区 | 升级窗口与回滚脚本与钉扎文对齐 |
把 OpenClaw 绑在临时低配实例上,会在内存、磁盘与密钥轮换三方面同时欠账;自建裸金属又被电力与线路 SLA 绑架。
对需要合同化算力、可选区域与可复核带宽、又要让 Gateway 与通道在 24/7 场景保持可观测的团队,VpsMesh 的 Mac Mini 云端租赁通常是更优解:可把 Compose 基线与反代、备份策略放在同一容量故事里验收。
核对探针运行用户与 PATH、以及 start_period 是否覆盖冷启动;仍异常时对照allowedOrigins 与反代长文检查是否走了错误环回地址。
先看宿主 dmesg 与容器退出码,再回到峰值采样调整 limit;详细步骤见Exit 137 排障文。选型可参考价格页。
会缩短本地热日志窗口,需要更长留存时应外发集中存储或对象存储;运维政策见帮助中心。