ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

OpenClaw 简化部署指南:基于 AWS 单节点架构与运维实践

OpenClaw 简化部署指南:基于 AWS 单节点架构与运维实践

把 OpenClaw 的官方部署文档翻完一遍后,我反正是被劝退过一次。架构图画了六七个组件,一会儿要消息队列、一会儿要高可用数据库,光是部署文档里的前置依赖就能列出一整页。但实际用起来,自己做一个内部工具或者给一个小团队用,根本不需要这么重的底座。

这篇文章就是我在 AWS 上实际把 OpenClaw 简化部署完之后的记录。我会告诉你一个更直接的路线:一台 EC2、一个 S3 桶、一个最小权限的 IAM 角色,再配上一份 systemd 服务配置,就可以把 OpenClaw 跑起来并长期维护。这套方案没有砍掉安全步骤,只是把高可用、自动扩展、托管数据库这些“生产环境增强项”暂时放到一边,让第一次接触的人能在一个下午内把东西操作起来,并且知道出了问题该去哪里查。

1. 这个简化版不是偷工减料:先搞清楚 OpenClaw 在 AWS 上到底需要什么

1.1 OpenClaw 的组件和运行依赖

OpenClaw 本身是一个开源的服务端组件,核心做的事情可以理解为“把任务收拢、调度、执行,再把结果推出去”。它的运行通常由三部分配合完成:负责接收任务与暴露接口的主进程、负责真正跑脚本或命令的执行器、负责保存元数据和运行记录的状态存储。

在官方默认的完整架构里,这三部分可能被拆到不同机器上,中间再用消息队列解耦。但简化部署时,完全可以跑在同一台 EC2 上,主进程同执行器之间通过本机回环网络通信,状态存储使用本地 SQLite 文件,日志走系统自带的 journald 或 logrotate。这样不仅减少了一半的组件,排障时也不需要跳好几台机器去查日志。

基础运行依赖其实很低。OpenClaw 是编译好的静态二进制,依赖于 Linux 内核的基本能力,不需要预先安装数据库、不需要单独装 PHP 或 Node.js 之类的东西。我曾经在一台 1 核 1GB 内存的机器上跑过一段时间,日常占用大概在几百 MB 内存,CPU 也主要是集中在执行任务的瞬间。所以选型门槛比想象中低很多。

1.2 简化版与完整版的差距在哪里

我把完整版和简化版的关键差异总结成下面这张表,方便你判断自己到底需要哪一层。

对比项完整部署方案本文的简化版
节点数量多节点负载均衡单台 EC2
调度依赖分布式消息队列应用内调度 + systemd
数据库PostgreSQL 独立实例本地 SQLite
外部入口ALB / CDN / API Gateway弹性 IP 直连端口
备份策略跨区域复制 + 自动恢复演练每日 S3 定时同步
适用场景正式产品、多人团队、SLA 要求高内部工具、小团队、个人项目

这不是“功能上偷工减料”,而是用更简单的组件替代了复杂组件。SQLite 在低并发、单写多读的场景下稳定性足够好;systemd 对进程守护和自动重启的支持也完全够用。只要你不追求多节点同时执行任务,这套方案能覆盖绝大多数使用场景。

2. 动手之前的四步准备:账号、权限、网络和选型

2.1 一个最小可用的 IAM 策略,不要给服务器绑管理密钥

在 AWS 上部署应用时,最常被忽略但影响最大的是权限设计。很多人图省事,直接给 EC2 关联一个 AdministratorAccess 角色,或者干脆在服务器里保存一个永不过期的访问密钥。这两种做法都属于给自己埋雷。

简化版的做法是创建一个专门的角色,只授权访问备份所需的 S3 桶。在 EC2 控制台创建实例时,把这个角色挂到实例上。OpenClaw 运行时通过实例配置文件自动获取临时凭证去读写对象存储,不会在服务器里存任何长期密钥。下面是一条最小范围的 IAM 策略,只需要给你自己的桶授权:

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:ListBucket", "s3:GetObject", "s3:PutObject", "s3:DeleteObject" ], "Resource": [ "arn:aws:s3:::your-openclaw-backup-bucket", "arn:aws:s3:::your-openclaw-backup-bucket/*" ] } ] }

这里唯一需要改的是桶名,后面备份脚本也会用到它。不要为这个角色额外加上 ec2:* 的权限,备份任务不需要它。

如果你的 EC2 已经启动并且之前没有绑定角色,不需要重建实例。在控制台选中实例,找到“操作”里的“修改 IAM 角色”选项,把角色加上即可。这个动作不会中断实例,也不会影响已运行的服务。

2.2 地域和实例规格怎么选

地域选择优先考虑“离 OpenClaw 的主要调用方近”。如果这个服务是给你自己写的小工具用的,你日常在哪个区域管理资源就选哪个区域;如果它是给某个业务系统做任务调度的,那就选业务系统所在的区域。跨地域调用虽然也能跑通,但网络延迟会体现在每一次任务提交和执行状态回传上,没必要为了省钱跨半个地球。

规格方面,我建议从 t3.micro 或 t3.small 起步。t3.micro 是 1 核 1GB,适合每天几百次小任务;t3.small 是 1 核 2GB,适合任务频繁一点或脚本稍微吃内存的场景。这类实例有 CPU 积分机制,如果长期满负荷跑,性能会受限。所以如果业务是那种每天都有大量定时任务且持续输出的,请直接选计算型或通用型系列,别贪便宜。

存储卷建议用 gp3,并且把根卷容量从默认值调大,至少给到 40GB。OpenClaw 的运行日志、执行产物、临时文件加起来会比你想象中涨得快,根卷太小会导致后面频繁清日志。gp3 的单价不高,多出来的成本几乎可以忽略,省下的是后续磁盘告警的运维时间。

2.3 安全组:一条 SSH、一条应用端口、一条健康检查,足够了

安全组是 AWS 上的实例防火墙,配错了最常见的表现就是“服务明明在跑,外面却访问不到”。简化版只需要几条入站规则。

协议/端口来源用途
TCP 22你本地的固定 IP 或小型办公网段SSH 管理
TCP 8080调用方所在的网段或安全组OpenClaw API 端口
TCP 8080你自己的跳板机 IP健康检查与排查

注意不要把 TCP 22 开放给 0.0.0.0/0。我之前见过有人把 SSH 端口全放开,结果实例被扫描爆破,这是完全可以通过安全组规避的风险。如果你的入口 IP 不固定,更推荐的方式是通过 IAM 配合会话管理功能登录,这样甚至可以不开 22 端口。

出站规则保持默认即可,也就是允许全部出站。如果你们公司有严格的出站管控,至少保证实例能访问 S3 的 HTTPS 端点,以及 NTP 的时间同步端口,否则备份和时间同步都会出问题。

2.4 存储:避开数据库“看似省事实际麻烦”的坑

在简化部署里,我特意没有使用 AWS 的托管关系型数据库。原因不是它不好,而是对于单节点运行的 OpenClaw,数据库实例本身成了一个额外的运维对象。你需要维护连接数、处理备份、关注版本升级,而这些对一个小规模应用来说负担太重。

OpenClaw 的状态存储用本地 SQLite 文件就够了。SQLite 在低并发下表现很出色,单写多读的模式也正是 OpenClaw 调度引擎的场景。它会锁住写入,但 OpenClaw 本身在简化模式下就是单节点运行,多个执行器本机并发写入时,SQLite 的锁策略完全能扛住。

为了避免未来需要替换实例时数据丢失,我会把 OpenClaw 的数据目录单独放到一块 EBS 数据卷上,而不是用根卷。这样即使实例发生故障,你也可以把数据卷从旧实例解绑并挂到新实例上,数据立刻就能恢复。实际操作中,如果只是个人测试,单独数据卷不是必选项;但你想让服务能长治久安地跑下去,这一条非常值得做。

3. 从空机器到 OpenClaw 跑起来:完整部署步骤

3.1 用用户数据脚本和环境变量固定配置,防止重启之后傻眼

我习惯在创建 EC2 实例时就把初始化工作写成用户数据脚本,而不是等机器起来后再手工敲命令。这样做的最大好处是:以后想复制一套新环境时,只需要重放这份脚本,生成过程可复现,不会出现“上次我少装了什么导致服务起不来”的情况。

下面这份脚本的思路是:更新系统包、创建专用用户、准备目录、写入 OpenClaw 的配置文件。下载链接可以用你实际部署包的发布地址替换。

#!/bin/bash set -euo pipefail # 更新系统 export DEBIAN_FRONTEND=noninteractive apt-get update -y apt-get install -y curl unzip rsync logrotate chrony # 创建目录和用户 useradd --system --home /opt/openclaw --shell /usr/sbin/nologin openclaw mkdir -p /opt/openclaw/bin mkdir -p /opt/openclaw/data mkdir -p /opt/openclaw/logs # 下载 OpenClaw(替换为实际发布的下载地址) curl -fsSL "https://example.com/openclaw/latest/openclaw-x86_64.tar.gz" \ -o /tmp/openclaw.tar.gz tar -xzf /tmp/openclaw.tar.gz -C /opt/openclaw/bin chown -R openclaw:openclaw /opt/openclaw # 写入环境变量 cat > /opt/openclaw/env.conf <<'EOF' OPENCLAW_HOME=/opt/openclaw OPENCLAW_DATA_DIR=/opt/openclaw/data OPENCLAW_LISTEN_ADDR=0.0.0.0:8080 OPENCLAW_BACKUP_BUCKET=your-openclaw-backup-bucket OPENCLAW_AWS_REGION=ap-southeast-1 EOF chown openclaw:openclaw /opt/openclaw/env.conf

有几个细节容易踩坑。第一,不要在用户数据脚本里写入任何长期密钥,比如数据库密码或 API Token。你的 IAM 角色已经解决了云资源访问问题,应用自身的密钥应该在启动后通过 secret 管理工具或手动安全注入。第二,脚本里设置的监听地址是 0.0.0.0,实际对外暴露范围还要靠前面安全组卡位,安全组才是真正的边界。

3.2 把 OpenClaw 作为 systemd 服务跑起来,而不是挂在终端里

不要用 nohup 或直接在当前终端里启动 OpenClaw。一旦你的 SSH 会话断开,进程就可能收到挂断信号退出。正确的做法是交给 systemd 管理,让它负责开机自启、崩溃拉起和标准输出去向。

在/etc/systemd/system/openclaw.service写入:

[Unit] Description=OpenClaw Service After=network-online.target Wants=network-online.target [Service] Type=simple User=openclaw Group=openclaw EnvironmentFile=/opt/openclaw/env.conf ExecStart=/opt/openclaw/bin/openclaw serve Restart=always RestartSec=5 ExecReload=/bin/kill -HUP $MAINPID [Install] WantedBy=multi-user.target

写完后的启用命令是:

systemctl daemon-reload systemctl enable --now openclaw systemctl status openclaw

这里的关键逻辑是 Restart=always。如果 OpenClaw 因为某个任务脚本导致进程崩溃,systemd 会在 5 秒后自动拉起。你可以通过一种方式模拟测试:直接杀掉进程再观察状态,正常情况下它会自动恢复。这一步对后期稳定性非常重要。

为什么不在这套部署里引入容器?因为 OpenClaw 是单一静态二进制,依赖很少,systemd 加环境配置文件已经是可复现方案。容器引擎会引入镜像升级、网络模式、数据卷挂载等额外概念,对只跑一个应用的简化版来说,收益并不明显。当然,这不是说容器方案不好,而是从维护成本角度,它能等以后规模变大了再使用。

3.3 通过 AWS 的弹性 IP 还是内网入口?

如果你的 OpenClaw 对外提供 API,对外入口有两种选择:弹性 IP 或内网 DNS。我建议用弹性 IP + 弹性 IP 绑定的方式,先解决“IP 会变”的问题。

EC2 公网 IP 在实例停止再启动后会更换,如果你把它写进了调用方配置,停一次实例就要改一次配置文件。弹性 IP 能够固定这个地址,绑定到实例上以后,即使重启实例,IP 也不会变。使用时注意,弹性 IP 只在绑定到运行中实例时免费,如果你开了实例但忘了绑定,或绑定的实例处于停止状态,会收取少量费用。

如果你的调用方全部都在同一个 VPC 或专线网络内,那么别使用公网入口,直接用内网 IP 或内网 DNS 更安全。安全组里也不用为 8080 端口放开公网来源,来源可以直接填 VPC 网段。等到需要跨环境调用的场景出现,再考虑公网入口,原则是别把自己的管理服务盲目暴露到公网。

3.4 配置日志轮转和定时备份到 S3

OpenClaw 跑起来之后,第一件不能省的事是日志轮转。默认情况下系统日志会一直增长,几个月后磁盘被占满,服务就可能开始出现各种诡异问题。在/etc/logrotate.d/openclaw写一份配置:

/opt/openclaw/logs/*.log { weekly rotate 4 compress delaycompress missingok notifempty copytruncate }

这份配置的意思是每周切一次日志,保留四份,旧日志压缩保存。copytruncate对 OpenClaw 这种持续写入的进程很关键,它先复制文件内容再清空原文件,不需要重启服务,也不会丢失正在写的日志。

备份走 S3 是所有步骤里性价比最高的一步。在 cron 里放一条任务:

10 2 * * * aws s3 sync /opt/openclaw/data "s3://your-openclaw-backup-bucket/backups/$(date +\\%F)/" --delete

注意脚本里的 IAM 权限和 AWS CLI 配置,如果你用实例角色,机器的 CLI 不需要执行aws configure,SDK 和 CLI 会自动从实例元数据服务获取临时密钥。备份策略有一个容易被忽略的细节:定期备份不等于可以恢复。我习惯每两周手动从备份数据启动一个临时实例,验证备份数据能否真正被读取并恢复,避免某天发现备份文件一直是坏的。

4. 部署验证和日常维护里的高频翻车点

4.1 验证 OpenClaw 真的“活”了:健康检查、日志和测试任务

部署完成后不要急着把地址发给同事。先把健康检查接口摸一下。OpenClaw 通常会提供一个健康检查端点,可以这样验证:

curl -fsS http://127.0.0.1:8080/healthz

如果服务正常,这个命令会返回一个 JSON 或纯文本的状态信息,比如{"status":"ok"}。如果连接失败,先确认进程存在:

systemctl status openclaw journalctl -u openclaw -n 50 --no-pager

journalctl 能看到服务启动时打出的日志。如果服务没有正常启动,多半是环境变量文件没读对、二进制文件没执行权限、或者监听端口被占用。

健康检查通过后,创建一个最小测试任务。OpenClaw 的 API 通常支持提交一个简单命令任务,比如echo hello。提交后观察任务状态和返回结果,确认执行器能正常工作。这里的经验是:测试任务要用真实的业务脚本,而不是永远只跑 echo。把脚本逻辑、日志位置、环境变量都一并验证一遍,才能提前发现权限缺失或路径写死的问题。

4.2 安全组改坏了连不上:一个恢复实例连接的经验

我早期在调整安全组时动手改错过一次,不小心删掉了 SSH 的入站规则,实例直接失联。当时第一反应是惊慌,担心需要销毁重建。实际 AWS 给了足够的恢复余地。

正确的恢复步骤是:打开实例控制台,先停止实例。停止不会影响 EBS 数据卷,只是操作系统会关机;然后在实例详情页进入“网络”或“安全”标签,找到修改安全组的入口,添加回原来的 SSH 规则;重新启动实例后,SSH 就恢复了。

这个过程的要点是:安全组属于实例的网络属性,可以直接修改,不需要进入系统内部。所以即使你把 SSH 规则设置错误,只要还有控制台权限,就能把规则改回来。反过来,如果你发现自己没有控制台权限或 IAM 权限不够,那就真的需要找管理员了。因此在日常操作中,给运维账号保留修改安全组的权限,其实也是应急链路的一部分。

4.3 磁盘耗尽、系统时间偏移和小文件太多,这些“慢刀子”问题

翻车最频繁的不是服务本身,而是一些看似不相关的底层问题。

磁盘耗尽是我遇到最多的情况。OpenClaw 执行任务时会产生很多临时输出,如果不定期清理,日积月累很容易占满根卷。判断方式有两个命令,一个看空间,一个看索引节点:

df -h df -i

df -h显示磁盘剩余空间,df -i显示的是 inode 占用。inode 是什么意思?你可以粗略理解为文件系统里记录每个文件元数据的索引槽位。如果文件数量特别多,即使磁盘空间还有剩余,inode 用完了也会报“No space left on device”。OpenClaw 如果产生大量小文件,很容易触发这个问题。我的建议是临时目录和任务产物目录尽量挂一个定时清理任务。

系统时间偏移是一个隐蔽问题。EC2 默认使用时间同步服务,但有些自定义 AMI 会关闭时间同步,时间一旦漂移,OpenClaw 的任务调度时间会变得不准确。确认办法是查看当前时间,再跟标准时间对比。配置 systemd 的 chrony 服务并设为开机自启,这是几分钟就能解决的事。

5. 简化版跑稳之后再往前走:低成本升级路径

5.1 添加备用节点,让我可以睡个好觉

当单节点跑了一段时间后,你会开始担心“万一实例挂了怎么办”。其实低成本的高可用思路不需要一开始就上负载均衡器,而是可以准备一台备用节点。

备份策略还是沿用前面的 S3 同步,然后在另一台 EC2 上部署一套相同的 OpenClaw 环境。备用节点平时不接收公网请求,只是定时从备份中同步数据。当主力节点出现故障时,你只需要把 DNS 记录切到备用节点的 IP。注意在 DNS 里把 TTL 调低,比如 60 秒,这样切换生效会比较快。

这种方案的优点是不需要引入负载均衡器和共享文件系统,日常成本只有备用节点的付费费用。如果你需要在故障时尽快切换,备用节点不要停止,让它保持运行只是不对外接入流量。

5.2 数据库替换成托管数据库,存储换成 EFS 或 S3

如果团队后续开始使用多个节点,或者需要同时处理大量任务,SQLite 会成为瓶颈。这时候再考虑把 SQLite 替换成 PostgreSQL 之类的数据库。OpenClaw 通常支持通过环境变量直接切换数据库连接,比如:

OPENCLAW_DATABASE_URL=postgresql://openclaw:密码@数据库主机:5432/openclaw

配置变更之后要执行一次数据迁移命令,把 SQLite 里的历史数据导入新数据库。替换数据库这一步建议在维护窗口期进行,提前做一次完整备份,迁移完成后立刻跑一遍关键测试任务。

当多节点需要共享执行产物或配置文件时,可以把数据目录迁移到 EFS。EFS 能让多台实例同时挂载同一个文件系统,避免了每个节点各自一份数据带来的不一致。不过要注意:如果数据库还在简化版单写模式下运行,共享文件加上数据库同时访问的场景,务必先经过测试,不能拍脑袋上线。

5.3 先别急着引入 CloudFront 或 API 网关

很多人一看到“生产环境”,立刻想把 CloudFront、API 网关、WAF 全部加上。我的建议是这个阶段先别动。OpenClaw 本身就是内部任务调度,流量模式是低频 API 加定时任务,并不是高并发网站。直连弹性 IP 在没有流量入口防护的场景下,并不会成为性能瓶颈;相反,每多一层网关,就多一层配置和故障排查的复杂度。

如果你确实有安全方面的需求,比如这个 API 要被外部调用,建议先做两件事:改用 HTTPS,让前端的 ALB 终止 SSL 证书;再通过安全组限制来源 IP。这两件事成本低、效果好,而且不会引入新的服务端组件。等业务规模真的大到需要限流、地域封禁、缓存加速时,再引入网关也完全不迟。

6. 用了一个多月后,我想给同样部署的人说的三句话

第一句:不要因为官方文档架构图复杂,就以为自己的部署不够完整。简化部署也是一种架构选择,只要边界清晰,该有的安全组、IAM、日志轮转、定时备份一项不少,它就是一个可靠的生产方案。

第二句:定时任务最可怕的不是任务失败,而是任务失败后没人知道。我后来给 OpenClaw 配了一个外部监控,每五分钟探测一次健康检查接口,连续失败三次就向团队发通知。这一条比任何技术优化都让人安心。

第三句:备份和恢复演练,永远不要在事故当天第一次做。我吃过一次亏:备份脚本每天都在执行,S3 里的文件看起来也都在,但真正尝试用这些文件恢复时,才发现有一个子目录一直没权限读取。后来我把“从备份恢复”也加进了每月的运维清单,再也没在这种事上踩过第二次。

这套部署路线不是银弹,但如果你也打算在 AWS 上把 OpenClaw 跑起来,而且业务规模暂时不需要多云和集群编排,它至少能帮你避开我走过的那些弯路。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进