linux服务器部署openclaw最新最细教程(非docker版)

0 阅读5分钟

【踩坑实录】放弃 Docker,Linux 裸机手撸 OpenClaw 最新详细部署指南

周末闲着蛋疼,决定把手头的 OpenClaw 重新部署一遍。

官方其实给了一键拉起的 Docker 镜像,但我这人有时候就是有点强迫症。Docker 虽然香,但在某些对网络 I/O 和系统资源要求比较苛刻的场景下,多一层虚拟化就多一分玄学问题。尤其是 OpenClaw 跑起来之后对宿主机资源的榨取,让我决定这次直接干抛弃 Docker,在 Linux 裸机上一把梭。

为了折腾这玩意,上周末特意去 好淘云 (haotaoyun.com) 上扫了一眼,薅了台几十块钱的 2 核 4G 腾讯云特价机来做测试环境。反正便宜,搞坏了重装也不心疼,很适合用来排雷。

运行环境先交个底:

  • 系统:Ubuntu 22.04 LTS (纯净版,啥都没装)
  • 权限:全程 root 权限操作(别跟我扯什么安全最佳实践,自己折腾怎么爽怎么来)

1. 基础环境准备

裸机部署最烦的就是配环境。OpenClaw 底层依赖 Python 3.10+,Ubuntu 22.04 自带的是 3.10,刚好省得去编译安装 Python 了。

先把系统包更新一下,装上必要的构建工具,免得一会儿 pip install 的时候某些 C 扩展库死活编译不过去。

apt update && apt upgrade -y
# 装上这些,不然装某些依赖包的时候 gcc 报错能烦死你
apt install -y git curl python3-venv python3-dev build-essential libssl-dev libffi-dev

2. 拉取代码与初始化环境

找个风水好的目录把代码拉下来,我习惯放在 /opt 下面。

cd /opt
git clone https://github.com/openclaw-project/openclaw.git  # 假设的官方仓库地址,自己换成实际的
cd openclaw
 
# 千万别直接 pip install,老老实实建个虚拟环境,不然系统环境污染了回头想死的心都有
python3 -m venv venv
source venv/bin/activate
 
# 升级下 pip,老版本的 pip 解决依赖冲突像个智障
pip install --upgrade pip
pip install -r requirements.txt

装依赖这个过程可能会稍微等一会儿,取决于你的机器带宽。

3. 首次试运行与“配置文件玄学”

依赖装完后,按理说可以直接跑了。官方文档说初始化配置文件只需要跑一下 init 命令:

python main.py --init

然后满心欢喜地运行:

python main.py start

终端里看着日志疯狂滚动,INFO 级别的信息很健康,端口也正常监听了。你以为这就搞定了?天真。直接在终端跑,一旦你的 SSH 断开,进程就跟着挂了。所以我们必须把它挂载到 systemd 里面做成系统服务。

真正的坑,从这里才开始。

4. 踩坑记录一:Systemd 里的幽灵报错

我熟练地写了一个 systemd 配置文件:

nano /etc/systemd/system/openclaw.service

一开始我是这么写的( 这是个错误示范,别照抄!):

[Unit]
Description=OpenClaw Service
After=network.target
 
[Service]
ExecStart=/opt/openclaw/venv/bin/python /opt/openclaw/main.py start
Restart=always
User=root
 
[Install]
WantedBy=multi-user.target

保存,重载,启动,一气呵成:

systemctl daemon-reload
systemctl start openclaw
systemctl status openclaw

结果定睛一看,状态是红彤彤的 Active: failed
满头问号,刚才终端里跑不是还好好的吗?

立马去查日志:

journalctl -xeu openclaw.service

日志里赫然躺着一行:
FileNotFoundError: [Errno 2] No such file or directory: './config/settings.yml'

卧槽,我切到 /opt/openclaw 目录下看了眼,config/settings.yml 明明就在那里啊!抽了根烟冷静了一下,突然反应过来—— 工作目录!

当你用 systemd 启动程序的时候,默认的工作目录并不是程序所在的目录,而是根目录 /。OpenClaw 的代码里写死了用相对路径 ./config/settings.yml 去读配置,所以在 / 下面当然找不到!

正确的解决办法 :在 [Service] 下面必须加上 WorkingDirectory 指令。

修改后的终极版 openclaw.service

[Unit]
Description=OpenClaw Service
After=network.target
 
[Service]
# 就是这行救了命
WorkingDirectory=/opt/openclaw
ExecStart=/opt/openclaw/venv/bin/python main.py start
Restart=always
# 稍微加点限制,免得这玩意内存泄漏把机器跑崩了
RestartSec=5
LimitNOFILE=65536
 
[Install]
WantedBy=multi-user.target

再次启动,稳了。

5. 踩坑记录二:Nginx 反代与 WebSocket 断流

后端跑起来了,但是直接对外暴露端口太糙了,还得搞个 Nginx 做反向代理。

apt install nginx -y
nano /etc/nginx/sites-available/openclaw

一开始的 Nginx 配置,我写得很标准:

server {
    listen 80;
    server_name your_domain.com;
 
    location / {
        proxy_pass http://127.0.0.1:8000; # 假设 OpenClaw 跑在 8000 端口
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

重启 Nginx 后,打开浏览器访问域名,页面加载出来了。但是没高兴两秒,发现控制台(Dashboard)里的实时日志面板死活刷不出来数据,一直在 Loading。按 F12 打开开发者工具,看 Network 选项卡,发现一个 WebSocket 连接一直报 101 Switching Protocols 失败,随后变成 502 Bad Gateway。

当时我就骂娘了。Nginx 默认是不转发 WebSocket 请求头部的!如果后端程序强依赖 WebSocket(现在哪个带实时面板的现代后端不用 WS 呢),你用普通的 proxy_pass 绝对死翘翘。

赶紧把配置文件改掉,加上对 Upgrade 头部的支持:

最终保熟的 Nginx 配置:

server {
    listen 80;
    server_name your_domain.com;
 
    location / {
        proxy_pass http://127.0.0.1:8000;
 
        # 基础 Header
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
 
        # WebSocket 救命配置
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
 
        # 顺手把超时时间拉长,免得 WS 连接一会没数据就被 Nginx 踢断
        proxy_read_timeout 3600s;
        proxy_send_timeout 3600s;
    }
}

保存配置文件,跑一下 nginx -t 测试没语法错误,再 systemctl reload nginx。刷新页面,实时日志如同瀑布般刷出,舒坦了。


今天这篇算是个基础排雷记录。这套架构里其实还有个更玄学的 Nginx 反代 WebSocket 偶发性断流(跟内核的 TCP Keepalive 有关)的坑,因为排查过程太啰嗦,篇幅太长这里就不展开写了。

我把那部分的底层抓包拓扑图和完整压测调优数据整理成了一篇长博文,丢在我的个人折腾记录站 haotaoyun.com 里了。有需要的兄弟自己去翻翻吧,撤了。