1. 为什么我要把OpenClaw搬进完全离线的环境
先说下背景。最近在折腾OpenClaw这套开源智能体框架,玩了一圈发现它确实能干活——接微信、飞书、钉钉,写小说、管理日程、调API跑自动化,上限很高。但真正让我决定把它改造成离线部署的,是前阵子一个内部项目需求:一台完全隔离的内网服务器,一个生产环境,不允许走任何外网请求。
当时我就在想,OpenClaw默认是走云端API的,模型推理要靠外部接口,这在离线场景下根本跑不通。后来花了几天时间,把OpenClaw、本地推理引擎、模型权重、依赖镜像全部打包到内网,最终实现了完全离线运行。整个过程踩了不少坑,尤其是Windows环境下的Node运行时问题、模型加载失败、资源锁冲突这些,今天一次性全部整理出来,给有同样需求的人一个可复现的参考方案。
这个方案适合谁?三类人:一是网络隔离要求严格的企业内部环境,数据不出内网是硬指标;二是想彻底摆脱按量计费API、把推理成本固定下来的人;三是纯折腾党,想在本地机器上完整跑一套不依赖外网服务的AI智能体。无论你属于哪一类,下面这套“有网机器准备 + 内网机器部署”的思路都适用。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 离线方案的架构设计与核心思路拆解
2.1 离线部署到底要解决哪几件事
很多人一听到“离线部署”就觉得是把安装包拷过去装一下,其实远没那么简单。OpenClaw这种框架级项目,离线部署至少要拆成四个维度来看:
-
程序本体:OpenClaw的代码、可执行文件、依赖库。它本身是用Node.js/TypeScript写的,部署时要考虑Node运行时版本、npm依赖、外部CLI工具链。
-
容器与系统依赖:如果走Docker方案,那镜像本身就包含了运行时依赖,这是最省心的做法;如果不用Docker,就得手动准备Node、Python、各类原生依赖库,麻烦程度翻倍。
-
模型推理引擎:OpenClaw本身只是个编排层,真正干活的是大模型。离线环境下必须有一个本地推理引擎,比如Ollama、llama.cpp、vLLM,或者NVIDIA NIM这类服务化推理组件。
-
模型权重文件:这是离线部署里最重的部分。一个7B量化模型大概4-5GB,13B模型要8GB以上,70B模型你得准备40GB+磁盘。这部分只能提前在有网环境下载,然后拷贝进内网。
这四个维度缺一不可。很多人离线部署失败,就是只准备了程序本体,忘了模型权重,或者模型权重有了但推理引擎没装好。
2.2 为什么我选择Docker容器 + Ollama的组合
我在方案选型上对比过三条路线:
路线一:纯二进制部署。 直接装Node.js,拉OpenClaw源码,再装Ollama。优点是灵活、改起来方便,缺点是OpenClaw的依赖非常多,Windows和Linux的兼容性问题一个接一个,离线环境下补依赖无比痛苦。
路线二:Docker容器打包OpenClaw,Ollama跑在宿主机。 这是我最终选用的方案。OpenClaw镜像一次性封装好所有运行时依赖,宿主机只需要装Docker和Ollama。模型通过宿主机网络暴露给容器内调用,逻辑清晰,迁移方便。
路线三:全部容器化。 OpenClaw和Ollama都跑Docker容器,用Docker Compose编排。优点是干净,缺点是Ollama的GPU透传在部分内网环境的NVIDIA驱动上容易出问题,配置复杂度高。
综合下来,路线二最稳。Docker镜像把最复杂的依赖问题隔离了,Ollama留在宿主机又保留了硬件调优的灵活性。还有个额外好处:以后升级OpenClaw,只需要换镜像,模型和配置完全不用动。
2.3 离线环境的拓扑结构
我实际部署的内网环境是这样的:
- 一台Linux服务器(Ubuntu 22.04),16核CPU,64GB内存,一张NVIDIA A10显卡(24GB显存)
- 无外网连接,只能通过U盘/内部文件服务器拷贝数据
- 客户机通过局域网访问OpenClaw的Web控制台和API
对应的组件关系是:OpenClaw容器通过http://172.x.x.x:11434访问宿主机的Ollama服务,Ollama加载本地模型权重做推理,OpenClaw的Skill和Agent逻辑全部在容器内运行,数据存储挂载宿主机目录持久化。
这套结构的核心思路就一句话:把需要联网才能做的事,全部挪到有网环境提前完成,内网只负责加载和执行。 后面所有操作都是围绕这句话展开的。
3. 有网机器上的部署包准备——这是最关键的环节
3.1 准备机器的环境要求
我用来做打包的是一台带外网的Ubuntu 22.04工作站,配置不需要很高,但磁盘最好留出80GB以上的空间,因为要同时放Docker镜像和模型权重。
准备工作分三步:
bash复制# 1. 安装Docker
curl -fsSL https://get.docker.com | sh
sudo systemctl enable --now docker
# 2. 安装Ollama
curl -fsSL https://ollama.com/install.sh | sh
# 3. 确认GPU驱动正常(NVIDIA环境)
nvidia-smi
如果你的打包机器是macOS或者Windows也没关系,Docker镜像的导出格式是通用的,Ollama的模型目录也可以跨平台拷贝。但注意一个事:容器镜像里如果包含GPU相关配置,建议在Linux环境下导出,兼容性最好。
3.2 拉取OpenClaw镜像并导出
OpenClaw官方提供Docker镜像,直接拉取即可:
bash复制# 拉取官方镜像,这里用最新稳定标签
docker pull openclaw/openclaw:latest
# 确认镜像存在
docker images | grep openclaw
这里有个坑:如果你的网络环境拉取Docker Hub很慢,建议先配置一个镜像加速器,或者在有稳定网络的环境下操作。镜像拉取完成后,用docker save导出成tar包:
bash复制# 导出镜像,gzip压缩可以省不少体积
docker save openclaw/openclaw:latest | gzip > openclaw-image.tar.gz
# 查看文件大小
ls -lh openclaw-image.tar.gz
OpenClaw镜像本身大约1-2GB,压缩后会更小。U盘拷贝完全没压力。
3.3 准备Ollama模型权重
这是整个准备过程中最需要耐心的环节。我用的是Ollama来跑本地推理,因为它对离线环境支持得很好,模型管理也简单。
先在准备机器上确认Ollama可用,然后拉取你需要的模型:
bash复制# 查看Ollama服务状态
ollama list
# 拉取模型,这里以Qwen2.5 7B指令版为例
ollama pull qwen2.5:7b-instruct
# 如果需要更大的模型,比如32B级别
ollama pull qwen2.5:32b-instruct-q4_K_M
模型选型这里多说两句。7B模型在24GB显存上跑非常轻松,速度也快,但复杂指令遵循能力一般;32B模型的智能程度提升明显,但需要大概20GB显存,A10刚好能跑。如果是CPU推理或者没有独显的环境,建议用7B甚至更小的4B模型,否则速度会让人崩溃。
下载完后,Ollama的模型文件默认存储在/usr/share/ollama/.ollama/models(Linux)或~/.ollama/models(macOS/Linux用户目录),我们需要把这整个模型目录完整拷贝出来:
bash复制# 确认模型目录位置
ollama list --format json | head -50
# 打包模型目录(以Linux默认路径为例)
sudo tar -czf ollama-models.tar.gz -C /usr/share/ollama/.ollama/models .
# 查看模型包大小
ls -lh ollama-models.tar.gz
有个细节:Ollama的模型是分层存储的,多个模型之间会共享相同的层,所以打包多个模型时,总大小不是简单相加,可能会省一些空间。另外,模型包务必保留目录结构,解压时对应到内网机器上的Ollama模型目录即可。
3.4 准备离线依赖的补充策略
除了上面两件最重要的东西,有些场景还需要准备额外的离线依赖包:
- 内网机器如果也要跑Python Skill(比如OpenClaw调用Python脚本),建议在有网机器上用
pip download提前下载依赖包:
bash复制pip download -r requirements.txt -d ./pip-packages
-
内网机器如果要用Ollama的GPU推理,需要提前准备好对应版本的NVIDIA驱动安装包和CUDA toolkit(或者用container toolkit镜像方式)。
-
如果需要部署离线知识库,比如AnythingLLM或者向量数据库,它们的模型嵌入(embedding)同样要提前下载。
我的做法是将所有准备材料放到一个统一的目录里,清晰归档:
text复制offline-pack/
├── openclaw-image.tar.gz # OpenClaw容器镜像
├── ollama-models.tar.gz # Ollama模型权重
├── ollama-install.deb # Ollama安装包(内网机器安装用)
├── docker-install.deb # Docker安装包及依赖
├── pip-packages/ # Python依赖离线包
└── README.md # 部署说明
这样内网机器拿到整个目录后,照着README操作就行,不需要临时上网查任何东西。
4. 内网服务器上的完整部署实操
4.1 基础环境安装:Docker和Ollama
拿到offline-pack目录后,正式开始内网部署。第一步是先装Docker和Ollama。
Docker在内网环境下有两种安装方式。如果内网服务器系统自带包管理器且可以访问内部软件源,直接apt install docker.io即可;如果没有内部源,就用离线deb包安装:
bash复制# 使用准备好的离线deb包
sudo dpkg -i ./docker-install.deb
sudo apt-get install -f -y # 修复依赖
Ollama的离线安装更简单,官方提供了单文件安装包:
bash复制# 解压预下载的Ollama安装包并安装
tar -xzf ollama-install.tar.gz
cd ollama-install
sudo ./install.sh
# 启动Ollama服务
sudo systemctl start ollama
sudo systemctl enable ollama
安装完成后测试一下服务是否正常:
bash复制curl http://localhost:11434/api/tags
能返回JSON就说明Ollama服务已经起来了。
4.2 导入模型权重:关键目录对应关系
把模型权重导入Ollama是离线部署最容易出错的一步。一定要搞清楚模型目录的对应关系:
- 准备机器上:模型在
/usr/share/ollama/.ollama/models(root环境)或~/.ollama/models - 内网机器上:同样要放到
/usr/share/ollama/.ollama/models(如果Ollama以系统服务运行)或~/.ollama/models(用户模式)
操作步骤:
bash复制# 停止Ollama服务(避免写入冲突)
sudo systemctl stop ollama
# 解压模型包到目标目录(先备份原目录)
sudo mv /usr/share/ollama/.ollama/models /usr/share/ollama/.ollama/models.bak
sudo mkdir -p /usr/share/ollama/.ollama/models
sudo tar -xzf ollama-models.tar.gz -C /usr/share/ollama/.ollama/models/
# 启动Ollama并验证模型列表
sudo systemctl start ollama
ollama list
执行完ollama list后,你应能看到之前在准备机器上拉取的所有模型。如果列表为空,先检查目录权限和路径是否正确:
bash复制# 查看日志排查问题
journalctl -u ollama --no-pager | tail -50
注意:Ollama在导入模型时不会做任何格式转换,它只是把模型层文件加载到本地存储中。所以只要目录结构完整,
ollama list就能识别。这一点比某些推理框架的模型注册机制简单得多。
4.3 加载OpenClaw镜像并启动容器
Docker镜像的导入就简单了:
bash复制# 解压并导入镜像
gunzip -c openclaw-image.tar.gz | docker load
# 确认镜像已加载
docker images | grep openclaw
接下来启动容器。OpenClaw的容器启动参数有几个关键点:
- 端口映射:默认Web控制台在
8080端口(部分版本可能是3000或8899,以你镜像的实际端口为准) - 存储挂载:把宿主机的
~/.openclaw目录挂载到容器内,持久化配置和数据 - 网络模式:默认桥接网络,但要确保容器能访问宿主机IP的Ollama服务
启动命令示例:
bash复制# 创建配置目录
mkdir -p ~/.openclaw
# 启动容器
docker run -d \
--name openclaw \
--restart unless-stopped \
-p 8080:8080 \
-v ~/.openclaw:/root/.openclaw \
-e CLAW_LLM_PROVIDER=ollama \
-e OLLAMA_HOST=http://172.17.0.1:11434 \
openclaw/openclaw:latest
这里172.17.0.1是Docker默认桥接网络中宿主机的网关地址。如果你的Ollama监听的是局域网IP或Unix Socket,改成对应地址即可。
启动后查看日志:
bash复制docker logs -f openclaw
看到服务启动成功、Web控制台可访问的输出,就算容器层面跑通了。
4.4 OpenClaw初始化与配置修改
容器起来后,还需要对OpenClaw做初始化配置,告诉它“你的模型跑在本地Ollama上,别去调云端API”。
进入容器,找到配置文件:
bash复制docker exec -it openclaw bash
# 在容器内查看默认配置
cat ~/.openclaw/config.yaml
配置文件的核心字段包括:
- provider:模型提供方,设为
ollama - baseUrl:Ollama服务地址,比如
http://172.17.0.1:11434 - model:要调用的模型名,比如
qwen2.5:7b-instruct
一种常见的配置示例:
yaml复制llm:
provider: ollama
model: qwen2.5:7b-instruct
baseUrl: http://172.17.0.1:11434
temperature: 0.7
maxTokens: 4096
注意一个细节:OpenClaw不同版本的配置字段名可能不同。有的版本用model.provider,有的用llm.provider。建议先看镜像内自带的默认配置文件,照着格式改,而不是盲从网上的教程。
改完配置后,重启容器:
bash复制docker restart openclaw
docker logs -f openclaw
看到日志里出现模型加载成功、智能体已就绪之类的信息,就说明OpenClaw已经成功接上本地模型了。
5. 模型接入的关键细节与多模型切换
5.1 验证离线推理是否真正生效
很多人在这一步犯迷糊:OpenClaw起来了,Ollama也起来了,但发消息给智能体,它还是报错或者无响应。这时候要做一个关键的连通性验证:
bash复制# 在宿主机上直接测试Ollama推理
curl http://localhost:11434/api/generate \
-d '{"model": "qwen2.5:7b-instruct", "prompt": "你好,简短回复", "stream": false}'
# 在OpenClaw容器内测试能否访问宿主机Ollama
docker exec openclaw curl http://172.17.0.1:11434/api/tags
如果容器内curl不通,优先排查网络模式或防火墙:
bash复制# 如果用的是默认桥接网络,检查iptables规则
sudo iptables -L -n | grep 11434
# 或者改用host网络模式最省心
docker stop openclaw
docker rm openclaw
docker run -d \
--name openclaw \
--network host \
-v ~/.openclaw:/root/.openclaw \
openclaw/openclaw:latest
使用host网络模式后,容器直接共享宿主机网络,容器内访问localhost:11434就能到Ollama,省去了IP地址的麻烦。缺点是端口直接暴露在宿主机上,内网环境问题不大。
5.2 离线环境下如何切换多模型
离线部署并不等于只能用一个模型。实际使用中,我经常在轻量任务和复杂任务之间切换模型。在OpenClaw里可以通过配置文件或运行时指令切换:
yaml复制llm:
provider: ollama
model: qwen2.5:7b-instruct
# 备选模型列表
alternateModels:
- name: qwen2.5:32b-instruct-q4_K_M
maxTokens: 8192
temperature: 0.6
或者在OpenClaw的对话界面中直接用指令切换模型。我实测下来,7B模型适合日常问答、摘要、简单任务,32B模型适合代码生成、复杂推理。这样搭配的好处是:轻量任务省算力,复杂任务有深度,而且完全不需要联网。
5.3 本地模型推理的参数调优
本地模型和云端模型在推理参数上有明显差异。以我用的Qwen2.5系列为例,几个实测经验:
- temperature:0.6-0.7比较均衡,低于0.3会显得死板,高于0.9容易胡说
- top_p:0.85附近效果最好
- maxTokens:7B模型建议控制在2048-4096,32B可以到8192
- context window:如果内存充足,可以调大上下文窗口,但要注意推理速度会下降
Ollama默认参数偏保守,可以在模型配置层面覆盖:
bash复制# 通过环境变量或Modelfile调整参数
ollama create qwen2.5-7b-tuned -f Modelfile
Modelfile内容示例:
text复制FROM qwen2.5:7b-instruct
PARAMETER temperature 0.65
PARAMETER top_p 0.85
PARAMETER num_ctx 8192
PARAMETER num_gpu 24
创建好后,把OpenClaw配置里的模型名改成qwen2.5-7b-tuned即可。这样就把参数固化在模型层,不需要每次都在OpenClaw侧调整。
6. 离线部署常见问题与排查实录
6.1 问题速查表
我把实际操作中踩过的坑和排查方法整理成了表格,方便对照:
| 问题现象 | 可能原因 | 解决方案 |
|---|---|---|
| Docker load报空间不足 | 磁盘分区不够 | 清理/var/lib/docker旧数据,或迁移Docker数据目录到更大分区 |
| Ollama服务起不来 | 端口被占用或目录权限错误 | journalctl -u ollama查看日志,确认模型目录属主是ollama用户 |
| 容器内无法访问Ollama | Docker网络IP不对 | 换--network host模式,或确认宿主机防火墙放行11434 |
| Agent回复unknown model | 配置的模型名不在Ollama列表里 | 执行ollama list核对模型名称,注意标签要完全一致 |
| 推理速度极慢 | GPU未被使用 | 执行ollama ps查看是否加载到GPU,没加载则装NVIDIA container toolkit |
| Web控制台打不开 | 端口映射错误或服务未监听 | docker logs查看启动日志,确认监听端口 |
| 读取文档失败 | 容器内缺少转换依赖 | 部分文件解析需要Poppler等系统库,用Dockerfile补充依赖后重新构建镜像 |
| Windows上报Node runtime not found | 本地二进制模式未正确安装Node | 改用Docker方案,Windows上用WSL2跑Docker最稳定 |
| 文件删除报EBUSY resource busy or locked | 文件被进程占用 | 先停止OpenClaw相关进程再清理~/.openclaw目录 |
6.2 深度排查案例:Ollama模型加载失败
这个案例我印象很深。导入模型包后ollama list能看到模型,但一调用就报错。查日志发现:
text复制Error: model requires more memory than is available
原因是准备机器上的模型是用高量化参数下载的(比如Q8),内网机器显存不够加载。解决思路有两个:
- 用
ollama run时临时指定量化等级(如果模型支持) - 提前在有网环境下载低量化版本的模型,比如把Q8换成Q4_K_M
建议在准备阶段就把量化等级确定好,避免到了内网才发现模型跑不动。
6.3 深度排查案例:OpenClaw读取文档乱码
我配置完离线环境后,让智能体读取一个PDF文档,结果内容全乱码。排查后发现是容器里缺少字体和文本提取库。
解决方案是在Docker镜像基础上补充系统依赖,重新导出镜像:
dockerfile复制FROM openclaw/openclaw:latest
RUN apt-get update && apt-get install -y \
poppler-utils \
fonts-noto-cjk \
libgl1 \
&& rm -rf /var/lib/apt/lists/*
然后构建并重新导出:
bash复制docker build -t openclaw-offline:latest .
docker save openclaw-offline:latest | gzip > openclaw-offline.tar.gz
这个教训就是:不要假设默认镜像什么都能干,离线环境下一定要提前验证你的核心功能链路。 我在第二次打包时就把文档解析、代码运行、网页抓取这些常见Skill全部测了一遍,省了很多返工时间。
7. 部署后的稳定性与日常维护建议
离线环境跑起来只是第一步,长期稳定运行才是关键。这里分享几个我实际摸索出来的维护经验。
第一,模型目录要定期备份。Ollama的模型权重不常变,但一旦损坏要重新导入非常痛苦。我一般把模型目录做成一个只读挂载,宿主机上再留一份压缩包备份。
第二,OpenClaw的配置目录要做好版本管理。~/.openclaw包含了所有Agent配置、Skill、对话历史。我习惯每次改动配置后打一个tar包,或者用git管理(如果内网有git服务)。这样即使容器损坏,重建也只是几分钟的事。
第三,资源监控要到位。离线环境没有云厂商的监控面板,我写了一个简单的巡检脚本:
bash复制#!/bin/bash
# 检查Ollama服务
curl -s http://localhost:11434/api/tags > /dev/null || echo "Ollama down"
# 检查OpenClaw容器状态
docker ps | grep openclaw || echo "OpenClaw container down"
# 检查磁盘使用率
df -h / | tail -1
配合crontab每小时跑一次,有问题第一时间发现。
第四,GPU显存要盯着。多个会话同时推理时,Ollama可能把显存撑满。我在测试中发现,当显存不足时Ollama会自动把部分层放到内存,速度会突然下降不少。这时要么限制并发数,要么在OpenClaw侧做请求排队。
最后,我自己的想法是:离线部署OpenClaw这件事,真正难的其实不是安装步骤本身,而是把所有可能的联网依赖提前想清楚。模型权重、系统依赖、容器镜像、Skill需要的原生库,每一样都要在准备阶段测试到位。只要这一步做好了,后面内网部署就是解压、导入、启动三个动作而已。
如果你正在做类似的离线部署,建议第一次跑通的时候不要追求大模型和高复杂度,先用7B模型配一个最简单的Agent场景,把全链路走通,再逐步加Skill、换大模型、调参数,这样排查问题会容易得多。
