从本地到云:一个 OpenClaw 玩家的迁移踩坑实录
我在 Mac 上跑了两周龙虾(OpenClaw 🦞),合盖断了 3 次之后决定搬到云上。 头一次断是周五下班,合上 MacBook 就走了——周末两天 Slack 消息没人回、RSS 抓取全停了、cron 任务挂了一地。第二次是出门开会,4G 热点一断龙虾直接掉线。第三次更离谱:macOS 系统更新自动重启,我回来一看 三次之后我不想再赌了。合盖断线这事在本地部署是个无解的结构性问题——你不可能要求笔记本永远开着不动。 刚好第 1 篇讲过 Lightsail 一键部署、第 3 篇讲过龙虾自动开 EC2——云端实例不存在"合盖"这个概念,启动之后就一直跑着。搬家本身不难,但坑全藏在迁移过程里。 这篇文章记录我从本地 Mac 迁到亚马逊云科技 EC2 实例的完整过程,包括迁移清单、实际命令、4 个踩过的坑和解法,以及搬完之后的真实体感对比。如果你也受够了笔记本合盖断线,这篇能帮你少走弯路。 先搞清楚龙虾的"家当"有哪些。在本地 Mac 上跑一下 一共 5 类东西需要考虑: 其中 云端实例我已经按第 1 篇的方案 B 开好了——一台 看看包有多大: 跑了两周,4MB 多——主要是 session 历史。 输出: 别直接启动——配置文件还是本地版本的,直接跑会炸。改什么见下面的坑 1。 这是我踩的头号坑。本地 Mac 上用的是 Anthropic 官方 API Key,配置长这样: 搬到 EC2 后要换成 Bedrock + IAM,不需要任何密钥(第 1 篇详细讲过原理): 用 三行改动,API Key 直接删掉。EC2 实例通过 IAM 角色自动获取临时凭证,不需要配置文件里写任何密钥。 验证方法: 看到 把 检查 session 文件: 问题在 修复:批量替换路径 验证: 重启 gateway,龙虾恢复记忆——之前的对话上下文全回来了。 踩坑教训:迁移完启动前,养成习惯先 本地 Mac 时区是 搬到 EC2 后没改,结果——凌晨 1 点(UTC 9:00 = 北京时间 17:00?不对,UTC 9:00 = 北京 17:00)。 等等,我之前设的是"本地 9:00",本地是 UTC+8,所以实际是 UTC 1:00。到了 EC2 上系统时区是 UTC,cron 读的是 UTC 时间, 总之时间全乱了。 解法:统一用 UTC 思维 转换速查表(北京时间 → UTC cron 表达式): 或者直接让龙虾帮你算——在 Slack 里跟它说"帮我把所有 cron 任务从北京时间转成 UTC",它会自动改 Slack 和 Telegram 的 bot token 是跟着 bot 走的,不绑定特定 IP 或机器。所以 token 搬过去理论上直接能用——但 webhook URL 是绑 IP 的,换了机器就得更新。 如果你用的是 Socket Mode(推荐),连接方式是 outbound websocket,不需要 webhook URL,token 搬过去就能用: 启动后确认连接: Telegram bot 默认用 webhook,URL 绑定了旧机器的地址。搬到新 IP 后需要更新: 如果嫌每次换 IP 都要改 webhook,可以改用 long polling 模式——在 跑了一周之后回头看,差距一目了然: 体感上变化很大的一点:以前用龙虾像用一个"桌面软件",打开才有,关了就没了。搬到云上之后它变成了一个"一直在线的同事"——你不需要主动想着去用它,它自己会在后台帮你抓新闻、处理消息、跑定时任务。 那三次合盖断线的日子一去不复返了。 如果你现在还在本地跑龙虾,而且只是偶尔用用,本地完全够了——不需要为了"上云"而上云。 但如果你已经开始依赖它(配了 cron 任务、接了 Slack 渠道、让它帮你监控 RSS),那迁移到云上是早晚的事。与其等下次合盖断线的时候着急,不如现在花 40 分钟搬完。 从这个系列五篇文章走下来,一只龙虾从"试试看"变成了"离不开":第 1 篇解决了部署和安全问题,第 2 篇打通了苹果生态,第 3 篇实现了全自动扩展,第 4 篇探索了多模型协作,这第 5 篇解决了"搬家"的临门一脚。 五篇看完,你手上应该已经有一只跑在云端、24/7 在线、零密钥、能自己干活的龙虾了。剩下的事——就交给它吧。 怕你上面看散了,这里把所有命令串一遍: 搬家本身不难——4 条命令传文件,改 3 处配置——难的是那几个不看日志根本发现不了的坑。踩完之后回头看,早搬早省心。 📖 系列回顾: 🔗 延伸阅读:《把 AI Agent 部署到云端,是值得做的事》 — 亚马逊云科技官方博客 OpenClaw 是开源项目,欢迎参与社区贡献。本系列所有代码和配置均在 GitHub 上公开。从本地到云:一个 OpenClaw 玩家的迁移踩坑实录
本文是「OpenClaw 云上实战指南」系列第 5 篇(完结篇)
openclaw gateway 进程没了,session 文件还锁着。搬什么?迁移清单
tree,看看 ~/.openclaw 目录结构:~/.openclaw/
├── openclaw.json # 核心配置(模型、渠道、心跳)
├── workspace/ # 工作区(SOUL.md、skills/、memory/ 等)
│ ├── SOUL.md
│ ├── USER.md
│ ├── MEMORY.md
│ ├── memory/
│ │ ├── 2026-02-25.md
│ │ ├── 2026-02-26.md
│ │ └── ...
│ ├── skills/
│ │ ├── content-watcher/
│ │ └── rss-ai-reader/
│ └── articles/
├── sessions/ # 聊天历史
├── .secrets/ # 本地密钥(迁移后用 IAM 替代)
└── crontab.json # 定时任务文件/目录 重要程度 说明 openclaw.json必须搬 核心配置,但到云上要改(见坑 1) workspace/必须搬 龙虾的"灵魂"——人格、记忆、技能全在这里 sessions/建议搬 聊天历史,丢了不影响功能但龙虾会"失忆" .secrets/不要搬 本地密钥文件,到了云上用 IAM 角色替代,更安全 crontab.json必须搬 定时任务配置,但时区需要调整(见坑 3) workspace/ 是重中之重。里面的 SOUL.md 定义了龙虾的性格,memory/ 存着它的日常记忆,skills/ 是你装的各种能力插件。这些丢了龙虾就不是"你的龙虾"了——它虽然还能跑,但会变成一只陌生的新龙虾。动手搬家:4 条命令
t4g.medium ARM 实例,挂了 IAM 角色,Bedrock 权限就位。1. 打包本地文件
# 本地 Mac 上执行
cd ~/.openclaw
tar czf ~/openclaw-backup.tar.gz \
openclaw.json \
workspace/ \
sessions/ \
crontab.json$ ls -lh ~/openclaw-backup.tar.gz
-rw-r--r-- 1 bill staff 4.2M 3 8 14:32 openclaw-backup.tar.gz2. 传到云端
# rsync 增量传输,比 scp 断点续传更靠谱
rsync -avzP ~/openclaw-backup.tar.gz \
ubuntu@<EC2-IP>:~/sending incremental file list
openclaw-backup.tar.gz
4,398,080 100% 12.35MB/s 0:00:00 (xfr#1, to-chk=0/1)3. 云端解压
# SSH 到 EC2
ssh ubuntu@<EC2-IP>
# 解压到 ~/.openclaw
mkdir -p ~/.openclaw
cd ~/.openclaw
tar xzf ~/openclaw-backup.tar.gz4. 启动前先改配置
坑 1:API Key → IAM 角色——配置文件要改
// 本地版 openclaw.json
{
"llm": {
"provider": "anthropic",
"model": "claude-sonnet-4-20250514",
"apiKey": "sk-ant-api03-xxxxxxxxxxxxx"
}
}// 云端版 openclaw.json
{
"llm": {
"provider": "amazon-bedrock",
"model": "anthropic.claude-sonnet-4-20250514",
"region": "us-east-1"
}
}diff 看一下改了什么: {
"llm": {
- "provider": "anthropic",
- "model": "claude-sonnet-4-20250514",
- "apiKey": "sk-ant-api03-xxxxxxxxxxxxx"
+ "provider": "amazon-bedrock",
+ "model": "anthropic.claude-sonnet-4-20250514",
+ "region": "us-east-1"
}
}# 确认 IAM 角色已绑定
$ curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/
OpenClawBedrockRole
# 确认 Bedrock 可调用
$ aws bedrock-runtime invoke-model \
--model-id anthropic.claude-sonnet-4-20250514 \
--region us-east-1 \
--body '{"anthropic_version":"bedrock-2023-05-31","max_tokens":10,"messages":[{"role":"user","content":"ping"}]}' \
/dev/stdout 2>/dev/null | jq -r '.content[0].text'
Pong!Pong! 就说明模型调用链路通了。整个过程不需要管密钥轮换、不需要担心 Key 泄露——IAM 角色的临时凭证由亚马逊云科技自动管理,每小时刷新一次。💡 如果之前本地用的是其他模型(比如 OpenAI),Bedrock 上也有 Claude、Nova、DeepSeek 等多种选择,改
model 字段就行。第 4 篇会详细讲 Nova 模型的切换实战。具体支持列表见 Bedrock 模型页面。坑 2:Session 历史路径变了——龙虾"失忆"
sessions/ 目录搬过去之后,启动龙虾,发现它完全不记得之前的对话。$ ls sessions/
main.json slack-C07XXXXXX.json telegram-123456789.json
$ head -5 sessions/main.json
{
"id": "main",
"createdAt": "2026-02-22T06:30:00.000Z",
"homedir": "/Users/bill/.openclaw",
"messages": [homedir 字段——还指向 /Users/bill/.openclaw(macOS 路径),但云端是 /home/ubuntu/.openclaw。OpenClaw 用这个路径解析 workspace 里的相对引用。# 一行搞定
cd ~/.openclaw/sessions
sed -i 's|/Users/bill/.openclaw|/home/ubuntu/.openclaw|g' *.json$ grep homedir main.json
"homedir": "/home/ubuntu/.openclaw",$ openclaw gateway restart
Gateway restarted. Sessions loaded: 3grep 一遍旧路径,确认没有残留:$ grep -r '/Users/' ~/.openclaw/sessions/ | wc -l
0 # 确认没有残留的 macOS 路径⚠️ 如果你的 session 文件特别大(几十 MB),也可以选择不迁移——龙虾会从
MEMORY.md 和 memory/ 目录重建上下文。丢的是逐条对话记录,不是"人格"。人格在 SOUL.md,记忆在 memory/,这些都在 workspace 里。坑 3:定时任务时区差 8 小时——凌晨 3 点推送日报
Asia/Shanghai(UTC+8),我设了一个每天早上 9 点抓 RSS 并推送摘要的 cron:// crontab.json(本地版)
{
"jobs": [
{
"name": "daily-rss-digest",
"schedule": "0 9 * * *",
"task": "抓取 RSS 订阅,生成今日摘要,推送到 Slack"
}
]
}0 9 * * * 就变成了 UTC 9:00 = 北京 17:00。// crontab.json(云端版,UTC 时间)
{
"jobs": [
{
"name": "daily-rss-digest",
"schedule": "0 1 * * *",
"task": "抓取 RSS 订阅,生成今日摘要,推送到 Slack"
}
]
}0 1 * * * = UTC 01:00 = 北京时间 09:00。搬家时脑子里要装一个公式:北京时间减 8 小时 = UTC 时间。你想要的北京时间 cron 里写的 UTC 08:00 0 0 * 09:00 0 1 * 12:00 0 4 * 18:00 0 10 * 22:00 0 14 * crontab.json 里的时间字段。毕竟这种机械换算的活交给 AI 来做正合适。💡 你也可以在 EC2 上改系统时区(
timedatectl set-timezone Asia/Shanghai),但不建议——云上统一用 UTC 是业界惯例,避免和 CloudWatch、CloudTrail 等服务的日志时间对不上。日志排查的时候时区不统一会让人抓狂。坑 4:渠道重连——Token 能用但 Webhook 要换
Slack(Socket Mode)
// openclaw.json — Slack 配置,直接搬
{
"channels": {
"slack": {
"enabled": true,
"appToken": "xapp-1-A07XXXXXX-...",
"botToken": "xoxb-..."
}
}
}$ openclaw gateway start
...
[Slack] Connected via Socket Mode ✓
[Slack] Listening on 2 channelsTelegram(Webhook Mode)
# 更新 webhook 到新 IP
curl -s "https://api.telegram.org/bot<TOKEN>/setWebhook?url=https://<NEW-EC2-IP>:8443/telegram/webhook"
# 验证
curl -s "https://api.telegram.org/bot<TOKEN>/getWebhookInfo" | jq '.result.url'
"https://<NEW-EC2-IP>:8443/telegram/webhook"openclaw.json 里把 webhook 去掉,龙虾会自动降级到 polling:{
"channels": {
"telegram": {
"enabled": true,
"botToken": "7000000000:AAxxxxxx"
// 不配 webhook,自动用 long polling
}
}
}💡 第 2 篇里的 iMessage 渠道比较特殊——它依赖 macOS 系统,如果你从 Mac 迁到 Linux,iMessage 渠道需要单独保留在 Mac 实例上。可以参考第 2 篇的 Mac 云实例方案。
搬家前后对比
维度 本地 Mac EC2 云端 在线时长 取决于开机时间,平均每天不到 12 小时 7×24 不间断运行 断线次数(一周) 3 次(合盖、断网、重启) 0 次 API 密钥管理 明文写在配置文件里 IAM 角色自动管理,零密钥 cron 定时任务 合盖就停,醒来不一定恢复 准时执行,从未漏过 Slack 消息响应 人在电脑前才有反应 凌晨 3 点消息也能秒回 RSS 抓取推送 出差那几天漏了 3 天内容 每天定点推送,一天不落 安全审计 无,全靠自觉 CloudTrail 记录每次 API 调用 迁移耗时 — 约 40 分钟(含踩坑排查时间) 写给还在犹豫的人
完整迁移命令速查
# ===== 本地 Mac =====
# 1. 打包
cd ~/.openclaw
tar czf ~/openclaw-backup.tar.gz \
openclaw.json workspace/ sessions/ crontab.json
# 2. 传到云端
rsync -avzP ~/openclaw-backup.tar.gz ubuntu@<EC2-IP>:~/
# ===== 云端 EC2 =====
# 3. 解压
mkdir -p ~/.openclaw && cd ~/.openclaw
tar xzf ~/openclaw-backup.tar.gz
# 4. 改配置:API Key → Bedrock
# 编辑 openclaw.json,provider 改 amazon-bedrock,删掉 apiKey
# 5. 修 session 路径
cd sessions/
sed -i 's|/Users/<你的用户名>/.openclaw|/home/ubuntu/.openclaw|g' *.json
# 6. 改 cron 时区(UTC+8 → UTC,减 8 小时)
# 编辑 crontab.json
# 7. 更新 Telegram webhook(如果用了的话)
curl -s "https://api.telegram.org/bot<TOKEN>/setWebhook?url=https://<EC2-IP>:8443/telegram/webhook"
# 8. 启动!
openclaw gateway start一句话总结