基于Terraform与Ansible的OpenClaw AI代理自动化部署实践
1. 项目概述与核心价值最近在折腾一个挺有意思的项目叫 OpenClaw。简单来说它是一个开源的 AI 代理框架你可以把它理解为一个能帮你处理各种任务的“数字助理”。它能接入 Telegram在群里或者私聊里和你对话帮你查资料、写代码、管理日程甚至控制智能家居功能相当强大。但问题来了这玩意儿怎么部署官方文档给了 Docker 跑本地的方案可我想让它 7x24 小时在线还得安全、可控、能方便地更新维护。于是我找到了tardigrde/openclaw-deploy这个仓库。它不是一个简单的部署脚本而是一套完整的基础设施即代码方案专门为在 Hetzner Cloud 的 VPS 上部署 OpenClaw 而设计。核心思路非常清晰用 Terraform 一键创建和配置云服务器用 Ansible 完成所有复杂的应用部署和环境准备最后用 Docker Compose 把 OpenClaw 跑起来。整个过程通过一个Makefile来串联你只需要敲几个make命令从零到一的完整生产环境就搭建好了。这套方案最吸引我的地方在于它的“全栈自动化”和“安全优先”设计。它不仅仅是把应用丢到服务器上而是考虑了从网络防火墙配置、密钥管理、到日常运维备份、升级、监控的完整生命周期。特别是它对 Tailscale VPN 的原生集成让你可以彻底关闭服务器的公网 SSH 端口所有管理操作都在一个加密的私有网络内进行安全性直接拉满。对于像我这样既想享受云服务的便利又对安全性和可控性有要求的开发者来说这简直就是“开箱即用”的完美模板。接下来我会带你一步步拆解这个项目从架构设计、工具选型到每一个实操命令背后的原理和踩过的坑分享我是如何用它搭建起一个稳定、安全且易于维护的 OpenClaw 服务站的。2. 架构深度解析为什么是这套技术栈刚接触这个项目时你可能会被 Terraform、Ansible、Docker Compose 这一连串工具搞得有点懵。别急我们一个个来看理解作者为什么选择它们以及它们是如何协同工作的。2.1 核心工具链选型背后的逻辑Terraform基础设施的蓝图与管家Terraform 在这里扮演的是“云资源编排者”的角色。它的核心价值是声明式和幂等性。你不需要写一堆“先创建服务器再配置防火墙最后绑定IP”的脚本而是用 HCL 语言描述你最终想要的状态“我需要一台 Hetzner CX23 规格的服务器开放 22 端口 SSH并且关联我的公钥”。Terraform 会自己计算如何达到这个状态并且无论你执行多少次terraform apply只要描述文件不变结果都是一样的。这避免了手动操作可能带来的配置漂移也为团队协作和版本控制基础设施配置打下了基础。为什么选 Hetzner Cloud除了性价比高更重要的是它的 API 稳定、文档清晰非常适合自动化。Terraform 的 Hetzner 提供商hetznercloud/hcloud成熟度很高能覆盖我们需要的所有资源服务器、防火墙、SSH 密钥、网络。Ansible系统配置与应用的“手术刀”服务器创建好了但还是个“裸机”。我们需要安装 Docker、配置用户、部署代码、设置环境变量……这些就是 Ansible 的舞台。与 Terraform 管理“外部资源”不同Ansible 专注于管理“系统内部状态”。这个项目里的 Ansible 用法很精髓它只在本地运行通过 SSH 连接到远端服务器执行任务。这意味着你的 Ansible Playbook 和敏感变量如 API 密钥永远不需要上传到服务器或 CI 环境极大降低了密钥泄露的风险。Playbook 被设计成幂等的你可以反复执行make deploy它只会对发生变化的部分进行更新非常安全。Docker Compose应用运行的标准化容器OpenClaw 本身及其依赖如数据库被打包在 Docker 容器里。Docker Compose 则负责定义和运行这些多容器的应用。它的好处是隔离性好、环境一致、一键启停。项目中的docker-compose.yml定义了 OpenClaw 网关服务并将其数据卷~/.openclaw挂载到宿主机方便持久化存储和备份。Make所有操作的统一入口这是提升体验的关键。面对 Terraform、Ansible 一堆命令和参数新手很容易记错。Makefile把这些封装成make init,make plan,make bootstrap等简单直观的命令。它处理了复杂的环境变量传递、命令顺序让你可以专注于“做什么”而不是“怎么做”。2.2 安全架构设计从外到内的层层防御这个项目的安全设计值得单独拿出来说它体现了“纵深防御”的思想云端防火墙第一道防线Terraform 创建的 Hetzner 云防火墙默认只允许你的 IP 访问 SSH22端口。这是阻止随机扫描的第一层。系统防火墙第二道防线Ansible 会在服务器上配置 UFWUncomplicated Firewall进一步收紧策略形成第二层防护。服务隔离第三道防线OpenClaw 网关服务在 Docker 内部仅绑定到127.0.0.1:18789这意味着从公网根本无法直接访问到该服务。Tailscale VPN终极方案这是最妙的一招。通过集成 Tailscale你可以创建一个覆盖所有你设备的加密私有网络tailnet。部署流程可以自动将服务器加入你的 tailnet然后关闭公网 SSH 端口。此后你只能通过 Tailscale 分配的私有 IP 或 MagicDNS如openclaw-prod.your-tailnet.ts.net来 SSH 或访问服务。公网攻击面几乎为零。密钥管理敏感信息如 Hetzner API Token、Tailscale OAuth Secret、OpenClaw 网关令牌等都通过secrets/inputs.sh和secrets/.env管理并被.gitignore排除。还支持使用sops和age进行加密以便安全地存入 Git 仓库实现 GitOps。这种设计确保了即使某个环节出现疏漏攻击者也无法长驱直入。对于部署一个长期运行、可能处理敏感对话的 AI 助手来说这种谨慎是非常必要的。2.3 配置覆盖系统平衡标准化与个性化项目作者明确表示这是“固执己见”的选择了特定的技术栈和默认配置。但为了灵活性它提供了一套优雅的“覆盖文件”系统。层定制内容覆盖文件何时复制Terraform后端状态存储terraform/envs/prod/backend.tfmake init前Terraform服务器规格、区域等terraform/envs/prod/terraform.tfvarsmake plan前Docker额外服务如数据库监控docker-compose.override.ymlmake bootstrap前Make自定义命令Makefile.local任何时候Ansible自定义部署步骤ansible/site.local.yml任何时候重点是这些覆盖文件都是.gitignore的。这意味着你可以 fork 这个仓库作为上游upstream然后在自己的私有分支里安全地存放这些个性化配置和密钥。未来上游更新时你可以轻松地git merge upstream/main而几乎不会产生冲突。这是一种非常专业的 IaC 项目管理模式。3. 从零开始手把手部署实战理论讲完了我们动真格的。假设你已经有 Hetzner Cloud 账户并准备好了 SSH 公钥我们从头走一遍。3.1 前期准备工具安装与环境配置首先确保你的本地开发机Mac/Linux/WSL2上安装了以下工具Terraform: 用于创建云资源。直接从 官网 下载或使用包管理器安装。Ansible: 用于配置服务器。通常pip install ansible或系统包管理器安装即可。age 和 sops: 用于加密解密密钥。这是可选的但如果你想走 GitOps 自动化部署路线则是必须的。brew install age sops(Mac) 或参考 GitHub 发布页安装。jq: 用于 JSON 处理make validate会用到。brew install jq或apt-get install jq。Git: 这个不用说。注意所有工具的版本最好参考项目 README 中的要求。特别是 Terraform不同主版本间语法可能有变。3.2 第一步克隆项目与基础配置# 1. 克隆仓库 git clone https://github.com/tardigrde/openclaw-deploy.git cd openclaw-deploy # 2. 配置基础设施密钥 cp secrets/inputs.example.sh secrets/inputs.sh vim secrets/inputs.sh打开secrets/inputs.sh你需要填写两个核心变量# 从 Hetzner Cloud 控制台生成Project - Security - API Tokens export HCLOUD_TOKEN你的_Hetzner_API_Token # 从 Hetzner Cloud 控制台获取Security - SSH Keys找到你上传的公钥对应的指纹 export TF_VAR_ssh_key_fingerprint你的_SSH_密钥指纹这里有个坑TF_VAR_ssh_key_fingerprint的值不是密钥本身而是指纹。在 Hetzner 控制台 SSH 密钥列表里点击你的密钥在详情页可以找到一串SHA256:开头的字符串或者一串冒号分隔的十六进制数复制那个就行。如果填错后续 Terraform 会报错找不到密钥。# 3. 配置 OpenClaw 应用本身 cp openclaw.example.json openclaw.json vim openclaw.json这个文件决定了你的 AI 助手的行为。至少需要修改gateway.auth.profiles配置 AI 供应商的 API 密钥。默认是 Anthropic Claude。gateway.controlUi.allowedOrigins允许访问网关 UI 的域名。初始部署先保持[localhost, 127.0.0.1]等 Tailscale 配置好后再加。telegram.botToken你的 Telegram Bot Token。需要先去 BotFather 那里创建一个机器人获取。# 4. 配置 Terraform 后端可选高级用法 cp terraform/envs/prod/backend.tf.example terraform/envs/prod/backend.tf # 默认是本地状态文件无需修改。如果是团队协作建议配置远程后端如 GCS。3.3 第二步基础设施部署与服务器创建现在激动人心的部分来了在云端变出一台服务器。# 1. 加载环境变量到当前 shell source secrets/inputs.sh # 2. 初始化 Terraform下载提供商插件 make init # 输出会显示 Terraform 初始化成功。 # 3. 生成执行计划预览将要创建的资源 make plan # 仔细阅读输出它会告诉你将要创建 1 个 Hetzner 服务器、1 个防火墙等。确认无误。 # 4. 执行部署真正创建资源 make apply # Terraform 会再次显示计划并询问是否执行输入 yes。 # 等待几分钟你会看到服务器创建成功并输出服务器的公网 IP 地址。执行现场记录与解析 当你运行make apply并确认后Terraform 会开始调用 Hetzner Cloud API。你会在终端看到类似下面的输出hcloud_server.openclaw: Creating... hcloud_server.openclaw: Still creating... [10s elapsed] hcloud_server.openclaw: Still creating... [20s elapsed] hcloud_server.openclaw: Creation complete after 31s [id12345678] hcloud_firewall.openclaw: Creating... hcloud_firewall.openclaw: Creation complete after 3s [id87654321] hcloud_firewall_attachment.openclaw: Creating... hcloud_firewall_attachment.openclaw: Creation complete after 2s [id12345678-87654321] Apply complete! Resources: 3 added, 0 changed, 0 destroyed. Outputs: server_ip 123.123.123.123这个过程通常需要 30-60 秒。成功后记下输出的server_ip这就是你新服务器的公网 IP。重要提示此时服务器的 SSH 端口22是对全世界开放的。如果你打算稍后再配置 Tailscale建议先执行一个临时限制只允许你的 IP 访问。在secrets/inputs.sh中临时添加export TF_VAR_ssh_allowed_cidrs[你的公网IP/32]然后重新source并运行make apply。这能极大降低从创建到配置完成窗口期的风险。3.4 第三步应用部署与启动服务器有了现在要把 OpenClaw 装上去。# 1. 配置容器运行所需的环境变量密钥 cp secrets/.env.example secrets/.env vim secrets/.env至少需要设置OPENCLAW_GATEWAY_TOKEN: 一个强密码用于访问网关 Web UI。ANTHROPIC_API_KEY: 你的 Claude API 密钥如果你用 Anthropic 模型。如果你用的是 Claude 订阅授权这里可以留空后续用make setup-auth配置。TELEGRAM_BOT_TOKEN: 你的 Telegram Bot Token需要和openclaw.json里的一致。# 2. 可选但推荐加密密钥文件 # 如果你打算把配置推送到 Git 仓库做自动化需要加密 .env 文件 make secrets-generate-key # 这会生成一个 age 密钥对并打印公钥。复制公钥。 # 编辑 .sops.yaml 文件将公钥粘贴到 age: 字段下。 make secrets-encrypt # 这会生成一个加密后的 secrets/.env.enc 文件。之后可以安全地提交这个文件。 # 本地开发时使用未加密的 .env 文件即可。# 3. 执行一键部署 source secrets/inputs.sh # 再次确认环境变量已加载 make bootstrap这个make bootstrap命令是核心它背后做了大量工作Ansible 连接服务器使用前面 Terraform 输出的 IP 和你的 SSH 密钥连接服务器。系统初始化创建openclaw系统用户、安装 Docker 和 Docker Compose、配置 UFW 防火墙默认允许 22 端口。推送配置将本地的openclaw.json和secrets/.env文件上传到服务器的~/.openclaw/目录。构建与启动在服务器上构建 OpenClaw 的 Docker 镜像然后通过docker compose up -d启动所有服务。整个过程会在终端滚动输出 Ansible 的执行日志。耐心等待直到最后出现类似“PLAY RECAP”且没有失败任务failed0的提示。3.5 第四步验证与访问部署是否成功我们来检查一下。# 1. 查看容器状态 make status你应该看到openclaw-gateway容器的状态是running或healthy。# 2. 查看实时日志 make logs滚动日志寻找关键信息[entrypoint] Skill installation complete表示技能加载成功Gateway listening on http://127.0.0.1:18789表示网关服务已启动。如果有错误比如 API 密钥无效也会在这里显示。# 3. 建立 SSH 隧道将本地端口映射到服务器的服务端口 make tunnel # 这个命令会挂起保持隧道打开。它会输出类似Forwarding from 127.0.0.1:18789 - 127.0.0.1:18789现在打开你的浏览器访问http://localhost:18789。你应该会看到 OpenClaw 的网关登录界面。输入你在secrets/.env中设置的OPENCLAW_GATEWAY_TOKEN。成功标志令牌被接受进入网关管理界面你可以看到已连接的 Telegram Bot 和配置的技能。到这一步一个基础的、通过公网 SSH 管理的 OpenClaw 服务就部署成功了。4. 进阶配置集成 Tailscale 实现零信任网络基础部署虽然能用但 SSH 暴露在公网始终是个风险。下面我们启用 Tailscale打造一个更安全的私有访问环境。4.1 Tailscale 原理与优势Tailscale 基于 WireGuard但它解决了 WireGuard 配置复杂的痛点。你只需要在所有设备上登录同一个 Tailscale 账户它们就会自动组成一个加密的 mesh 网络每个设备都会获得一个固定的私有 IP100.x.x.x并且可以通过 MagicDNS 直接用主机名访问。在这个项目中集成 Tailscale 的好处关闭公网 SSH服务器 SSH 只监听 Tailscale 网络接口互联网上的扫描器根本看不到 22 端口。安全访问 Web UI可以通过 Tailscale 的 HTTPS URL 直接访问 OpenClaw 网关无需 SSH 隧道。跨网络访问无论你是在公司、在家还是用手机流量只要设备在 tailnet 内访问体验都一样。简化配置不需要记住服务器 IP直接用openclaw-prod.your-tailnet.ts.net这样的域名访问。4.2 详细配置步骤前提你需要一个 Tailscale 账户免费版足够个人使用。创建 Tailscale OAuth 客户端 登录 Tailscale 管理后台 点击 “Create OAuth client”。名称随意如 “OpenClaw Terraform”。重定向 URI填写http://localhost:8080/callback这是一个本地回调 URITerraform provider 会用到。权限范围务必勾选auth_keys:write创建预认证密钥、settings:write修改设备设置、dns:write配置 DNS。如果想用 Terraform 管理 ACL还需勾选acls:write。 创建后保存好Client ID和Client Secret。更新本地配置 编辑secrets/inputs.sh添加以下三行export TF_VAR_enable_tailscaletrue export TF_VAR_tailscale_oauth_client_idtskey-client-xxxxxxxxx export TF_VAR_tailscale_oauth_client_secrettskey-secret-xxxxxxxxx更新基础设施source secrets/inputs.sh make apply这次make apply会为你的 Tailscale 网络生成一个“预认证密钥”Auth Key并存储在 Terraform 的状态文件里。这个密钥用于让服务器自动加入你的 tailnet而无需你手动操作。重新部署应用关键步骤make bootstrap这个命令现在有了新任务它会让 Ansible 在服务器上安装 Tailscale 客户端并使用上一步生成的 Auth Key 自动注册设备。注册成功后你会在 Tailscale 管理后台看到一台名为openclaw-prod的新设备。锁定 SSH仅限 Tailscale 访问make tailscale-enable这个命令非常智能首先它会检查服务器是否已成功通过 Tailscale 连通。如果连通它会自动运行make apply但这次会修改 Terraform 配置将防火墙规则中的ssh_allowed_cidrs设置为空列表[]从而关闭公网的 SSH 访问。如果 Tailscale 连通检查失败命令会中止公网 SSH 保持开放防止你把自己锁在外面。切换连接方式 编辑secrets/inputs.sh将SERVER_IP从公网 IP 改为 Tailscale 的 MagicDNS 主机名。# 注释掉旧的公网 IP使用 MagicDNS # export SERVER_IP123.123.123.123 export SERVER_IPopenclaw-prod然后source secrets/inputs.sh。此后所有的make ssh、make tunnel等命令都会通过 Tailscale 网络连接。配置 OpenClaw 允许 Tailscale 访问 编辑openclaw.json在gateway.controlUi.allowedOrigins数组中添加你的 Tailscale HTTPS URL。你可以在 Tailscale 管理后台找到它格式是https://设备名.tailnet名.ts.net。{ gateway: { auth: { allowTailscale: true }, controlUi: { allowedOrigins: [ localhost, 127.0.0.1, https://openclaw-prod.your-tailnet-name.ts.net ] }, trustedProxies: [172.20.0.0/24] } }allowTailscale: true允许通过 Tailscale 身份头进行认证这样访问 Web UI 可能就不需要手动输入令牌了取决于浏览器插件。trustedProxies必须设置。因为当通过 Tailscale Serve反向代理访问时真实客户端 IP 是通过X-Forwarded-For头传递的。这个 CIDR 需要匹配 Docker Compose 网络的子网默认是172.20.0.0/24网关才能正确识别 Tailscale 的头部信息。保存后运行make deploy推送新配置。完成现在你可以直接通过浏览器访问https://openclaw-prod.your-tailnet-name.ts.net来打开 OpenClaw 网关并且服务器的 22 端口在公网已不可见。你的整个管理平面都转移到了加密的 Tailscale 私有网络内。5. 日常运维、问题排查与经验心得部署完成只是开始长期稳定运行更重要。这部分分享一些日常操作和踩过的坑。5.1 常用 Make 命令速查项目把几乎所有操作都封装成了make命令这里列几个最常用的命令作用使用场景make status检查容器、Tailscale 状态日常健康检查make logs查看容器实时日志调试服务启动失败、查看 AI 调用记录make deploy推送配置变更并重启服务修改openclaw.json或.env后make deploy REBUILD1重建镜像并部署升级 OpenClaw 版本后make sshSSH 登录到服务器需要执行高级调试命令时make backup-now立即触发一次备份重大变更前make backup-pull下载最新备份到本地本地存档或用于恢复测试5.2 常见问题与解决方案实录问题一make bootstrap或make deploy失败Ansible 报错 “Permission denied (publickey).”原因SSH 认证失败。排查确认secrets/inputs.sh中的TF_VAR_ssh_key_fingerprint是否正确对应了已上传到 Hetzner 的公钥。确认本机~/.ssh/id_rsa或SSH_KEY环境变量指定的路径存在对应的私钥且权限是600。如果刚配置了 Tailscale 并切换了SERVER_IP确认make tailscale-status显示连接是活跃的。解决修正密钥指纹或路径重新source secrets/inputs.sh并重试。问题二容器不断重启make logs显示OPENCLAW_GATEWAY_TOKEN environment variable is required原因secrets/.env文件中的OPENCLAW_GATEWAY_TOKEN变量没有正确传递到容器内或者文件本身没有上传到服务器。排查登录服务器make ssh然后cat ~/.openclaw/.env检查变量是否存在。在服务器上运行docker compose -f ~/openclaw/docker-compose.yml config查看最终渲染出的环境变量。解决确保本地secrets/.env文件已正确配置然后重新运行make deploy。如果使用了 SOPS 加密确保服务器上有对应的 age 私钥能解密.env.enc文件。问题三通过 Tailscale URL 访问网关一直显示 “Unauthorized” 或空白页原因allowedOrigins或trustedProxies配置不正确。排查检查openclaw.json中allowedOrigins数组是否包含了完整的 Tailscale HTTPS URL注意是https://开头。检查trustedProxies是否设置为[172.20.0.0/24]。可以通过make ssh然后docker network inspect openclaw_default来确认 Docker 网络的子网。查看网关日志make logs看是否有关于来源不被允许的错误。解决修正openclaw.json配置运行make deploy。如果还不行尝试暂时在浏览器中直接输入网关令牌或者通过make tunnel的 SSH 隧道访问localhost:18789来排除网络问题。问题四想升级 OpenClaw 到新版本步骤务必先备份make backup-now。编辑docker/Dockerfile找到FROM openclaw/openclaw-gateway:xxxxx这一行将标签修改为目标版本号如2026.3.24。执行make deploy REBUILD1。REBUILD1会强制重建 Docker 镜像。观察make logs输出确认新版本启动无误。心得在升级前最好去 OpenClaw 的 GitHub Release 页面查看更新日志确认是否有破坏性变更需要同步调整openclaw.json的配置。问题五服务器磁盘空间不足原因Docker 镜像、日志或 OpenClaw 的会话数据积累。解决make ssh登录服务器。清理无用的 Docker 资源docker system prune -a -f谨慎使用会删除所有未使用的镜像、容器、网络。查看~/.openclaw目录大小如果过大可以考虑在openclaw.json中配置日志轮转或清理旧会话数据需参考 OpenClaw 文档。最根本的可以在terraform/envs/prod/terraform.tfvars中修改disk_size参数默认 40GB然后make apply。注意扩大磁盘需要服务器重启。5.3 备份与恢复给你的 AI 助手上保险OpenClaw 的会话、技能配置等都存储在服务器的~/.openclaw目录下。项目内置了备份机制。手动触发备份make backup-now。这会在服务器上创建一个带时间戳的.tar.gz压缩包存放在~/backups/目录下。下载备份到本地make backup-pull。这会将最新的备份文件拉取到本地的backups/目录。查看可恢复的备份make restore。这会列出服务器上所有的备份文件。执行恢复make restore EXECUTE1 BACKUP文件名。恢复操作会停止当前服务覆盖现有数据务必谨慎最好先在测试环境演练。我的备份策略在Makefile.local中创建一个 cron 任务每周自动运行make backup-now。重要配置变更如升级前手动触发一次备份。定期使用make backup-pull将备份下载到本地或另一个云存储实现异地容灾。5.4 关于成本与优化服务器成本默认的 Hetzner CX232vCPU4GB RAM每月约 5 欧元。对于个人或小团队使用 OpenClaw 完全足够。如果觉得性能有余量可以降级到 CX211vCPU2GB RAM。监控服务器资源使用情况make ssh后htop按需调整。API 成本这是主要成本取决于你使用 AI 模型的频率和类型。Anthropic Claude 或 OpenAI GPT-4 的 API 调用费用需要自行在对应平台监控。建议在 OpenClaw 网关的配置中设置使用限制或切换到更经济的模型如 Claude Haiku进行日常对话。状态存储成本如果使用 Terraform 远程后端如 GCS会产生少量的存储和读写 API 调用费用几乎可以忽略不计。部署完成后整个系统几乎不需要人工干预。它通过 IaC 实现了基础设施的版本化通过 Ansible 和 Docker 实现了应用部署的一致性通过 Tailscale 和防火墙实现了安全加固。你可以放心地让你的 AI 助手持续运行专注于用它来提升效率而不是操心运维问题。这套组合拳对于任何想在云上部署类似复杂应用的个人开发者来说都是一个极具参考价值的范本。