这个项目圈子里最近的讨论热度确实起来了,很多人拿到手第一件事就是往云服务器上整,结果一半以上都卡在环境依赖、端口不通和日志看不出问题这三件事上。这篇文章就围绕 OpenClaw(Clawdbot)在阿里云上的完整部署过程,从买机器开始一步一步讲到服务跑起来,中间会穿插说明每一步为什么要这么做,以及我在实际部署里踩过、也帮别人排查过的那些坑。
不管你是第一次接触这类服务框架,还是已经折腾过几轮但总在某个环节翻车,这篇文章都能给你一条能走通的路径。我会尽量把每一步的操作、理由和可能出现的问题都讲清楚。
1. 部署前的思路与架构选型
1.1 为什么选择阿里云 + Docker 的组合
先回答一个很多人会问的问题:为什么推荐阿里云,而不是本地虚拟机或者树莓派之类的东西?
OpenClaw 这类智能体服务框架对网络的稳定性要求比较高,需要长时间在线、能够被动接收请求,而且后续如果想要接入消息推送、回调函数或者对外提供 API,就必须要有一个公网可达的地址。本地设备虽然也能跑,但家庭宽带的动态IP、运营商封端口、设备断电这些问题会让整个服务变得很不靠谱。阿里云轻量应用服务器或者 ECS 的优势在于:固定公网IP、24小时在线、安全组规则可以灵活控制,而且新用户买轻量服务器的话成本其实很低,一年下来比一杯咖啡钱多不了多少。
再说为什么用 Docker 而不是直接在系统里安装 Python、Redis 这些环境。我见过太多人死在环境依赖上:Python 版本不对、OpenSSL 版本不兼容、某个 C 库缺失导致编译失败,每一个问题都能让人浪费半天时间。Docker 把这些依赖全部封装在镜像里,只要镜像能跑起来,就不需要考虑宿主机上装了什么东西。而且 Docker Compose 可以用一个文件把 Web 服务、数据库、缓存、队列这几件套全部编排起来,一键启动、一键停止,升级也不用手动清理旧文件。
提示:部署这类框架,优先选 Ubuntu 22.04 LTS 系统镜像。这个版本的用户基数大,遇到问题搜解决方案最容易命中,而且对 Docker 的支持最稳定,不需要额外折腾内核模块。
1.2 目标架构与组件清单
先说清楚我们要部署的完整结构,免得后面跑起来之后不知道哪一层出了状况。
整套服务主要由四个部分组成:
| 组件 | 作用 | 说明 |
|---|---|---|
| OpenClaw 主服务 | 核心运行框架 | 负责接收指令、执行定时任务、调用工具链 |
| PostgreSQL 数据库 | 数据持久化 | 保存任务记录、会话状态、配置信息 |
| Redis | 缓存与消息队列 | 处理异步任务、会话缓存、限流控制 |
| Nginx | 反向代理 | 统一入口,处理 HTTPS 和 WebSocket 转发 |
为什么要拆成这么多服务?一个核心原因是职责分离。比如任务队列放在 Redis 里,就算主服务挂了重启,未执行的任务还能在队列里保留着,等恢复后再继续处理,不至于丢任务。PostgreSQL 单独跑,能保证数据的一致性,而且不会被主服务的重启影响。Nginx 在最前面做入口,统一管理证书和端口转发,这样主服务本身就不需要直接暴露到公网上,安全性高很多。
内存配置上,我建议机器选择 2GB 内存起步,4GB 更宽裕。OpenClaw 主服务本身占用大约 300MB 到 500MB,PostgreSQL 空闲时占用 80MB 左右,但遇到复杂查询时会有明显的内存峰值,Redis 加上缓存之后又占几十MB,多预留一点内存,能避免很多莫名其妙的服务崩溃问题。
2. 云服务器与基础环境准备
2.1 购买实例与安全组配置要点
在阿里云控制台购买实例时,有几个参数需要重点确认。地域原则上离你的目标用户近一点就行,如果你主要自己用,选哪都无所谓,但如果你要接国内的服务回调,选国内地域延迟会好看一些。系统镜像选 Ubuntu 22.04 LTS,这点我上面已经说过,不再重复。带宽建议按流量计费,基础带宽选 3Mbps 到 5Mbps 就够用,按流量付费比固定带宽灵活,费用也低一些,特别是前期调试阶段流量消耗其实很少,跑几天也就几百MB。
购买完成之后,第一件事不是装环境,而是配置安全组。这里有个非常经典的坑:很多人默认只开放了 22 端口,结果部署完发现 Web 界面打不开,日志里又看不出任何异常,最后才发现是安全组没放行端口。
需要放行的端口如下:
- 22:SSH 登录端口,正常保留
- 80:HTTP 访问,如果配了 HTTPS 后面可以让 Nginx 强制跳转
- 443:HTTPS 访问,强烈建议开启
- 17000:OpenClaw 服务默认监听端口(按你的实际情况填写,但以后统一用这个)
注意:如果你后续要接 WebSocket 功能,确认安全组里放行了对应端口,同时阿里云的控制台里能否修改源IP范围?能就尽量限制来源IP,不要对 0.0.0.0/0 全放行。
2.2 系统初始化与账户安全
拿到服务器 IP 和 root 密码后,通过 SSH 登录,先做三个初始化操作。
第一个是更新系统软件源。Ubuntu 22.04 的软件源在国内访问速度还算可以,但如果遇到下载慢的情况,可以替换成阿里云的镜像源。执行命令更新索引并升级已有软件包:
sudo apt update && sudo apt upgrade -y第二个是创建一个日常使用的普通用户。长期用 root 操作风险太高,万一某条命令写错,可能直接导致系统起不来。创建用户并加入 sudo 组:
sudo adduser deploy sudo usermod -aG sudo deploy之后日常都用这个用户操作,只有需要特权时在前面加 sudo。
第三个是配置 SSH 密钥认证。很多安全问题都源于密码登录被暴力破解,配置密钥登录之后可以关闭密码登录。在本地机器生成密钥对,然后把公钥上传到服务器:
ssh-keygen -t ed25519 -C "openclaw-deploy" ssh-copy-id deploy@你的服务器IP上传完成之后测试一下密钥登录是否正常,确认能用就修改 /etc/ssh/sshd_config,把 PasswordAuthentication 改成 no,再重启 SSH 服务。这一步做完,密码爆破的威胁就基本解决了。
2.3 安装基础软件:Docker、Compose、Git
接下来的操作统一用刚创建的 deploy 用户执行。安装 Docker 本身没什么复杂的,但有些细节需要注意。
先在系统里安装几个基础依赖包,然后添加 Docker 官方源。阿里云专门为国内用户提供了 Docker 的镜像源地址,速度比官方源快非常多:
sudo apt install -y ca-certificates curl git sudo install -m 0755 -d /etc/apt/keyrings curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg sudo chmod a+r /etc/apt/keyrings/docker.gpg echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null sudo apt update sudo apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin安装完之后,把 deploy 用户加入 docker 组,这样就不用每次敲命令都带 sudo:
sudo usermod -aG docker deploy记得重新登录一次,让组的变更生效。验证安装是否成功,运行版本检查命令:
docker version docker compose version两条命令都能正常输出版本信息,说明 Docker 环境就绪。
提示:如果你发现 docker pull 拉取镜像的速度异常慢,可以在 /etc/docker/daemon.json 里配置 registry-mirrors,填入可用的镜像加速地址,然后重启 Docker 服务。这个文件如果不存在则自己创建。
3. 项目获取与配置文件编写
3.1 拉取代码与目录设计
环境准备好之后,开始拉取 OpenClaw 的项目文件。项目的仓库地址通常在项目文档首页就能找到,通过 Git 克隆到服务器上的指定目录:
mkdir -p ~/apps/openclaw cd ~/apps/openclaw git clone https://github.com/你的项目地址/openclaw.git .这里注意一个小细节:目录名不要带空格,不要放在系统盘根目录,也不要放在 /tmp 下,因为重启后 /tmp 的内容可能被清空。建议统一放在用户目录下的 apps 子目录里,后续维护好找。
仓库克隆完成之后,先看下目录结构,确认有没有 docker-compose.yml 文件、.env.example 示例文件,以及 README 或 docs 目录下的配置说明。这三个东西是部署的关键线索。
3.2 环境变量与核心参数详解
大多数项目都会提供一个 .env.example 文件,里面是运行配置的模板。我们需要把它复制成 .env,然后逐项修改:
cp .env.example .env打开 .env 文件,重点关心这几类配置:
第一类是数据库配置。包括 PostgreSQL 的用户名、密码、数据库名,以及连接地址。注意,在 Docker Compose 网络内部,服务名就是主机名,所以数据库地址通常写 postgres 而不是 127.0.0.1。密码建议用一段随机字符串,不要用 123456。
第二类是 Redis 配置。同样,连接地址写 redis,端口保持默认 6379。如果在配置里需要密码,记得和 compose 文件里的密码保持一致。
第三类是密钥和 Token 配置。OpenClaw 通常需要一个主密钥或者 Token 用于 API 鉴权,这个 Token 要足够长、足够随机。生成方式很简单:
openssl rand -hex 32把生成的结果填到 .env 对应的字段里。这个 Token 相当于你服务的钥匙,不要泄露、不要提交到 Git 仓库。
第四类是域名和回调地址配置。如果你打算对外提供服务,或者要接收某些平台的回调消息,这里的 Base URL 必须是公网可访问的完整地址,比如 https://bot.example.com。如果只在内网调试,可以先用 http://服务器IP:端口。
注意:.env 文件里任何包含密码、Token 的字段都尽量不要写在博客、截图或者分享内容里。我见过有人调试时把配置截图发到群里,结果 Token 被扫走,服务被拿去当肉鸡挖矿。
3.3 编写 docker-compose.yaml
如果项目自带 docker-compose.yml,那直接用即可。但如果自带文件里缺少某些服务,或者你想调整资源限制,那就需要自己维护一份。下面是一个基础可用的 compose 文件参考:
version: "3.8" services: postgres: image: postgres:16-alpine container_name: openclaw-postgres restart: unless-stopped environment: POSTGRES_USER: ${POSTGRES_USER} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} POSTGRES_DB: ${POSTGRES_DB} volumes: - postgres_data:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"] interval: 10s timeout: 5s retries: 5 redis: image: redis:7-alpine container_name: openclaw-redis restart: unless-stopped command: redis-server --appendonly yes volumes: - redis_data:/data healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 5 openclaw: image: openclaw/最新版本镜像名 container_name: openclaw-main restart: unless-stopped depends_on: postgres: condition: service_healthy redis: condition: service_healthy env_file: - .env ports: - "17000:17000" volumes: - app_logs:/app/logs - app_data:/app/data volumes: postgres_data: redis_data: app_logs: app_data:几个配置点说明一下。depends_on 配合 healthcheck 写,可以确保主服务启动前数据库和 Redis 已经就绪,避免启动竞争导致的连接失败。restart 策略用 unless-stopped,意味着除非手动 stop,否则容器挂掉后会自动拉起。时间同步、时区这些问题如果不加特殊配置,容器会用 UTC 时间,如果你的业务日志需要本地时间,可以在环境变量里加 TZ=Asia/Shanghai。
3.4 用容器编排保持环境一致
为什么坚持用 docker compose 而不是直接在主服务容器里手动装 Redis?因为 Compose 把整个环境定义成一个"可重复的配方",换一台新机器,只需要把项目目录和 .env 一起拷过去,一条命令就能恢复整套环境。省去重复"安装依赖、改配置、排错"的过程。
我也建议把容器视为"一次性"的,想更新某个组件,直接改镜像版本号,然后 recreate 容器就行,旧数据都保留在 volume 里,不会丢。
4. 启动服务与连通性验证
4.1 首次启动与日志解读
所有配置文件就绪之后,执行启动命令:
cd ~/apps/openclaw docker compose up -d第一次启动会拉取镜像,耗时取决于镜像大小和网速,一般三到五分钟。启动完之后,用下面的命令看所有容器的状态:
docker compose ps正常的输出里,三个容器都应该是 Up 状态。如果有一个容器的状态显示 Restarting,基本可以断定是启动失败,原因可能在数据库没有准备好、环境变量缺失或者端口被占用。
想看详细日志,用:
docker compose logs -f openclaw观察日志输出,有几个关键信息需要关注:
- 是否成功连接到 PostgreSQL,连接成功的日志通常会显示类似 "database connection established" 的信息
- 是否成功连接到 Redis,会显示 ping 成功的信息
- 是否成功加载模型或初始化工具链,这个过程会比较慢,日志会逐步输出加载的模块名称
提示:首次启动如果发现日志长时间不更新,不要急着 Ctrl+C。有些模块需要下载模型文件或者初始化向量索引,这期间日志输出很少,但后台进程其实在工作。可以先看容器资源占用情况,如果 CPU 持续有变化,说明还在处理中。
4.2 Web 入口与服务健康检查
如果 OpenClaw 自带 Web 控制台或者管理界面,通常默认监听刚才放行的 17000 端口。在浏览器输入 http://服务器IP:17000,能看到登录页就可以继续下一步。
这里有个高频问题:页面打不开,但日志显示服务已经启动。排查顺序如下:
第一步,先确认机器内部可以访问服务:
curl http://127.0.0.1:17000/health如果返回正常的 JSON 信息,说明服务本身没问题。
第二步,检查阿里云安全组是否放行了 17000 端口。有些用户开的是轻量应用服务器,安全组和防火墙配置在控制台另一个入口,别漏看。
第三步,如果服务器开启了 ufw 防火墙,需要放行端口:
sudo ufw allow 17000/tcp这三步走完,90% 的"打不开"问题都能解决。剩下的可能就是 Nginx 配置问题,往下看。
4.3 Nginx 反向代理与 HTTPS 配置
虽然直接用 IP 加端口也能访问,但公网环境下我强烈建议套一层 Nginx,主要是为了做 HTTPS,以及为后续的域名绑定做准备。
在服务器上安装 Nginx:
sudo apt install -y nginx然后创建一个站点配置文件:
sudo nano /etc/nginx/sites-available/openclaw内容如下,注意 server_name 换成你自己的域名,上游地址指向 OpenClaw 服务端口:
server { listen 80; server_name bot.example.com; location / { proxy_pass http://127.0.0.1:17000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } }启用这个站点并重载 Nginx:
sudo ln -s /etc/nginx/sites-available/openclaw /etc/nginx/sites-enabled/ sudo nginx -t sudo systemctl reload nginx如果没有域名,可以先使用 IP 访问,等到有域名之后再补充 HTTPS 配置。证书申请方面,让 Nginx 通过验证域名归属来申请免费证书,一个比较顺畅的做法是先配置好 HTTP 跳转,再用自动续期工具处理证书。
需要提醒的是,如果你后续要接平台回调,回调 URL 必须是 HTTPS,所以证书这一步最终是绕不过去的。建议从一开始就用域名部署。
5. 日志排查与常见故障处理
5.1 常见问题速查表
部署过程中遇到的故障,绝大多数都能归到几个固定的套路里。直接看表:
| 现象 | 原因 | 处理方法 |
|---|---|---|
| 容器不断重启,状态显示 Restarting | 环境变量错误,或数据库/Redis未就绪 | 用 docker compose logs openclaw 查看具体报错,检查 .env 配置 |
| 外部访问不通,但服务日志正常 | 安全组未放行端口,或系统防火墙拦截 | 检查阿里云安全组入方向规则,执行 sudo ufw status |
| 数据库连接失败 | 密码不一致,或服务地址写错 | 确认 .env 中密码,compose 内连接地址用服务名 postgres |
| 磁盘空间被日志占满 | 容器日志未做轮转 | 设置 max-size 和 max-file 限制,定期清理 |
| 上传的模型/数据文件写入失败 | 挂载目录权限不足 | 宿主机目录给合适的用户权限,或用 named volume 避免权限问题 |
| WebSocket 连接秒断 | Nginx 未配置升级响应头 | 在 location 中追加 Upgrade 和 Connection 头 |
5.2 我踩过的几个坑
第一个坑,是将 .env 文件里的密码设置成了和外部服务一样的弱密码。有一次在某台服务器上部署类似框架时,Redis 没有启用密码保护,结果被脚本扫描打进来,被塞了一堆挖矿进程,最后只能整台机器重装。教训就是:所有中间件都必须设置访问密码,不能裸奔。
第二个坑,是日志文件不轮转。容器长时间运行后日志量非常惊人,尤其在 DEBUG 级别模式下,几天就能写满几十GB磁盘。解决办法是,在 compose 文件中为 openclaw 服务加 log 配置:
logging: driver: "json-file" options: max-size: "20m" max-file: "5"第三个坑,是修改了 .env 文件后没有重建容器。很多人改完配置后直接 docker compose restart,发现改动没有生效。原因在于环境变量是容器创建时注入的,restart 不会重新读取 .env。正确的操作是:
docker compose up -d --force-recreate加 --force-recreate 强制重新创建容器,环境变量才会更新。
5.3 启动超时与初始化失败的处理思路
如果主服务启动到某个环节一直报错,比如模型初始化失败,首先要判断是不是网络下载问题。国内访问部分资源源不稳定,容易导致初始化超时。简单的处理办法是,在 .env 里设置超时时间参数(按项目文档说明调整),同时给容器加网络重试策略。但不建议把超时时间拉太长,因为如果真有问题,等待时间越长,浪费的时间越多。
如果确认是依赖包缺失,可以进入容器手动验证:
docker exec -it openclaw-main /bin/bash在容器内部手工执行相关命令,看看具体报错信息。容器内环境相对干净,报错往往比日志里更直接。
写在最后
部署 OpenClaw 这个流程,前前后后我帮人排查过不少次。整体感觉是,框架本身并不复杂,难的点都集中在环境一致性和网络配置上。只要理解了容器编排的基本逻辑,然后把安全组、防火墙、端口转发这几件事查一遍,部署过程基本就是一条直线走完。
最后再分享一个小技巧:每次修改配置之前,都先把当前生效的环境变量导出一份备份放在项目外的目录,比如 ~/backups/openclaw-env-日期.bak。这个习惯成本很低,但当你改完配置发现服务全部起不来的时候,能直接回滚到上一个可用状态,不用靠记忆去猜之前填的是什么。服务器上的生产服务,最怕的就是带着猜测去改配置,一次改多个变量,出了问题根本不知道是哪一步改坏的。