☰
物理隔离内网离线部署OpenClaw:环境筑基与容器化实践指南
2026/10/17 5:03:46 网站建设 项目流程

去年我们把一套开源智能体平台 OpenClaw(社区里都叫它“小龙虾”)部署进了一个内外网物理隔离的企业内网,整个过程踩了不少坑,也沉淀了一套可以照抄的离线部署流程。这篇是系列第一篇,先讲环境筑基的完整路径:资源盘点、离线物料准备、操作系统初始化、容器运行时安装,再到数据库和中间件编排,最后把服务跑起来做健康检查。

如果你手头也有一台不能访问外网的服务器,想部署这类智能体服务,这篇应该能帮你省掉大量试错时间。适合运维工程师、后端开发,以及所有要在隔离网络里交付应用的同学阅读,哪怕你以前没碰过离线部署,按步骤走也能推得动。

1. 写在前面:这个系列到底要做什么

1.1 先认识一下 OpenClaw(小龙虾)

OpenClaw 是一个开源的智能体运行平台,核心能力是让开发者把大模型、工具调用、知识库和自动化流程串联起来,形成可对话、可执行任务的智能助手。社区里叫它“小龙虾”,因为 Claw 这个词本身就带“钳子”的意思,配合上这只开源小动物的吉祥物形象,大家叫着叫着就顺口了。

在实际使用中,OpenClaw 能做的不只是聊天。它可以对接内部工单系统、查询数据库、调用企业内部的 API,也可以把多个模型服务统一封装成一个入口。很多团队把它当作企业内部的“AI 中控台”来用。不过这些都是后话,这一篇我们先把地基打好——让 OpenClaw 在一台干干净净的物理隔离服务器上跑起来。

1.2 为什么要在物理隔离环境里部署

有些企业的内网承载着研发资产、客户数据或生产系统,出于数据安全要求,这个网络段和互联网之间没有物理链路,数据只能靠受控的介质或专用设备单向导入。好处是攻击面被大幅压缩,但代价也显而易见:所有软件包、依赖、镜像、模型文件,都必须在互联网侧提前准备好,再搬到内网装。

这意味着部署方式和普通的云服务器完全不同。你不能直接在机器上执行 yum install 或 pip install 去拉取最新版本,所有依赖必须提前锁版本、验完整性,再离线导入。这也是为什么我把“环境筑基”作为系列第一篇文章——物料没备齐,后面一切免谈。

1.3 系列文章的规划与本文范围

这个系列我会按实际交付顺序来写:

  • 第 1 篇(本文):环境筑基。覆盖资源盘点、离线包制作、系统初始化、容器运行时、数据库与缓存组件、基础验证。
  • 第 2 篇:模型接入。讨论内网环境下如何部署推理服务,以及模型权重的离线导入方案。
  • 第 3 篇:数据集与知识库。讲解结构化数据、文档类知识库如何接入 OpenClaw。
  • 第 4 篇:Agent 与工具链。让智能体真正调用企业内部系统和 API。
  • 第 5 篇:运维与监控。跑起来只是开始,后续还有日志、告警、备份和版本升级。

本文聚焦第 1 篇,最终目标是把 OpenClaw 服务跑起来,并确认它对外提供正常响应。

2. 环境勘察:先别急着装系统

2.1 资源盘点:服务器、存储、网络

部署前先做资源盘点,这一步看似基础,但决定后续方案选型。我们这次用的是一台普通机架式服务器,双路 CPU、64GB 内存、4TB 机械硬盘。如果你的环境要跑本地大模型,建议内存至少 32GB,有 GPU 更好;如果只是把 OpenClaw 作为智能体调度框架,后端模型服务跑在别的机器上,那么 8 核 16GB 也能起步,但别指望并发了。

磁盘规划也很关键。OpenClaw 自身代码不大,但日志、向量数据库、上传文件、模型缓存都会持续增长。我建议至少准备 500GB 独立数据分区,不要和系统分区混在一起。网络方面要记录服务器的管理 IP、业务 IP,以及规划好对外提供服务的端口段。

2.2 物理隔离环境的特点与部署策略

物理隔离环境最大的特点是:内网侧完全无法直接访问互联网,所有外发流量被物理切断。所以部署策略必须调整为“互联网侧集中准备、内网侧离线交付”。

比较理想的方式是在互联网侧准备一台同架构、同版本操作系统的中转机,把所有安装包下载好、验证好,再通过受控介质导入内网。为什么要强调同架构同版本?因为二进制包和动态库依赖与操作系统高度绑定,你在 CentOS 7 上下的包,放到某个较新的发行版上大概率装不上,反之亦然。

2.3 规划目录、端口与权限

我习惯在部署前先定好三件事:目录结构、端口规划、运行账号。

目录结构建议这样划分:

  • /opt/openclaw:放置 OpenClaw 程序文件和离线安装包
  • /data/openclaw:数据目录,包括数据库文件、向量索引、上传文件、日志
  • /data/offline_pkgs:离线安装包暂存区,装完后可保留备份

端口规划:OpenClaw 主服务默认监听 8000;PostgreSQL 用 5432;Redis 用 6379。如果这几个端口和内网其他系统冲突,提前改掉,不要等启动时报错再回头处理。

运行账号方面,我强烈建议创建专用账号,比如 openclaw,并授权它对 /data/openclaw 的读写权限。不要用 root 跑服务,后续排障会非常被动。

3. 离线物料准备:隔离环境最难的一步

3.1 在互联网侧准备安装源

离线部署的成败,九成取决于物料清单是否完整。我通常按类别来准备,每类单独建目录:

  • 操作系统 ISO 与补丁包
  • Python 解释器安装包
  • Python 第三方库(pip 离线包)
  • 容器运行时(以 Docker 为例)的 RPM 包及依赖
  • Docker 镜像(PostgreSQL、Redis、OpenClaw 本体)
  • 后续文章要用的模型权重文件(本篇不展开)

以 Python 依赖为例,我会在互联网中转机上用一个干净的虚拟环境确定版本清单,然后统一执行:

pip download -r requirements.txt -d /data/offline_pkgs/pip_packages

如果不确定依赖范围,可以先在虚拟环境里把 OpenClaw 装一遍,再通过 pip freeze 导出完整列表。比手工一个个找要靠谱得多。Docker 镜像用 docker pull 拉取后,再通过 docker save 导成 tar 包:

docker pull postgres:16 docker pull redis:7.2 docker pull openclaw/openclaw:latest docker save -o postgres16.tar postgres:16 docker save -o redis72.tar redis:7.2 docker save -o openclaw.tar openclaw/openclaw:latest

注意私有镜像仓库的场景,你需要在中转机上先 docker login,再 pull,否则会卡在认证环节。

3.2 打包与完整性校验

所有安装包准备完毕后,不要急着搬。先给整个目录生成校验文件:

cd /data/offline_pkgs find . -type f -exec sha256sum {} \; > SHA256SUMS.txt

这个文件务必和安装包一起带到内网,安装前要逐个核对。隔离网络里没有外网源可以重新下载,一旦某个包传坏了,你只能再跑一趟物理流程,耗时又耗力。我见过有人因为省事跳过校验,结果内网装到一半发现某个 RPM 包损坏,整个项目停摆两天。

3.3 摆渡进内网:介质选择与规范

离线物料导入内网的方式一般是移动硬盘或单向导入设备。这里有一条铁律:介质必须是专用介质,不能在内外网之间混用。每次拷贝前先查一次病毒,导入后不要随便再拿回互联网侧使用。

到内网后,把离线包目录完整解压到 /data/offline_pkgs,然后立刻做校验:

sha256sum -c SHA256SUMS.txt

所有输出为 OK 再继续。如果出现 FAILED,请直接从源头重新拷贝,不要尝试“应该没问题”这种侥幸验证。

4. 操作系统层环境初始化

4.1 最小化安装与基础配置

进内网后,第一件事是安装操作系统。建议选择与中转机完全一致的发行版与主版本,安装时选最小化安装,不带图形界面,这样可以减少后续补丁数量和解耦难度。

系统装完后,依次完成三件基础配置:

  • 设置静态 IP、掩码、网关和 DNS(内网 DNS,不填外网地址)
  • 修改主机名,写入 /etc/hosts,确保本机名可解析
  • 创建 openclaw 用户并配置 sudo 权限

还有一项容易忽略:关闭或按需配置防火墙。物理隔离内网不是没有攻击风险,所以我不会建议直接 disable 防火墙,而是把需要用到的端口显式放行。前面规划的 8000、5432、6379 以及 SSH 管理端口,放行即可。

4.2 内网时间同步与 DNS

隔离环境没有互联网 NTP 服务器可同步,但时间偏差会导致日志时间错乱、JWT 过期、数据库主从异常等诡异问题。正确做法是使用内网已有的 NTP 服务器:

systemctl enable --now chronyd

然后编辑 /etc/chrony.conf,把 server 指向内网 NTP 地址。如果内网连 NTP 都没有,至少手动把时间校准到和公司标准时间源一致,并把它写进运维文档。

DNS 配置同理,指向内网 DNS 服务器。有些内网环境连 DNS 也没有,那就把涉及的主机名全部写进 /etc/hosts,保证 OpenClaw 和数据库、Redis 之间可以互相通过主机名访问,而不是依赖 IP 裸连。

4.3 搭建本地软件源

如果你的发行版是 RHEL/CentOS 系,强烈建议把离线 RPM 包做成本地 yum 源,后面装系统级依赖会省很多事。先把所有 RPM 包放到 /data/offline_pkgs/rpm_packages,然后:

yum install -y createrepo createrepo /data/offline_pkgs/rpm_packages

再新建一个 repo 文件,比如 /etc/yum.repos.d/local.repo:

[local] name=Local Offline Repo baseurl=file:///data/offline_pkgs/rpm_packages enabled=1 gpgcheck=0

这样后续通过 yum install 安装任何内网已有的软件,都会优先从本地源解决,不会因为尝试访问外网而卡住。

5. 安装 Python 运行时与容器运行时

5.1 安装 Python 解释器

OpenClaw 依赖 Python 环境。如果你的离线包是官方提供的 Python 源码包,可以通过编译安装。这里提醒一句,编译前确认系统已经具备 gcc、make、zlib-devel、openssl-devel 等基础依赖,否则会在 make 阶段报各种头文件缺失的错。

编译安装的经典流程:

tar xzf Python-3.11.9.tgz cd Python-3.11.9 ./configure --prefix=/usr/local/python311 --enable-optimizations make -j$(nproc) make install

装完后把 Python 路径加入环境变量,并把 pip 源指向本地:

export PATH=/usr/local/python311/bin:$PATH pip config set global.index-url file:///data/offline_pkgs/pip_packages

用本地目录做 pip 源时,建议额外配置 trusted-host 与 find-links 参数,避免 pip 因为“不是合法 http 源”而拒绝使用。

5.2 安装 Docker 容器运行时

为了避免系统依赖地狱,OpenClaw 的数据库、缓存,甚至主服务,我都建议以容器方式运行。离线安装 Docker 的方式比较简单:把准备好的 RPM 包全部放进本地源,然后:

yum install -y docker-ce docker-ce-cli containerd.io systemctl enable --now docker

启动后验证一下:

docker version

这里要特别检查 Server 段是否正常输出。如果 Server 为空,大概率是 Docker 守护进程没起来或者 selinux 拦截了。执行 journalctl -u docker 查一下日志,解决问题后再继续。

5.3 搭建内网私有的镜像加载通道

Docker 装好后,暂时还没有远程镜像仓库可用。不过我们可以先把离线镜像导入本机:

docker load -i postgres16.tar docker load -i redis72.tar docker load -i openclaw.tar

加载完成后用 docker images 确认镜像列表。如果后续有多台机器需要部署,可以考虑内网起一个 registry:2 容器作为私有镜像仓库,把镜像 push 进去,其他节点从它拉取。单一主机部署的话,直接用 docker load 就够了,没必要额外引入组件。

6. 编排 OpenClaw 三件套:数据库、缓存与服务

6.1 用 Compose 定义服务

OpenClaw 的完整运行需要主服务、数据库和缓存三个组件。我用 Docker Compose 来编排,所有配置写在 /opt/openclaw/docker-compose.yml 里。这样最直观,也方便后续扩展。

一个基础版编排文件大致长这样:

version: "3.8" services: db: image: postgres:16 container_name: openclaw-db environment: POSTGRES_USER: openclaw POSTGRES_PASSWORD: your_strong_password POSTGRES_DB: openclaw volumes: - /data/openclaw/postgres:/var/lib/postgresql/data restart: always redis: image: redis:7.2 container_name: openclaw-redis command: ["redis-server", "--appendonly", "yes", "--requirepass", "your_redis_password"] volumes: - /data/openclaw/redis:/data restart: always openclaw: image: openclaw/openclaw:latest container_name: openclaw-server ports: - "8000:8000" environment: DATABASE_URL: postgresql://openclaw:your_strong_password@db:5432/openclaw REDIS_URL: redis://:your_redis_password@redis:6379/0 volumes: - /data/openclaw/data:/data depends_on: - db - redis restart: always

注意,这里面的密码和连接串要按你的实际情况替换。我通常会把敏感信息放到 .env 文件里,并设置 .gitignore,不让它进入版本库。

6.2 初始化数据库

首次启动前,需要确认数据库容器初始化没有报错。执行:

docker compose up -d db docker compose logs db

看到数据库启动完成并接受连接的日志后,再检查数据库是否能正常登录。这一步如果跳过,后面 OpenClaw 主服务启动时会反复报数据库连不上的错。

如果 OpenClaw 提供数据库迁移脚本,在这一步执行迁移。一般来说会在初次启动时自动迁移,但我更倾向于手动确认迁移表已经生成,避免服务启动半途失败。

6.3 配置 OpenClaw 服务并启动

数据库和 Redis 就绪后,启动主服务:

docker compose up -d

服务和容器全部起来后,先看容器状态:

docker compose ps

再盯前几分钟的日志:

docker compose logs -f openclaw

如果日志里出现“Initialization completed”或者“Server started”之类的输出,说明主服务已经起来了。接下来做基础验证。

7. 基础验证与连通性检查

7.1 服务启动与健康检查

容器起来不代表服务真的可用。我会习惯性地从三个层面验证:

  • 进程层面:docker compose ps 确认三个容器都是 Up 状态
  • 端口层面:ss -lntp | grep 8000 确认端口在监听
  • 健康接口:curl 本机地址确认 HTTP 响应

健康检查命令可以这样写:

curl -i http://127.0.0.1:8000/health

不同版本的健康检查路径可能不同,如果 /health 不存在,就看 openclaw 容器日志里打印的完整访问路径。能返回 200 说明服务核心链路没问题。

7.2 Web 控制台与 API 验证

OpenClaw 通常提供 Web 控制台。在能访问这台服务器的内网机器上,打开浏览器输入 http://<服务器内网IP>:8000 看看能不能出来登录页或控制台首页。这一步不只是验证网络连通性,也是确认静态资源是否正确加载。

如果页面能打开但接口报错,多半是 Web 端和 API 之间走的是相对路径,需要确认反向代理或入口配置。暂时没有代理的话,直接用 IP 访问即可。

7.3 内网访问与访问控制

基础验证通过后,要收紧入口。物理隔离内网不等于完全可信,访问控制仍然要做。最简单的方式是通过防火墙限制只有指定网段可以访问 8000 端口,再配合反向代理做 TLS 和访问认证。

我建议把 8000 端口从所有网段放行改为仅放行业务网段,管理网段只放开 SSH。这样万一服务器被攻破,凭据泄露的影响范围也不会立刻扩散到全部内网。

8. 踩坑实录与避坑指南

8.1 离线依赖不全的排查思路

离线部署最容易遇到的问题是“缺包”。我们现在有本地 yum 源和 pip 目录,缺包时不要猜,先看报错信息里的包名和依赖版本,再到中转机上下载对应 RPM 或 pip 包,补进离线目录后重新 createrepo 或更新 pip 目录索引。

一个降低缺包概率的技巧:在互联网侧中转机上先按照真实流程完整安装一遍,把系统记录下来的实际依赖全部导出,然后再离线搬到内网。这比照着文档清单一个个找要全面得多。

8.2 版本差异导致的兼容性问题

我在另一个项目里遇到过离线编译的 Python 到内网跑不起来的情况,最终排查发现是内网系统的 glibc 版本比中转机低,二进制运行时报 GLIBC 版本不存在的错。从那以后,我养成了一个习惯:所有第三方组件优先用容器,能用 RPM 就不用源码编译,必须编译的尽量选纯 Python 包或者 statically linked 的二进制。

如果你也遇到类似的 GLIBC 报错,最简单的解法是换镜像版本或者换构建环境,而不是在内网机器上硬着头皮重编系统库。版本兼容性问题的排查往往比功能性 bug 更费时,建议多留一点缓冲时间。

8.3 数据目录权限与 SELinux 拦截

容器运行 Postgres 和 Redis 时,数据目录的权限问题非常常见。容器内进程以特定 UID 运行,如果宿主机的数据目录权限是 755 且属主是 root,数据库容器可能无法写入,日志里会报 permission denied。

最简单的处理方式是把数据目录属主改成对应的容器 UID,或者直接设置为 777(测试环境可以,生产不建议)。如果你这台机器开启 SELinux,还要记得给容器数据卷挂载目录加上正确的 SELinux 标签,否则就算权限是 777,一样会被拦截。这一点很容易被忽视,报错形式也极其隐蔽。

8.4 一次完整启动失败的处理顺序

主服务启动失败时,我一般按这个顺序排查:

  • 先看容器状态和退出码,定位是哪个组件的问题
  • 再按顺序看 db、redis、openclaw 的日志
  • 数据库日志关注鉴权和初始化,Redis 关注密码与持久化目录
  • 最后才怀疑 OpenClaw 本身,多半是连接串或配置项拼写问题

按照从底层到上层的顺序排查,比东翻西找高效得多。特别是三件套架构里,底层服务没就绪时,上层应用会反复重试,日志里的报错容易误导人。

我个人这一年多在隔离环境里折腾下来,最大的体会是:物料清单和校验流程才是环境筑基阶段真正的核心资产,而不是安装命令本身。安装命令是死的,任何一个细心的运维都能照抄,但在没有外网兜底的环境里,能不能一次把所有依赖带全、带对,全靠前期的准备工作是否扎实。

最后再分享一个小技巧:在互联网侧准备离线包时,我会保留一份和交付内容完全一致的目录快照,标注好每个包的来源、版本和用途。这样内网部署如果中途出现问题,我可以快速回溯是哪一步的准备不完整,而不是重新拉一遍所有版本去猜。环境筑基的基础打牢之后,后面模型接入、知识库数据、Agent 工具链才能在这台机器上稳稳地长出来。

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

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

立即咨询