很多人第一次接触 OpenClaw 源码安装时心里想的是“不就是 clone、install、build 三步走吗”结果真折腾起来会发现坑全藏在细节里Node 版本不对、编译工具链缺失、配置文件里的相对路径在开机自启后失效、systemd 和 launchd 的差异又完全不是一套逻辑。我这次把 Linux 和 macOS 两套环境从头到尾过一遍源码安装、基础配置、开机自启动以及各类报错都整理成手册形式尽量把每个操作背后的原因讲清楚而不只是丢给你一串命令。这篇内容适合真正想把 OpenClaw 跑在个人服务器、NAS 或主力开发机上的人也适合刚接触 Linux 服务管理、想把某个开源项目做成守护进程的初学者。我默认你至少会用终端执行命令但不会假设你熟悉 systemd 或 launchd 的完整语法所以每一步都会解释为什么这么写。1. 项目概述与源码安装思路OpenClaw 本质上是一个常驻后台运行的开源个人助理框架负责接收来自终端、消息通道或 API 的请求再把请求交给大模型服务进行理解与工具调用。它的主体是一个基于 Node.jsTypeScript编写的服务进程安装完成后你需要维护的其实就是这一个进程让它正常启动、保持运行、开机自动拉起。我之所以推荐源码安装而不是直接用某些包管理器分发版本主要有三个原因。第一这个项目迭代速度偏快功能调整频繁包管理器里的版本往往落后源码仓库一两个迭代遇到 bug 时你没法快速验证修复第二源码安装能让你直观察觉它依赖了哪些模块、数据落地在什么位置后续排错时心里有数第三很多人在生产环境有定制需求比如改端口、改数据目录、加内部证书源码方式改起来最直接。如果你是图省事、只想跑一圈试试功能那其实用 Docker 或官方脚本会更合适源码安装并不适合所有人。源码安装这件事本身并不复杂最核心的难点反而在安装之后的进程管理。Windows 上大家习惯装完就完事Linux 和 macOS 的世界里“让一个服务在系统重启后自动恢复”才是真正需要花时间的地方。Linux 有 systemdmacOS 有 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 版本有硬性要求。这里推荐用 nvmNode 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 SiliconM 系列芯片和 Intel 芯片的 PATH 路径不太一样建议执行which node确认一下。如果是 M 系列通常会落在/opt/homebrew/bin/nodeIntel 一般是/usr/local/bin/node这个路径在配自启动时需要用到别跳过了。2.3 版本检查清单我整理了一份常用检查清单装完后逐条过一遍比等到报错再排查省时间检查项最低要求推荐配置检查命令Node.js18.1720 LTSnode -vnpm9.x10.xnpm -vGit2.30最新版git --versionGCC/Clang 工具链可编译 C随系统最新gcc --version 或 clang --versionPython3.73.10python3 --version网络连通性可访问 npm registry稳定npm ping如果 Python 的版本太老某些 node 原生模块也能编但可能会出现各种诡异告警建议直接装新版本。这个阶段多花五分钟把版本确认完后面 npm install 环节会顺利得多。3. 源码安装、构建与初始化3.1 获取源码与切换版本找到 OpenClaw 项目的官方仓库后用 git 克隆到本地。我习惯把这类服务类项目放在固定目录Linux 用/opt/openclawmacOS 用$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 cinpm ci和npm install的区别值得说一句。npm ci会严格按照 package-lock.json 里面锁定的版本安装并清空 node_modules 后重新装速度更快也更能保证可复现性。而npm install会根据 package.json 的版本范围重新解析可能拿到比你上次安装时新的小版本。对于服务端项目稳定压倒一切我会在首次安装和升级时都用npm ci。安装过程中最常见的报错是编译型依赖失败比如某个模块需要 node-gyp 从源码编译原生代码而系统里缺编译工具链或 Python。看到这类报错不要慌回到第 2 节把build-essentialLinux或 Xcode CLTmacOS装上再清理重装一次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_PORT8787 OPENCLAW_HOST127.0.0.1 OPENCLAW_DATA_DIR./data OPENCLAW_LOG_LEVELinfo OPENCLAW_MODEL_PROVIDERdefault OPENCLAW_MODEL_API_KEYsk-xxxxxxxx OPENCLAW_MAX_WORKERS4 OPENCLAW_REQUEST_TIMEOUT60配置项作用注意事项OPENCLAW_PORT服务监听端口改端口后记得同步防火墙规则OPENCLAW_HOST监听地址127.0.0.1 只允许本机访问0.0.0.0 会暴露到局域网OPENCLAW_DATA_DIR数据存放目录建议用绝对路径自启动时不会迷路OPENCLAW_LOG_LEVEL日志级别debug 级别会输出大量请求体生产环境用 infoOPENCLAW_MODEL_API_KEY大模型服务密钥必须保密不要提交到 gitOPENCLAW_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] DescriptionOpenClaw Service Afternetwork-online.target Wantsnetwork-online.target [Service] Typesimple Userclaw Groupclaw WorkingDirectory/opt/openclaw EnvironmentFile/opt/openclaw/.env ExecStart/usr/bin/node /opt/openclaw/dist/index.js Restartalways RestartSec3 StandardOutputjournal StandardErrorjournal [Install] WantedBymulti-user.target把文件放到/etc/systemd/system/openclaw.service然后重新加载并启用sudo systemctl daemon-reload sudo systemctl enable --now openclaw systemctl status openclaw这个文件的几个关键设置我解释一下。WorkingDirectory指定工作目录解决相对路径问题。EnvironmentFile让 systemd 在启动进程前先加载 .env 里的变量这样密钥不需要写死在 ExecStart 里。Restartalways保证进程意外退出后能被自动拉起RestartSec3表示崩溃后等 3 秒再重启避免一直快速循环重启打满日志。这里有一个很常见的坑Afternetwork-online.target只是说网络服务已启动并不代表 IP 已经分配完成。如果你的机器用的是 DHCP极端情况下 service 启动时网络还没就绪服务会连接外部 API 失败。稳妥起见可以再加一个Restarton-failure策略让首次网络未就绪导致的失败自动重试。配合RestartSec10基本上 30 秒内网络就绪后服务能正常起来。日志查看方式journalctl -u openclaw -fsystemd 默认会把标准输出和标准错误重定向到 journal用上面的命令即可实时观察日志排查启动失败非常方便。5.2 macOS launchd 服务配置macOS 的开机自启走的是 launchd配置文件是 plist 格式语法比 systemd 容易多但坑也不少。我来写一个典型的 LaunchAgent plist服务于当前用户?xml version1.0 encodingUTF-8? !DOCTYPE plist PUBLIC -//Apple//DTD PLIST 1.0//EN http://www.apple.com/DTDs/PropertyList-1.0.dtd plist version1.0 dict keyLabel/key stringcom.openclaw.daemon/string keyProgramArguments/key array string/opt/homebrew/bin/node/string string/Users/yourname/apps/openclaw/dist/index.js/string /array keyWorkingDirectory/key string/Users/yourname/apps/openclaw/string keyEnvironmentVariables/key dict keyOPENCLAW_DATA_DIR/key string/Users/yourname/apps/openclaw/data/string /dict keyRunAtLoad/key true/ keyKeepAlive/key true/ keyStandardOutPath/key string/tmp/openclaw.stdout.log/string keyStandardErrorPath/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 再 bootstraplaunchctl bootout gui/$(id -u) ~/Library/LaunchAgents/com.openclaw.daemon.plist launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.openclaw.daemon.plist5.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 镜像源后重试也可加大 timeoutnpm install 报 node-gyp 错误缺少编译工具链或 Python 版本过旧安装 build-essential / Xcode CLT确认 python3 可用构建时JavaScript heap out of memoryNode 默认堆内存不够执行export NODE_OPTIONS--max-old-space-size4096后重新 build浏览器能访问 API 但服务启动失败HOST 或端口配置错误查看启动日志确认端口未占用确认 HOST 是否为本机地址systemd 状态显示 active 但服务无响应启动成功后网络才就绪导致连接中断增大 RestartSec观察 journal 确认重启后的状态launchd 加载时报 plist 文件格式错误plist 语法错误用plutil -lint 文件路径校验语法开机后服务不在了未 enable 或 KeepAlive 配置不对Linux 执行 systemctl enablemacOS 检查 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 时也栽过跟头后来总结出的规律是路径用绝对路径、环境变量显式注入、日志先看文件输出。把这几个原则记住无论以后换什么项目、换什么系统你都能很快搞定它的开机自启。
阅读完成 · 觉得有帮助?