1. 项目概述:在Azure上部署你的专属AI助手
如果你和我一样,对把个人数据交给第三方AI服务商总有些顾虑,同时又希望拥有一个能帮你处理真实任务——比如浏览网页、执行命令、管理文件——的智能助手,那么自己动手搭建一个私有化的AI助理系统,可能就是你一直在找的解决方案。今天要聊的这个项目,openclaw-azure,就是一个能让你在30分钟内,在微软Azure云平台上,从零部署一个功能完整、安全加固的OpenClaw AI助手的“一站式”工具包。它最大的魅力在于,整个部署过程完全自动化,你不需要在Azure门户里手动点击任何一个按钮,所有基础设施的创建、虚拟机的安全加固、以及OpenClaw应用的配置,都由几个脚本替你完成。
简单来说,OpenClaw是一个开源的、能连接到Telegram、WhatsApp、Discord等即时通讯软件的个人AI助手。它不只是个聊天机器人,而是一个能真正“做事”的代理。你可以通过自然语言命令它去网上搜索信息,在你的服务器上运行特定的Shell命令,或者管理文件系统。而这个GitHub仓库,则为你提供了将OpenClaw部署到Azure所需的一切:用Bicep(Azure原生的基础设施即代码语言)编写的资源模板,以及一系列封装好的Bash脚本。
整个架构的核心设计非常清晰:你在Azure上获得一台虚拟机(VM),OpenClaw以Docker容器的方式运行在这台VM上。最关键的是,OpenClaw的网关服务(Gateway)绝不对外暴露。它只监听VM内部的端口(18789)。你要想通过浏览器访问它的控制面板,或者让AI助手正常工作,必须通过一条加密的SSH隧道来连接。这意味着,所有的认证信息和对话数据,都不会在公网上裸奔。AI模型调用则指向你自己的Azure OpenAI或Azure AI Foundry服务,确保了你的对话数据始终在你的控制范围内,不会流向任何未经你授权的第三方。
成本方面,项目选择了性价比很高的Standard_B2als_v2虚拟机规格,大约每月22到27美元(持续运行)。如果不用的时候把VM关机(停止计费),只保留磁盘和公网IP,每月成本能降到5美元左右。对于个人使用或小团队实验来说,这个投入是相当可控的。
接下来,我会带你完整走一遍部署流程,并分享我在实际操作中踩过的坑和总结出的技巧。无论你是想快速拥有一个私有AI助手,还是想借此学习Azure Bicep、Linux安全加固和Docker部署,这篇文章都能给你提供一份可靠的“抄作业”指南。
2. 部署前的核心准备与环境检查
在运行那个神奇的deploy.sh脚本之前,我们需要把“柴火”准备好。这个阶段看似繁琐,但每一步都关系到后续部署能否一次成功。我会详细解释每个前提条件的意义,并给出更稳妥的检查方法。
2.1 Azure CLI:与云平台对话的命令行工具
Azure CLI是你本地机器与Azure云交互的桥梁。所有自动化脚本的背后,其实都是它在执行az命令。安装后,第一件事不是急着登录,而是检查版本并确保配置正确。
# 检查是否已安装及版本 az --version如果未安装,请根据你的操作系统(Windows/macOS/Linux)前往微软官方文档安装。安装后,我建议先运行一下az upgrade来确保CLI工具本身是最新的,这能避免一些因版本过旧导致的奇怪错误。
2.2 Azure订阅与多租户登录
这是最容易出问题的一步,尤其是对于在企业账户下有多个订阅或租户的用户。
# 基础设备代码登录 az login --use-device-code执行后,命令行会给出一个网址和一个代码。用浏览器打开那个网址(通常是https://microsoft.com/devicelogin),输入代码,然后完成登录。这个过程比直接输入密码更安全。
关键技巧:确认当前订阅登录成功后,强烈建议立刻运行
az account show,查看当前激活的是哪个订阅。因为一个微软账户可能关联多个Azure订阅(例如公司的、个人的、免费试用的)。自动化脚本会在你当前激活的订阅下创建资源。如果选错了订阅,资源会被创建到你不期望的地方,甚至产生计划外的费用。 如果需要切换订阅,使用az account list --output table列出所有订阅,然后用az account set --subscription “你的订阅名称或ID”来切换。
如果你的账户属于多个Azure Active Directory租户(常见于企业环境),必须在登录时指定正确的租户ID,否则会因权限不足而失败。
# 指定租户登录 az login --tenant <your-tenant-id> --use-device-code如何找到租户ID?最简单的方法是登录 Azure门户 ,进入“Azure Active Directory”服务,在“概述”页面就能看到“租户ID”。
2.3 SSH密钥对:无密码安全访问的基石
项目强制使用SSH密钥认证,彻底禁用密码登录,这是服务器安全的第一道防线。检查你本地是否已有可用的密钥:
# 查看 ~/.ssh 目录下是否有 .pub 结尾的公钥文件 ls -la ~/.ssh/*.pub如果已有(常见的是id_rsa.pub或id_ed25519.pub),你可以直接使用它。如果没有,或者你想为这个项目专门生成一对新密钥(推荐,便于管理),使用以下命令:
# 使用更安全、更快的 Ed25519 算法生成密钥对 ssh-keygen -t ed25519 -C “openclaw-azure-deployment”-t ed25519: 指定密钥类型。Ed25519比传统的RSA更安全、生成更快、密钥更短。-C “comment”: 添加一个注释,通常用邮箱或用途标识,这里用于标记这个密钥的用途。- 执行后,它会询问密钥保存路径,直接回车使用默认路径(
~/.ssh/id_ed25519)。 - 接着询问“passphrase”(密码短语),这里我强烈建议设置一个。这为你的私钥又加了一层密码保护,即使私钥文件不慎泄露,没有密码短语也无法使用。当然,如果图省事,也可以直接回车留空。
生成后,查看你的公钥内容,稍后需要把它填到配置文件中:
# 如果你刚生成了Ed25519密钥 cat ~/.ssh/id_ed25519.pub # 或者如果你使用已有的RSA密钥 cat ~/.ssh/id_rsa.pub你会看到一串以ssh-ed25519 AAAAC3...或ssh-rsa AAAAB3...开头的长文本,复制整个这一行。
2.4 获取你的公网IP地址
为了极致安全,部署脚本会在Azure的网络安全组(NSG)中创建一条规则,只允许从你当前机器的公网IP地址通过SSH(22端口)访问虚拟机。这就像给你的云服务器大门加了一把只有你家钥匙能开的锁。
# 获取你的IPv4公网地址 curl -4 ifconfig.me运行后,你会得到一个类似12.34.56.78的IP地址。注意:对于大多数家庭宽带或公司网络,这个IP是动态的,可能会变化。如果未来某天你发现连不上VM了,首先就应该检查IP是否变了。
你需要在这个IP后面加上/32,形成CIDR表示法,例如12.34.56.78/32。/32意味着“仅限这一个确切的IP地址”。把这个值记下来。
2.5 配置Azure AI服务:模型与终结点
这是OpenClaw的“大脑”所在。你需要一个已部署了模型(如GPT-4o)的Azure OpenAI服务或Azure AI Foundry资源。
- 登录Azure门户,找到你的AI资源。
- 在资源的左侧菜单中,点击“密钥和终结点”。
- 在这里,你需要复制两个关键信息:
- 密钥:任选
Key 1或Key 2。 - 终结点:复制“终结点”栏里的完整URL。这里有个巨坑:原始文档的
.env示例里要求的是AZURE_API_BASE,但Azure门户给的URL可能不包含/openai/v1这个路径。你需要手动确保你使用的URL以/openai/v1结尾。例如,如果门户给出的是https://my-ai-resource.openai.azure.com/,那么你需要使用的AZURE_API_BASE应该是https://my-ai-resource.openai.azure.com/openai/v1。很多“404 Resource not found”错误都源于此。
- 密钥:任选
- 记录部署名称:在Azure门户中,进入你的AI资源下的“模型部署”部分,找到你计划使用的模型部署(例如你创建的一个名为
my-gpt4o的GPT-4o部署),并准确记下它的名字。这个“部署名称”和模型类型(如gpt-4o)是两回事,必须完全匹配。
2.6 创建Telegram机器人
Telegram是初始配置最简单、最稳定的消息通道。创建过程完全在Telegram应用内完成:
- 在Telegram中搜索
@BotFather(官方机器人)。 - 发送
/newbot指令。 - 根据提示,为你的机器人设置一个显示名称(例如
My Private Assistant)和一个唯一的用户名(必须以bot结尾,例如my_private_assistant_bot)。 - 创建成功后,BotFather会发给你一个“令牌”(Token),格式如
1234567890:ABCdefGhIJKlmNoPQRsTUVwxyZ。妥善保管这个令牌,它相当于你机器人的密码。任何人拿到它都可以控制你的机器人。
至此,所有前置条件准备完毕。我们可以进入激动人心的部署环节了。
3. 基础设施即代码:使用Bicep一键构建Azure环境
项目的精髓之一,就是用Bicep模板和封装脚本,把原本需要在Azure门户上点点点的繁琐操作,变成一行命令。我们来深入看看这背后发生了什么。
3.1 克隆仓库与脚本授权
首先,把项目代码拿到本地。
git clone https://github.com/Emrullah007/openclaw-azure.git cd openclaw-azure进入目录后,你会看到几个关键的脚本文件(deploy.sh,setup-vm.sh,configure-openclaw.sh,destroy.sh)和一个infra文件夹(里面是Bicep模板)。为了让脚本可执行,需要授权:
chmod +x scripts/*.sh这个操作只需要做一次。
3.2 配置基础设施参数
Bicep模板需要一些动态输入,比如你的SSH公钥和IP地址。项目通过一个parameters.json文件来管理这些参数。
# 复制示例文件作为我们的配置文件 cp infra/parameters.example.json infra/parameters.json然后用文本编辑器打开infra/parameters.json。它的结构很简单:
{ “parameters”: { “sshPublicKey”: { “value”: “这里粘贴你的整个SSH公钥内容” }, “allowedSshSourceIp”: { “value”: “这里粘贴你的公网IP/32” } } }sshPublicKey:粘贴你之前用cat命令看到的整行公钥字符串。allowedSshSourceIp:粘贴你获取到的公网IP并加上/32,例如“12.34.56.78/32”。
重要安全提示:
parameters.json文件已被列入.gitignore,这意味着它不会被意外提交到Git仓库,避免了密钥泄露的风险。请务必不要移动或重命名这个文件,也不要将其内容提交到任何版本控制系统。
3.3 配置应用环境变量
接下来配置OpenClaw运行时需要的环境变量,主要是AI服务和Telegram的凭据。
# 复制环境变量示例文件 cp docker/.env.example docker/.env打开docker/.env文件,填写你的信息:
# 你的Azure AI终结点,务必以 /openai/v1 结尾! AZURE_API_BASE=https://<your-resource-name>.openai.azure.com/openai/v1 # 从Azure门户复制的密钥 AZURE_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # 你在Azure门户中创建的模型部署的确切名称 AZURE_DEPLOYMENT_NAME=my-gpt4o-deployment # 从 @BotFather 获得的Telegram机器人令牌 TELEGRAM_BOT_TOKEN=1234567890:ABCdefGhIJKlmNoPQRsTUVwxyZ # OpenClaw工作空间目录,通常使用默认值即可 OPENCLAW_WORKSPACE_DIR=/home/azureuser/.openclaw/workspace关于AZURE_API_BASE的再次强调:这是错误高发区。Azure AI Foundry的终结点格式可能略有不同,但核心规则是:URL必须指向一个提供OpenAI兼容API的终结点,并且路径必须包含/openai/v1。如果你不确定,一个简单的测试方法是:在浏览器中访问{你的终结点}/openai/v1/models,并附上api-key请求头。如果返回一个JSON模型列表,说明终结点正确;如果返回404,说明路径不对。
3.4 执行部署脚本
万事俱备,运行核心部署命令:
./scripts/deploy.sh这个交互式脚本会引导你完成以下步骤,我强烈建议你理解每一步的选择:
- 选择区域:脚本会列出可用的Azure区域。选择离你地理位置最近的区域,通常能获得更低的网络延迟。默认是“East US”(美国东部),这个区域资源通常最充足。如果你的订阅在某些区域有配额限制,可能需要选择其他区域。
- 输入资源组名称:资源组是Azure中用于逻辑分组和管理相关资源的容器。直接回车会使用默认的
openclaw-rg。如果你想部署多个实例,或者有特定的命名规范,可以修改它。 - 输入虚拟机名称:这将成为你VM的主机名和公共DNS标签的一部分(格式为
{vm-name}.{region}.cloudapp.azure.com)。脚本会检查名称的全局唯一性,如果已被占用,会提示你换一个。 - 输入管理员用户名:这是你通过SSH登录VM时使用的用户名。默认是
azureuser。你可以自定义,但避免使用admin,root,test等常见名称。 - 确认部署:脚本会汇总你的选择,并要求你输入
yes来确认。仔细核对,尤其是区域和VM名称。
确认后,脚本开始工作。它底层调用的是az deployment sub create命令,并传入了我们准备好的Bicep模板和parameters.json。这个过程大约需要3-5分钟,Bicep引擎会在云端按顺序创建以下资源:
- 一个资源组,作为所有资源的容器。
- 一个虚拟网络和一个子网,为VM提供网络隔离。
- 一个公共IP地址,让你的VM拥有一个固定的公网IP。
- 一个网络安全组,并附加到子网,其中包含一条规则:仅允许从你的IP地址(
allowedSshSourceIp)访问TCP 22端口(SSH)。其他所有入站流量默认拒绝。 - 一台Ubuntu 24.04 LTS虚拟机,规格为
Standard_B2als_v2(2 vCPU,4 GiB 内存)。它使用我们提供的SSH公钥进行认证。
部署成功后,你会在终端看到一个漂亮的输出框,里面包含了VM的公网IP、DNS名称以及最重要的SSH连接和隧道命令。这些信息也会被自动保存到项目根目录下一个名为.deployment-info的隐藏文件中,供后续脚本读取。
实操心得:处理VM规格不可用错误偶尔,你选择的区域可能暂时没有
Standard_B2als_v2的库存。deploy.sh脚本内置了错误处理:如果遇到“SKU不可用”的错误,它会捕获这个错误,并友好地提示你选择另一个区域重试。你不需要从头开始,脚本会保留你已输入的其他配置(如资源组名、VM名),只重新询问区域。这是一个非常贴心的设计。
4. 虚拟机安全加固与基础环境配置
VM创建好了,但它还是个“裸机”。setup-vm.sh脚本的任务就是通过SSH连接上去,把它打造成一个安全、稳定、适合生产环境运行Docker应用的系统。
4.1 脚本执行与安全加固详解
运行脚本:
./scripts/setup-vm.sh这个脚本会自动读取上一步保存的.deployment-info文件,获取VM的IP和管理员用户名,然后执行一系列远程命令。我们来看看它具体做了什么:
- SSH连接与初始更新:脚本首先通过SSH连接到VM,并立即执行
sudo apt update && sudo apt upgrade -y。这确保了系统所有软件包都是最新的,修补了已知的安全漏洞。 - 安装Docker(官方源):脚本没有使用 Docker 提供的便捷安装脚本,而是遵循了Ubuntu官方推荐的方式:添加Docker的官方APT仓库、安装GPG密钥、然后安装
docker-ce(社区版)、docker-ce-cli等组件。这种方式更透明、更可控,也便于后续的版本管理和安全审计。 - 配置非root用户使用Docker:安装后,脚本将当前用户(
azureuser)添加到docker用户组中。这样你就不需要每次运行docker命令都加sudo了。这里有个小坑:组权限的变更不会立即在当前已打开的SSH会话中生效。所以脚本执行完后,如果你还在同一个终端里操作,可能还会遇到docker: command not found或权限错误。解决方法很简单:退出SSH重新登录,或者新开一个SSH会话。 - 配置防火墙(UFW):Ubuntu自带的简易防火墙UFW会被启用。默认策略设置为拒绝所有入站连接,然后单独放行SSH端口(22)。这意味着,除了SSH,VM上的其他所有端口(包括未来OpenClaw要用的端口)从外部都无法直接访问,极大地缩小了攻击面。
- 安装并配置fail2ban:这是一个入侵防御工具,它会监控系统日志(如
/var/log/auth.log),如果发现某个IP在短时间内多次尝试SSH登录失败,就会临时将该IP加入防火墙黑名单(默认封禁10分钟)。这能有效抵御针对SSH端口的暴力破解攻击。 - 启用无人值守安全更新:通过安装
unattended-upgrades包并启用相关配置,系统会自动下载并安装重要的安全更新,让你无需手动干预就能保持系统安全。
脚本运行完毕后,会打印一份清晰的安全配置摘要。看到那一排绿色的对勾,你会对这台VM的安全性更有信心。
4.2 手动验证与故障排查
脚本运行顺利固然好,但如果中途网络波动或出现意外错误,我们需要知道如何手动检查和修复。
- 验证Docker安装:SSH登录到VM,运行
docker --version和docker run hello-world。如果成功,说明Docker安装并运行正常。 - 验证UFW状态:运行
sudo ufw status verbose。你应该看到状态是active,并且有一条规则22/tcp ALLOW IN Anywhere。 - 验证fail2ban状态:运行
sudo systemctl status fail2ban。状态应为active (running)。 - 如果Docker命令找不到:正如前面提到的,执行
newgrp docker或者直接退出SSH重新登录即可。
注意事项:关于公网IP变更部署时锁定的SSH IP是你的当前公网IP。如果你从另一个网络(比如从公司换到家里)连接,或者家庭宽带IP被运营商重置了,你会连不上VM。此时,你需要去Azure门户,找到你的VM所在的资源组,进入“网络”部分,找到关联的网络安全组(NSG),修改那条名为
allow-ssh-from-my-ip的入站规则,将源IP地址更新为你新的公网IP(同样要加/32)。这是自托管服务的一个常见维护点。
5. OpenClaw应用部署与核心配置
VM环境就绪后,就该部署主角——OpenClaw了。configure-openclaw.sh脚本会处理所有应用层面的配置。
5.1 执行应用配置脚本
在你的本地机器上运行:
./scripts/configure-openclaw.sh这个脚本同样会读取.deployment-info,然后通过SSH在VM上执行一系列操作:
- 克隆OpenClaw主仓库:脚本会切换到VM上的用户家目录(
/home/azureuser),然后克隆官方的OpenClaw仓库。这确保了你能获取到最新的应用代码。 - 写入AI模型配置:这是关键一步。脚本会在VM上创建
~/.openclaw/openclaw.json文件,并根据你本地docker/.env文件中的AZURE_API_BASE、AZURE_API_KEY和AZURE_DEPLOYMENT_NAME,生成OpenClaw连接Azure AI服务所需的配置。它绕过了OpenClaw内置的、可能不兼容Azure的交互式配置向导,直接写入了正确的配置。 - 复制环境变量文件:将你本地的
docker/.env文件(包含Telegram令牌和工作空间路径)复制到VM上的OpenClaw目录中,供Docker Compose使用。 - 构建并启动Docker容器:在VM的OpenClaw目录下,执行
docker compose up -d。这会根据docker-compose.yml文件拉取或构建OpenClaw的Docker镜像,并以守护进程模式启动容器。第一次运行需要拉取基础镜像和构建,可能需要3-5分钟。 - 输出连接信息:脚本最后会打印出最重要的信息:SSH隧道命令和带令牌的控制面板URL。
5.2 建立SSH隧道与访问控制面板
OpenClaw的设计非常注重安全:它的网关服务(端口18789)只绑定在Docker容器的内部网络和VM的本地回环地址(127.0.0.1)上,没有暴露在VM的公网网卡上。因此,从外部世界无法直接访问http://<vm-ip>:18789。
访问它的唯一方式,是通过SSH本地端口转发,也就是常说的“SSH隧道”。
打开隧道:在一个新的终端窗口,运行脚本输出的那条命令:
ssh -L 18789:localhost:18789 azureuser@<你的VM-IP>-L 18789:localhost:18789:表示“将本地机器的18789端口,通过SSH连接转发到远程VM的localhost:18789端口”。- 执行后,这个终端会保持连接状态,并提供一个VM的Shell。不要关闭这个终端,关闭它会断开隧道。
获取控制面板URL:在上一步建立的SSH连接(隧道终端)里,VM的Shell中,运行:
docker compose -f ~/openclaw/docker-compose.yml run --rm openclaw-cli dashboard --no-open这会输出一个类似
http://localhost:18789/#token=eyJhbGciOiJ...的链接。这个链接包含了一次性认证令牌,是访问控制面板的凭证。在浏览器中打开:复制整个链接,粘贴到你本地电脑的浏览器地址栏中打开。千万不要直接打开
http://localhost:18789,那样会显示“未授权”。批准设备:首次在浏览器中点击“连接”后,OpenClaw会将你的浏览器视为一个新设备,需要管理员批准。回到SSH终端的VM Shell中,运行:
# 列出待批准的设备请求 docker compose -f ~/openclaw/docker-compose.yml run --rm openclaw-cli devices list你会看到一个请求ID。然后批准它:
docker compose -f ~/openclaw/docker-compose.yml run --rm openclaw-cli devices approve <请求ID>批准后,回到浏览器,刷新页面。现在你应该能看到OpenClaw的控制面板了。
5.3 配对Telegram机器人
让AI助手在Telegram上活起来:
- 在Telegram中找到你创建的机器人,向它发送
/start命令。 - 机器人会回复一个配对码(一串字符)。
- 在VM的SSH终端中,运行:
docker compose -f ~/openclaw/docker-compose.yml run --rm openclaw-cli pairing approve telegram <配对码> - 配对成功!现在你可以直接在Telegram里和你的AI助手对话了。你可以尝试问它“你能做什么?”或者让它执行一些简单的任务。
效率技巧:使用 oc 别名
setup-vm.sh脚本已经在VM的~/.bashrc文件中添加了一个别名:alias oc=‘docker compose -f ~/openclaw/docker-compose.yml’。在VM的Shell中,先运行source ~/.bashrc使其生效,之后你就可以用简短的oc命令替代冗长的docker compose命令了。例如:oc logs -f # 查看日志 oc run --rm openclaw-cli devices list # 列出设备这能极大提升操作效率。
6. 日常运维、问题排查与深度优化
部署完成只是开始,稳定运行和高效管理才是关键。这部分分享一些日常操作命令、常见问题的根因分析和解决方法,以及一些性能优化技巧。
6.1 日常操作速查表
以下命令能覆盖90%的日常场景。建议保存下来。
| 任务 | 命令 | 执行位置与说明 |
|---|---|---|
| 停止VM(节省成本) | az vm deallocate -g openclaw-rg -n <vm-name> | 本地终端。这会释放计算资源,只保留磁盘和IP的费用。 |
| 启动VM | az vm start -g openclaw-rg -n <vm-name> | 本地终端。VM启动需要1-2分钟。 |
| SSH登录VM | ssh azureuser@<vm-ip> | 本地终端。用于管理VM本身。 |
| 开启控制面板隧道 | ssh -L 18789:localhost:18789 azureuser@<vm-ip> | 本地终端。访问控制面板前必须运行。 |
| 获取带令牌的面板URL | oc run --rm openclaw-cli dashboard --no-open | 在VM的SSH终端中运行。每次连接都需要新的。 |
| 查看容器状态 | oc ps | VM终端。检查OpenClaw容器是否在运行。 |
| 查看实时日志 | oc logs -f | VM终端。-f参数可以持续输出日志,调试时非常有用。 |
| 重启OpenClaw服务 | oc restart | VM终端。在修改配置后使用。 |
| 完全销毁所有资源 | ./scripts/destroy.sh | 本地项目目录。危险操作,会删除整个资源组。 |
6.2 典型问题排查实录
即使按照指南操作,也可能会遇到问题。这里记录了几个我亲自遇到过并解决了的典型案例。
问题一:控制面板打开后显示“未授权”或“origin not allowed”
- 症状:浏览器打开
http://localhost:18789或带token的链接后,页面提示未授权或源不被允许。 - 根因分析:
- 使用了错误的URL:直接打开了
http://localhost:18789而没有带#token=...后缀。OpenClaw的网关会拒绝无令牌的访问。 - Token过期:生成的令牌是临时的。如果距离生成时间过长,或者重启了OpenClaw服务,旧的令牌会失效。
- 配置中的允许来源不匹配:OpenClaw配置 (
openclaw.json) 中的allowedOrigins字段可能只包含了http://localhost:18789,但你的浏览器实际访问的是http://127.0.0.1:18789(两者在浏览器看来是不同的“源”)。
- 使用了错误的URL:直接打开了
- 解决方案:
- 始终使用
oc run --rm openclaw-cli dashboard --no-open命令生成的新URL。 - 如果问题持续,检查并修正VM上的
~/.openclaw/openclaw.json文件:
确保nano ~/.openclaw/openclaw.jsonallowedOrigins数组同时包含http://localhost:18789和http://127.0.0.1:18789。“allowedOrigins”: [“http://localhost:18789”, “http://127.0.0.1:18789”] - 修改配置后,重启OpenClaw服务:
oc restart。
- 始终使用
问题二:Telegram机器人无响应,或AI回复“模型未找到”
- 症状:Telegram机器人能收到
/start,但对话时无反应,或者OpenClaw日志/控制面板显示类似404 - Resource not found或model_not_found的错误。 - 根因分析:这几乎总是Azure AI服务终结点或部署名称配置错误。
- 排查步骤:
- 在VM上检查配置文件:
重点关注cat ~/.openclaw/openclaw.jsonbaseUrl和deployment字段。baseUrl必须精确地以/openai/v1结尾。deployment的值必须与你在Azure门户中创建的模型部署名称完全一致,大小写敏感。
- 在本地检查环境变量:核对
docker/.env文件中的AZURE_API_BASE和AZURE_DEPLOYMENT_NAME。 - 手动测试API(在本地进行):
如果返回一个JSON格式的模型列表,说明终结点和密钥正确。如果返回404,说明终结点路径不对;如果返回403,说明密钥错误。# 将 <your-endpoint> 和 <your-key> 替换为你的值 curl -X GET “<your-endpoint>/openai/v1/models” \ -H “api-key: <your-key>”
- 在VM上检查配置文件:
- 解决方案:根据排查结果,修正
docker/.env文件中的错误配置,然后重新运行./scripts/configure-openclaw.sh脚本。该脚本会更新VM上的配置并重启服务。
问题三:VM运行一段时间后变得异常缓慢
- 症状:SSH连接卡顿,Docker命令执行缓慢,OpenClaw响应超时。
- 根因分析:
Standard_B2als_v2是一种可突增虚拟机。它有一个基准CPU性能(通常较低,如20%),并通过“CPU积分”机制来获得突发性能。当VM空闲时积累积分,高负载时消耗积分。如果OpenClaw容器因配置错误等原因不断崩溃重启(crash-loop),会持续消耗大量CPU积分。一旦积分耗尽,CPU性能就会被限制在基准水平,导致VM整体卡顿。 - 解决方案:
- 检查CPU积分:登录Azure门户,进入你的VM,在“监控”部分查看“剩余CPU积分”指标。如果接近0,说明积分已耗尽。
- 降低负载,等待恢复:停止不必要的进程。可突增VM在负载降低后会逐渐恢复积分。
- 检查容器状态:
oc ps查看容器是否在不断重启。oc logs查看日志找出崩溃原因(常见于AI配置错误)。 - 考虑增加交换空间:对于内存只有4GB的B2als_v2,如果应用内存占用过高,可能会触发OOM(内存溢出)导致容器被杀和重启循环。可以按项目文档建议,添加一个交换文件作为缓冲:
sudo fallocate -l 1G /swapfile sudo chmod 600 /swapfile sudo mkswap /swapfile sudo swapon /swapfile echo ‘/swapfile none swap sw 0 0’ | sudo tee -a /etc/fstab - 终极方案:如果问题频繁发生,可以考虑在Azure门户中将VM规格调整为性能更稳定的系列(如
Standard_D2s_v3),但成本会相应增加。
6.3 升级与维护
升级OpenClaw版本: OpenClaw项目本身在持续更新。要升级到最新版本,只需在VM上执行:
# 拉取最新的Docker镜像 oc pull # 重启服务以使用新镜像 oc up -d # (可选)清理旧的、无用的镜像层以节省磁盘空间 docker image prune -a前提:确保VM上~/openclaw/.env文件中设置了OPENCLAW_IMAGE=ghcr.io/openclaw/openclaw:latest。configure-openclaw.sh脚本默认会设置这个。
日常维护命令:
- 查看磁盘空间:
df -h。定期检查,确保根目录有足够空间。 - 查看系统资源:
htop(需安装)或top。监控CPU和内存使用情况。 - 查看安全更新日志:
grep “unattended-upgrades” /var/log/syslog。确认自动更新在正常工作。
7. 安全架构深度解析与成本控制实践
最后,我们来深入聊聊这个部署方案的安全设计和如何精明地控制云成本。理解这些,能让你更放心地使用这个私有AI助手。
7.1 多层防御的安全架构
这个项目不是简单地把应用跑起来,而是构建了一个从云到应用的多层防御体系:
- 身份认证层(SSH密钥):在VM层面彻底禁用密码登录,强制使用非对称加密的SSH密钥。私钥在本地,公钥在服务器,比密码安全几个数量级。
- 网络边界层(Azure NSG):在Azure云平台这一层,网络安全组充当了第一道防火墙。它明确了一条规则:仅允许来自你指定IP地址(
allowedSshSourceIp)的TCP 22流量。其他所有入站流量(包括ICMP ping)都被默认拒绝。 - 主机防火墙层(UFW):在Ubuntu操作系统内部,UFW提供了第二道防火墙。即使有人以某种方式绕过了NSG(理论上不可能,除非Azure有漏洞),也会被UFW的默认拒绝策略挡住。
- 入侵防御层(fail2ban):针对SSH端口的暴力破解尝试,fail2ban会动态分析日志,自动将攻击IP加入临时黑名单。
- 系统更新层(无人值守升级):自动安装安全补丁,确保操作系统没有已知的高危漏洞。
- 应用访问层(SSH隧道):OpenClaw服务本身不暴露任何端口到公网。所有访问都必须通过加密的SSH隧道进行。这意味着,即使应用本身存在未发现的漏洞,攻击者也无法从互联网直接触及它。
- 秘密管理层(.gitignore):所有包含敏感信息的文件(
parameters.json,.env,.deployment-info)都被排除在版本控制之外,避免了代码仓库泄露密钥的风险。
这种“纵深防御”的策略,确保了单一层面的失效不会导致整个系统被攻破。
7.2 精细化成本控制策略
Azure采用按需计费,对于个人项目,成本控制至关重要。
核心成本构成:
- 虚拟机计算:
Standard_B2als_v2按运行时间计费。约 $0.03/小时,每月持续运行约 $22。 - 托管磁盘:VM的系统盘(默认Premium SSD LRS)只要存在就计费,无论VM是否运行。每月约 $5。
- 公共IP地址:分配的标准静态IP地址,只要未被释放就计费,每月约 $3.65。
- 网络流量:入站流量免费,出站流量(VM到互联网)有少量费用,但个人使用量通常极小,可忽略。
- Azure AI服务:这是另一项独立费用,根据你选择的模型(如GPT-4o)和令牌使用量计费。本项目不产生额外AI成本,因为你使用的是自己已有的AI资源。
- 虚拟机计算:
省钱实战技巧:
- 非使用时关机:这是最有效的省钱方法。通过
az vm deallocate命令关机(停止并解除分配)。这会使你不再支付VM的计算费用,只支付磁盘和IP的费用,每月成本从~$27降至~$8.65。 - 使用自动化启停:对于有规律的使用场景(例如只在工作日白天使用),可以利用Azure自动化或简单的定时任务(cron job)来定时执行
az vm start和az vm deallocate。 - 监控成本:定期访问Azure门户的“成本管理+账单”中心,设置预算警报。你可以按资源组筛选,清晰看到
openclaw-rg这个资源组的开销。 - 考虑更低规格:如果OpenClaw负载很轻,可以尝试在
deploy.sh运行前,手动修改infra/main.bicep文件中的vmSize参数,换成Standard_B1ls(1 vCPU, 0.5 GiB内存)等更便宜的规格。但需注意内存可能不足,需要配合交换文件使用。
- 非使用时关机:这是最有效的省钱方法。通过
7.3 销毁与清理
当你不再需要这个环境时,务必彻底清理以停止所有计费。项目提供的destroy.sh脚本是最安全、最彻底的方式。
./scripts/destroy.sh脚本会列出将要删除的资源组,并要求你手动输入资源组名称进行确认。这是一个防止误操作的安全措施。确认后,它会删除整个openclaw-rg资源组及其内部的所有资源(VM、磁盘、IP、网络等)。
重要提示:这个操作不会删除你的Azure AI服务资源,因为它们通常位于另一个独立的资源组中。你的AI模型和部署保持不变。
通过以上七个部分的详细拆解,你应该已经掌握了在Azure上从零部署、配置、运维一个私有化、安全加固的OpenClaw AI助手的全流程。这套方案的优势在于其自动化、安全性和对数据主权的把控。它可能不是最简单的,但绝对是让你睡得最安稳的那种。