☰
OpenClaw源码安装与开机自启动全攻略:Linux systemd与macOS launchd实践
2026/10/20 6:54:15 网站建设 项目流程

很多人第一次接触 OpenClaw 源码安装时,心里想的是“不就是 clone、install、build 三步走吗”,结果真折腾起来会发现坑全藏在细节里:Node 版本不对、编译工具链缺失、配置文件里的相对路径在开机自启后失效、systemd 和 launchd 的差异又完全不是一套逻辑。我这次把 Linux 和 macOS 两套环境从头到尾过一遍,源码安装、基础配置、开机自启动以及各类报错都整理成手册形式,尽量把每个操作背后的原因讲清楚,而不只是丢给你一串命令。

这篇内容适合真正想把 OpenClaw 跑在个人服务器、NAS 或主力开发机上的人,也适合刚接触 Linux 服务管理、想把某个开源项目做成守护进程的初学者。我默认你至少会用终端执行命令,但不会假设你熟悉 systemd 或 launchd 的完整语法,所以每一步都会解释为什么这么写。

1. 项目概述与源码安装思路

OpenClaw 本质上是一个常驻后台运行的开源个人助理框架,负责接收来自终端、消息通道或 API 的请求,再把请求交给大模型服务进行理解与工具调用。它的主体是一个基于 Node.js(TypeScript)编写的服务进程,安装完成后你需要维护的其实就是这一个进程:让它正常启动、保持运行、开机自动拉起。

我之所以推荐源码安装,而不是直接用某些包管理器分发版本,主要有三个原因。第一,这个项目迭代速度偏快,功能调整频繁,包管理器里的版本往往落后源码仓库一两个迭代,遇到 bug 时你没法快速验证修复;第二,源码安装能让你直观察觉它依赖了哪些模块、数据落地在什么位置,后续排错时心里有数;第三,很多人在生产环境有定制需求,比如改端口、改数据目录、加内部证书,源码方式改起来最直接。如果你是图省事、只想跑一圈试试功能,那其实用 Docker 或官方脚本会更合适,源码安装并不适合所有人。

源码安装这件事本身并不复杂,最核心的难点反而在安装之后的进程管理。Windows 上大家习惯装完就完事,Linux 和 macOS 的世界里,“让一个服务在系统重启后自动恢复”才是真正需要花时间的地方。Linux 有 systemd,macOS 有 launchd,两者语法不同、排错方式也不同,我会在第 5 节给你可直接抄的配置文件和操作命令。

整体安装流程可以先用一张表建立认知:

阶段主要工作关键产物容易出错的地方
环境准备安装 Git、Node.js、构建工具链可用的 node/npm 命令Node 版本过旧,npm 版本不匹配
获取源码拉取仓库、切换到目标版本项目源码目录拉到开发分支导致依赖不稳定
安装依赖npm 安装第三方模块package-lock.json 对应的 node_modules编译型依赖缺少 Python 或 C 工具链
构建产物执行 TypeScript 编译dist 或 build 目录内存不足导致 OOM
初始化配置生成 .env 和配置文件.env、数据目录密钥写在代码里,或权限为 777
进程托管systemd / launchd 注册守护进程配置环境变量、绝对路径、工作目录出错

搭建好这个整体认知后,再往下走就不会像无头苍蝇一样乱试命令了。

2. 环境准备与依赖检查

2.1 Linux 环境准备

我以 Ubuntu/Debian 系为例说明,其他发行版对应的包管理器命令不同,但思路一致。先做系统软件源更新,然后安装基础工具。

sudo apt update sudo apt install -y curl git build-essential python3

这里build-essential包含了 gcc、gmake 等编译工具链,python3 主要是给一些 node 原生模块的编译脚本用的。很多人忽略 python3 的安装,等到npm install时看到一个莫名其妙的 node-gyp 报错才回头补,不如一开始就装好。

接下来是 Node.js 安装。我不建议用 apt 直接装,因为 Ubuntu 官方源里的 Node 版本通常偏旧,而 OpenClaw 这类新项目对 Node 版本有硬性要求。这里推荐用 nvm(Node Version Manager)来装 LTS 版本:

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash source ~/.bashrc nvm install 20 nvm alias default 20 node -v npm -v

为什么执着于 LTS?因为 OpenClaw 依赖链里的很多框架,会先在 LTS 版本上做兼容测试,用最新奇数版本(比如 21、23)反而容易触发底层模块的兼容警告。如果你手头已经装了 nvm,安装完成后记得确认一下 npm 版本不低于 9,太低的话后续安装依赖会提示 lockfile 版本不兼容。

2.2 macOS 环境准备

macOS 上的准备分三步:安装 Xcode Command Line Tools、安装 Homebrew、通过 Homebrew 安装 Git 和 Node。

xcode-select --install

这个命令会弹出图形界面让你确认安装,装的是命令行工具,不需要装完整 Xcode,体积会小很多。如果不装,后面 git 和编译工具链都会缺胳膊少腿。

接着安装 Homebrew。这里要注意一点:早期很多人喜欢用 sudo 把 Homebrew 装到 /usr/local,但现在的安装脚本默认会装到用户目录,这其实是更好的做法,避免给系统目录写权限的隐患。

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" brew install git node

装完 Node 后,Apple Silicon(M 系列芯片)和 Intel 芯片的 PATH 路径不太一样,建议执行which node确认一下。如果是 M 系列,通常会落在/opt/homebrew/bin/node,Intel 一般是/usr/local/bin/node,这个路径在配自启动时需要用到,别跳过了。

2.3 版本检查清单

我整理了一份常用检查清单,装完后逐条过一遍,比等到报错再排查省时间:

检查项最低要求推荐配置检查命令
Node.js18.1720 LTSnode -v
npm9.x10.xnpm -v
Git2.30最新版git --version
GCC/Clang 工具链可编译 C++随系统最新gcc --version 或 clang --version
Python3.73.10+python3 --version
网络连通性可访问 npm registry稳定npm ping

如果 Python 的版本太老,某些 node 原生模块也能编,但可能会出现各种诡异告警,建议直接装新版本。这个阶段多花五分钟把版本确认完,后面 npm install 环节会顺利得多。

3. 源码安装、构建与初始化

3.1 获取源码与切换版本

找到 OpenClaw 项目的官方仓库后,用 git 克隆到本地。我习惯把这类服务类项目放在固定目录,Linux 用/opt/openclaw,macOS 用$HOME/apps/openclaw,这样后续写 systemd 或 launchd 配置时路径清晰,不容易出错。

git clone <openclaw-仓库地址> cd openclaw

克隆完成后,先别急着npm install。先看仓库当前在哪个分支,如果是默认分支,我建议先查看最近的 tag 版本,然后切到稳定版本,而不是直接用默认分支:

git tag -l git checkout v0.x.x

这里的原因很现实:默认分支是开发分支,可能正处于功能开发中途,依赖声明不稳定,你拉下来构建时可能今天能过、明天就不能过。而带 tag 的版本通常经过一定测试,至少能保证 package.json 里的依赖是可解析的。如果你是第一次接触这个项目,直接用最新稳定版能少踩非常多坑。

3.2 安装依赖

进入项目目录后,先看看有没有锁定文件。常见的两种锁定文件是package-lock.json(对应 npm)和yarn.lock(对应 yarn)。项目如果用的是 npm,就执行:

npm ci

npm ci和npm install的区别值得说一句。npm ci会严格按照 package-lock.json 里面锁定的版本安装,并清空 node_modules 后重新装,速度更快,也更能保证可复现性。而npm install会根据 package.json 的版本范围重新解析,可能拿到比你上次安装时新的小版本。对于服务端项目,稳定压倒一切,我会在首次安装和升级时都用npm ci。

安装过程中最常见的报错是编译型依赖失败,比如某个模块需要 node-gyp 从源码编译原生代码,而系统里缺编译工具链或 Python。看到这类报错不要慌,回到第 2 节把build-essential(Linux)或 Xcode CLT(macOS)装上,再清理重装一次:

rm -rf node_modules npm ci

这里有个容易犯的错:直接用 sudo 执行 npm install。一旦用 root 安装 node_modules,后续项目运行时的普通用户可能没有写权限,做热更新或写缓存时会遇到各种 permission denied。正确做法是让项目目录归当前用户所有,或者单独创建一个专用系统用户来跑服务。

3.3 构建与首次启动

依赖安装完成后,看下 package.json 里的 scripts 字段,通常会有 build 或 dev 脚本:

npm run build

构建就是 TypeScript 编译的过程,产物一般输出到 dist 目录。构建完以后,你可以先手动启动一次,确认服务本身能跑起来:

node dist/index.js

如果控制台能正常输出监听端口,说明基础环境没有问题。但源码包通常还带初始化配置的步骤,比如生成 .env 文件、初始化数据目录等:

cp .env.example .env npm run init

.env.example是项目自带的配置模板,复制成 .env 后才能填自己的密钥。如果你发现仓库里没有 .env.example,通常 README 里会直接给出需要手动创建的配置项,照着写即可。

3.4 升级与二次构建

项目用一段时间后,你会想升级到新版本。升级流程和首次安装类似,但要多一步备份:

git pull npm ci npm run build npm run migrate

这里npm run migrate只有在项目提供迁移脚本时才需要执行,一般会在 README 的升级说明里写清楚。千万别跳过备份,因为升级往往伴随着数据表结构或配置项格式的变化,没有备份就升级,一旦迁移脚本出问题,数据恢复会很麻烦。

我习惯在升级前把整个数据目录复制一份,命名带上日期:

cp -r ./data ./data-backup-$(date +%Y%m%d)

这种备份方式很笨,但足够简单可靠,特别适合个人维护的服务器服务。

4. 基础配置详解

4.1 配置项说明

OpenClaw 的配置主要通过 .env 环境变量文件和 config 文件完成。这两者分工有区别:环境变量适合放端口、路径、开关这类运行时参数,而 config 文件适合放结构化配置,比如工具列表、白名单等。

一份典型配置大概长这样:

# .env OPENCLAW_PORT=8787 OPENCLAW_HOST=127.0.0.1 OPENCLAW_DATA_DIR=./data OPENCLAW_LOG_LEVEL=info OPENCLAW_MODEL_PROVIDER=default OPENCLAW_MODEL_API_KEY=sk-xxxxxxxx OPENCLAW_MAX_WORKERS=4 OPENCLAW_REQUEST_TIMEOUT=60
配置项作用注意事项
OPENCLAW_PORT服务监听端口改端口后记得同步防火墙规则
OPENCLAW_HOST监听地址127.0.0.1 只允许本机访问,0.0.0.0 会暴露到局域网
OPENCLAW_DATA_DIR数据存放目录建议用绝对路径,自启动时不会迷路
OPENCLAW_LOG_LEVEL日志级别debug 级别会输出大量请求体,生产环境用 info
OPENCLAW_MODEL_API_KEY大模型服务密钥必须保密,不要提交到 git
OPENCLAW_MAX_WORKERS并发处理数按机器内存调整,默认值一般偏保守
OPENCLAW_REQUEST_TIMEOUT单次请求超时时间根据实际模型响应速度设置

这里特别提一下 OPENCLAW_HOST。很多新手会为了图省事直接设成 0.0.0.0,结果服务暴露在公网或局域网,一旦模型密钥被扫描抓取,损失远超想象。如果你只是本机使用,请务必用 127.0.0.1;只有需要内网其他设备访问时才放开,并配合防火墙和访问控制。

4.2 密钥和信息安全

. env 文件里最敏感的就是 API Key。这里有几个必须养成的习惯:

第一,不要动它提交进 Git。在你初始化仓库或做其他操作前,先确认 .env 已经在 .gitignore 里,如果没有,手动加进去。

第二,修改权限,让密钥文件对其他人不可读:

chmod 600 .env

第三,尽量不要把密钥写在启动脚本里。写脚本的人容易图方便,把密钥明文写进 shell 或 service 配置里,可在 systemd 的 EnvironmentFile 里其实可以单独指定,放到一个只有 root 或服务账号能读的文件里。

如果你在 macOS 上,可以考虑用系统的钥匙串来管理密钥,运行时通过环境变量注入。但要注意,launchd 启动的服务和你在终端里执行的 shell 环境并不完全一致,环境变量的传递往往需要额外设置,这一点在第 5 节会详细展开。

4.3 双平台路径差异

配置里的相对路径在手动启动时没问题,因为当前目录就是你执行命令的目录。但一旦交给 systemd 或 launchd 托管,工作目录并不一定等同于项目目录:systemd 默认的工作目录是/,launchd 也不会主动切到项目目录。所以配置和数据目录尽量不要用相对路径,直接把 .env 和配置里的OPENCLAW_DATA_DIR=./data改成绝对路径,例如/opt/openclaw/data。

macOS 还有个容易踩的坑:用 Homebrew 安装的 Node 和系统自带 Node 路径不同,你终端里执行 which node 拿到的路径,和 launchd 启动服务时实际调用的路径不一定一致。配置自启动时务必写上 Node 的绝对路径,最好先手动执行一次找到真实路径再写进配置文件。

5. 开机自启动与守护进程

5.1 Linux systemd 服务配置

先把服务注册成系统服务,创建一个 systemd unit 文件:

[Unit] Description=OpenClaw Service After=network-online.target Wants=network-online.target [Service] Type=simple User=claw Group=claw WorkingDirectory=/opt/openclaw EnvironmentFile=/opt/openclaw/.env ExecStart=/usr/bin/node /opt/openclaw/dist/index.js Restart=always RestartSec=3 StandardOutput=journal StandardError=journal [Install] WantedBy=multi-user.target

把文件放到/etc/systemd/system/openclaw.service,然后重新加载并启用:

sudo systemctl daemon-reload sudo systemctl enable --now openclaw systemctl status openclaw

这个文件的几个关键设置我解释一下。WorkingDirectory指定工作目录,解决相对路径问题。EnvironmentFile让 systemd 在启动进程前先加载 .env 里的变量,这样密钥不需要写死在 ExecStart 里。Restart=always保证进程意外退出后能被自动拉起,RestartSec=3表示崩溃后等 3 秒再重启,避免一直快速循环重启打满日志。

这里有一个很常见的坑:After=network-online.target只是说网络服务已启动,并不代表 IP 已经分配完成。如果你的机器用的是 DHCP,极端情况下 service 启动时网络还没就绪,服务会连接外部 API 失败。稳妥起见可以再加一个Restart=on-failure策略,让首次网络未就绪导致的失败自动重试。配合RestartSec=10,基本上 30 秒内网络就绪后服务能正常起来。

日志查看方式:

journalctl -u openclaw -f

systemd 默认会把标准输出和标准错误重定向到 journal,用上面的命令即可实时观察日志,排查启动失败非常方便。

5.2 macOS launchd 服务配置

macOS 的开机自启走的是 launchd,配置文件是 plist 格式,语法比 systemd 容易多,但坑也不少。我来写一个典型的 LaunchAgent plist,服务于当前用户:

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Label</key> <string>com.openclaw.daemon</string> <key>ProgramArguments</key> <array> <string>/opt/homebrew/bin/node</string> <string>/Users/yourname/apps/openclaw/dist/index.js</string> </array> <key>WorkingDirectory</key> <string>/Users/yourname/apps/openclaw</string> <key>EnvironmentVariables</key> <dict> <key>OPENCLAW_DATA_DIR</key> <string>/Users/yourname/apps/openclaw/data</string> </dict> <key>RunAtLoad</key> <true/> <key>KeepAlive</key> <true/> <key>StandardOutPath</key> <string>/tmp/openclaw.stdout.log</string> <key>StandardErrorPath</key> <string>/tmp/openclaw.stderr.log</string> </dict> </plist>

将文件保存到~/Library/LaunchAgents/com.openclaw.daemon.plist,然后加载:

launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.openclaw.daemon.plist

查看状态和日志:

launchctl list | grep openclaw tail -f /tmp/openclaw.stderr.log

注意 ProgramArguments 里我用的是/opt/homebrew/bin/node,这是 Apple Silicon 上 Homebrew 的默认路径;如果是 Intel 机器或使用 nvm 安装,路径会不同,先执行which node再回填,不要想当然。KeepAlive 为 true 时,进程无论因为什么原因退出都会被 launchd 重新拉起。如果你希望只在开机时启动一次、退出后不要反复拉起,可以改为 false。

如果改配置需要重载,用 bootout 再 bootstrap:

launchctl bootout gui/$(id -u) ~/Library/LaunchAgents/com.openclaw.daemon.plist launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.openclaw.daemon.plist

5.3 自启动常见故障与排查思路

服务装好之后最怕的就是“手动启动没问题,自启动一开就挂”。我总结几个高频原因:

第一,环境变量丢了。systemd 启动的进程不会自动读取你写在~/.bashrc里的变量,所以必须通过 EnvironmentFile 显式加载。macOS 的 launchd 对环境变量有一些特殊约定,在 GUI 会话中通过 launchctl setenv 设置的值只在当前 GUI 会话有效,系统启动阶段不保证存在,最简单的做法是把关键变量全部显式写进 plist 的 EnvironmentVariables 字典。

第二,Node 路径不对。systemd 和 launchd 的 PATH 都比较精简,不会像你的 shell 那样自动加载 nvm。如果 ExecStart 写的是node而不是/usr/bin/node,可能直接提示找不到命令。务必写绝对路径。

第三,工作目录不对。进程如果找不到数据目录或配置文件,会直接启动失败。排查时先看 journal 或 stderr 日志,这类问题一般日志会直接给出报错路径。

第四,权限不足。如果你的服务用系统用户运行,而 .env 或数据目录属于你自己的用户,进程会没有读取权限,启动即退。这时要么让服务用户和目录所有者一致,要么修改目录权限为 750 并正确设置属主组。

6. 常见问题与避坑经验

这一节把安装和使用中会遇到的典型问题整理成速查表,再补充几条实操中的独门经验。

6.1 问题速查表

现象最可能的原因排查与解决办法
npm ci 卡住或长时间无响应网络到 npm registry 不稳定检查网络,配置 npm 镜像源后重试;也可加大 timeout
npm install 报 node-gyp 错误缺少编译工具链或 Python 版本过旧安装 build-essential / Xcode CLT,确认 python3 可用
构建时JavaScript heap out of memoryNode 默认堆内存不够执行export NODE_OPTIONS="--max-old-space-size=4096"后重新 build
浏览器能访问 API 但服务启动失败HOST 或端口配置错误查看启动日志,确认端口未占用,确认 HOST 是否为本机地址
systemd 状态显示 active 但服务无响应启动成功后网络才就绪,导致连接中断增大 RestartSec,观察 journal 确认重启后的状态
launchd 加载时报 plist 文件格式错误plist 语法错误用plutil -lint 文件路径校验语法
开机后服务不在了未 enable 或 KeepAlive 配置不对Linux 执行 systemctl enable,macOS 检查 plist 是否放进了 LaunchAgents
服务重启后数据丢失数据目录用了相对路径,而服务启动目录非项目目录将数据目录配置改为绝对路径

6.2 内存资源与并发控制

在低配机器上跑 OpenClaw,最明显的瓶颈是内存。Node 服务的默认堆内存一般受限于系统内存,并不一定够用。上次我在只有 2G 内存的机器上构建,npm run build直接 OOM,后来加了一个 swap 文件就好了:

sudo fallocate -l 2G /swapfile sudo chmod 600 /swapfile sudo mkswap /swapfile sudo swapon /swapfile

关于并发的设置,OPENCLAW_MAX_WORKERS 不建议盲目调大。每个并发请求都会占用内存和处理线程,并发数过大反而会因为频繁上下文切换导致吞吐量下降。我的经验是先从默认值开始,观察内存占用,CPU 都没跑满再加,一次加两个,稳着来。

6.3 日志轮转和持久化

服务一旦常驻,日志文件会无限增长。Linux 上我用 journal 管日志,它会自动按大小轮转,不用额外操心。macOS 上我重定向到了文件,就需要定期清理了。一个简单的方案是让系统自带的 newsyslog 定时轮转,但更省事的是直接写个 cron 定时把超过 7 天的日志清掉:

find /tmp -name "openclaw.*.log" -mtime +7 -delete

别小看这个问题,日志塞满磁盘会导致服务异常,而且往往是你不在现场的时候才发生,到时候排查起来非常痛苦。

6.4 多版本共存与翻车恢复

如果你在机器上同时维护多个 Node 项目,很容易遇到“这个项目要 Node 18,那个项目要 Node 20”的情况。解决方案是坚持用 nvm,并在项目目录下放一个.nvmrc文件,内容写上 20。这样每次进入目录执行nvm use就能自动切换版本,减少大量低级错误。

如果某次升级后服务起不来,不要急着删库重来。先看日志,一般是依赖不兼容或配置字段改动。我的习惯是先回滚源码版本:

git checkout <上一个正常tag> npm ci npm run build

如果回滚源码后还是不行,大概率是数据目录里的配置格式已经升级了,这时候备份好的数据就派上用场了,恢复备份目录再启动。

6.5 永远先手动启动一次

最后分享一个让我少走很多弯路的小习惯:任何一次升级或改配置后,我都会先在前台手动启动一次:

npm run build && node dist/index.js

如果前台能正常跑、不报错、能正常响应请求,再启动 systemd 或 launchd。因为前台启动能直接看到输出,报错时定位最快。直接改完配置就去 systemctl restart,一旦失败,你还要去翻日志,绕一大圈。这个习惯花了很小的成本,却能帮你把安装维护的摩擦降到最低。

OpenClaw 的源码安装本身是不难,真正决定后续使用体验的是你是否愿意花十分钟把进程托管和日志系统理顺。我第一次在 macOS 上配 launchd 时也栽过跟头,后来总结出的规律是:路径用绝对路径、环境变量显式注入、日志先看文件输出。把这几个原则记住,无论以后换什么项目、换什么系统,你都能很快搞定它的开机自启。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询