OpenClaw:面向业务流程的智能体操作系统架构解析
1. OpenClaw 不是“另一个 Agent 框架”,而是面向真实业务流的智能体操作系统
你点开 GitHub 上 OpenClaw 的 README,第一眼看到的不是“支持多模型”“内置 20+ Skill”,而是一张带虚线边框的三层架构图:最上层写着Business Flow Layer,中间是Agent Runtime Layer,底层标着Infrastructure Abstraction Layer。这和 LangChain、LlamaIndex 一上来就讲 Chain、Tool、Retriever 的路径截然不同——OpenClaw 从诞生第一天起,就拒绝把自己定义成“LLM 调用胶水”,它要解决的是一个更硬、更痛、也更被忽视的问题:当一个企业想把 AI 真正嵌进采购审批、客服工单、金融研报生成这些具体业务环节里时,谁来管理那个“会自己查数据库、填表格、发消息、等反馈、再决策”的完整闭环?
这不是靠写几个 Python 函数就能搞定的事。我去年在一家做跨境供应链 SaaS 的公司落地过类似需求:客户希望系统能自动识别邮件里的付款申请,提取金额、币种、供应商名称,比对 ERP 中的合同条款,若金额超阈值则触发飞书审批流,审批通过后调用银企直连接口打款,并将回执截图发回原邮件。整个流程涉及 7 个异构系统、4 种认证方式(OAuth2、Basic Auth、Token Header、Cookie Session)、3 类数据格式(HTML 邮件正文、XML ERP 接口、PDF 回执),且每个环节都可能失败、超时、返回非预期结构。我们最初用 LangChain + 自定义 Tool 写了 300 行代码,跑通一次 demo 后,运维同事直接摇头:“这玩意儿上线后怎么监控?哪个环节卡住了?重试几次?失败了通知谁?日志在哪看?配置改个 API 地址得重启整个服务?”——问题不在 LLM,而在缺乏一个能承载业务语义、可编排、可观测、可治理的运行时环境。
OpenClaw 正是为此而生。它的核心设计哲学非常朴素:把 Agent 当作一个有生命周期、有状态、有依赖、有资源约束的操作系统进程来管理,而不是一个无状态的 HTTP 请求处理器。它不关心你用 Qwen 还是 DeepSeek,但强制要求你声明 Skill 的输入 Schema(比如{"invoice_id": "str", "currency": "str"})、输出 Schema({"status": "success|failed", "payment_id": "str"})、超时时间(timeout: 120s)、重试策略(retry: {max_attempts: 3, backoff: exponential})以及依赖的外部服务(requires: ["erp-api", "payment-gateway"])。这些声明不是文档注释,而是会被 OpenClaw Runtime 解析、校验、注入到执行上下文中的元数据。当你在 YAML 文件里写下:
name: finance_payment_approval description: 自动完成付款审批与支付 trigger: type: webhook path: /webhook/invoice skills: - name: extract_invoice_info input: {"email_body": "{{ .trigger.payload }}"} - name: validate_contract_terms input: {"invoice_data": "{{ .extract_invoice_info.output }}"} requires: ["erp-api"] - name: initiate_payment input: {"validated_data": "{{ .validate_contract_terms.output }}"} requires: ["payment-gateway"] timeout: 180OpenClaw 并不会立刻去调用模型。它先启动一个轻量级的Flow Orchestrator实例,这个实例会:
- 预加载所有声明的 Skill 插件(动态链接库或容器镜像);
- 根据
requires字段向内置的服务注册中心发起健康检查,确认erp-api和payment-gateway服务在线且响应正常; - 为整个 Flow 分配唯一的
flow_id,并初始化一个内存中状态机(State Machine),其初始状态为WAITING_FOR_TRIGGER; - 将该 Flow 的元数据(包括所有 Skill 的 Schema、超时、重试策略)持久化到本地 SQLite 或远程 Redis,作为后续故障恢复的依据。
这才是“架构设计”的起点:OpenClaw 的架构不是围绕 LLM 构建的,而是围绕“业务流程的确定性执行”构建的。它把模型调用降级为一个可插拔的、带严格契约的子任务(Skill),把复杂度转移到了流程编排、依赖治理、状态追踪和错误恢复上。这也是为什么你在热搜词里反复看到 “openclaw gateway 启动又自动关闭”、“openclaw 页面打不开”、“agent failed before reply: http 401”——这些问题几乎全部指向其底层运行时(Runtime)的初始化失败、服务发现异常或认证链断裂,而非模型本身。理解这一点,是搞懂 OpenClaw 的第一把钥匙。它不是一个让你快速写个 ChatBot 的玩具,而是一个需要你像部署一个微服务一样去规划、配置、监控和运维的生产级基础设施。
2. 三层架构拆解:从用户请求到模型推理的全链路穿透
OpenClaw 的官方架构图常被简化为三个水平分层,但这种静态视图极易误导。真正理解其运行原理,必须沿着一个具体的请求(例如:用户在 Web UI 点击“执行财务审批 Flow”)走一遍完整的垂直调用栈。我将其拆解为Trigger → Gateway → Orchestrator → Skill → Model五个关键跃迁点,每个跃迁都对应着架构中一层的核心职责与技术实现细节。
2.1 Trigger 层:业务事件的统一入口与协议适配器
Trigger 层是 OpenClaw 的“皮肤”,它不处理任何业务逻辑,只负责一件事:将五花八门的外部事件,标准化为内部可识别的Event对象。这解释了为何热搜词中充斥着“openclaw接入飞书”、“openclaw接入微信”、“openclaw接入chrome”。OpenClaw 本身不内置飞书 SDK 或微信公众号 API,它提供的是一个高度抽象的Trigger Plugin接口规范:
type Trigger interface { // 初始化,加载配置(如飞书AppID、密钥) Init(config map[string]interface{}) error // 启动监听,将外部事件转为内部Event Start() error // 停止监听 Stop() error } type Event struct { ID string // 全局唯一事件ID Type string // 事件类型,如 "feishu.message" Timestamp time.Time // 事件发生时间 Payload map[string]interface{} // 原始有效载荷,已做基础清洗 Metadata map[string]string // 附加元数据,如 "source: feishu", "tenant_id: abc123" }当你执行openclaw trigger install feishu时,OpenClaw 并没有下载一个“飞书插件包”,而是从其官方插件仓库(一个 Git 仓库)拉取一个符合上述接口的 Go 模块源码,然后在本地用go build -buildmode=plugin编译成.so动态链接库。这个.so文件里封装了:
- 飞书开放平台的 OAuth2 授权码换取 Access Token 流程;
- 对
/bot/v2/hook/xxxWebhook URL 的签名验证逻辑(使用飞书提供的encrypt_key); - 将飞书推送的 JSON 消息体(含
msg_type,content,open_id)解析、脱敏(如隐藏手机号)、并映射到标准Event.Payload结构。
提示:很多“页面打不开”或“gateway 启动失败”的问题,根源在于 Trigger 插件初始化时无法连接到其依赖的第三方服务。例如,飞书插件需要访问
https://open.feishu.cn,如果服务器 DNS 配置错误或防火墙策略禁止出站 HTTPS,Init()就会超时失败,导致整个 Gateway 进程崩溃退出。排查时务必先openclaw logs --follow --component=trigger-feishu查看插件自身的日志,而非只盯着主进程日志。
2.2 Gateway 层:流量网关与安全边界守门人
Gateway 是 OpenClaw 的“大门”,它位于 Trigger 层之后、Orchestrator 层之前,承担着三重关键职责:协议转换、身份认证、流量路由。它不是一个简单的反向代理,而是一个内嵌了完整认证鉴权引擎的独立服务。
其核心组件是一个基于 Envoy Proxy 定制的OpenClaw Gateway。与 Nginx 或 Traefik 不同,它在 HTTP/HTTPS 流量进入时,会执行以下深度检查:
- JWT Token 解析与校验:所有来自 Web UI、CLI 或外部系统的请求,都必须携带一个由 OpenClaw Admin Service 签发的 JWT。Gateway 会验证其签名(使用 Admin Service 的公钥)、有效期(
exp)、签发者(iss)以及最关键的scope声明。例如,一个用于触发财务 Flow 的请求,其 JWT 的scope必须包含flow:finance_payment_approval:execute。 - RBAC 权限匹配:解析出 JWT 中的
user_id和scopes后,Gateway 会查询内置的权限数据库(SQLite),确认该用户是否被授权执行此特定 Flow。这实现了细粒度的权限控制,而非简单的“管理员/普通用户”二分法。 - 流量路由决策:根据请求路径(如
/api/v1/flows/finance_payment_approval/trigger)和 JWT 中的tenant_id(租户标识),Gateway 将请求精准路由到对应租户的 Orchestrator 实例。在多租户部署中,这是隔离不同客户数据的关键。
注意:
agent failed before reply: http 401: invalid authentication这个高频错误,90% 的情况是 JWT 过期或签名无效。但有一个极其隐蔽的坑:OpenClaw Admin Service 默认使用HS256算法签名,其密钥(admin.jwt.secret)在首次启动时自动生成并写入config/admin.yaml。如果你手动修改了该文件或在 Docker 部署时未通过-e ADMIN_JWT_SECRET=xxx注入密钥,Admin Service 重启后会生成新密钥,导致所有旧 JWT 失效。此时必须清空浏览器 Cookie 或重新登录获取新 Token。
2.3 Orchestrator 层:业务流程的“中央处理器”与状态大脑
如果说 Gateway 是门卫,那么 Orchestrator 就是整个 OpenClaw 系统的“CPU”和“内存”。它是纯内存驻留的 Go 进程,不直接暴露给外部网络,只与 Gateway 和 Skill Runner 通信。其核心是一个基于Actor 模型实现的状态机引擎。
当你通过 Gateway 触发一个 Flow 时,Orchestrator 会为该次执行创建一个唯一的FlowInstanceActor。这个 Actor 的生命周期完全由其内部状态驱动:
| 状态 (State) | 触发条件 | 下一状态 | 关键动作 |
|---|---|---|---|
PENDING | Flow 被触发,尚未开始执行 | RUNNING | 加载 Flow 定义,初始化Context(含flow_id,trigger_event,start_time) |
RUNNING | 当前 Skill 正在执行 | WAITING_FOR_SKILL或FAILED | 调用 Skill Runner,传入Context和当前 Skill 的输入参数;设置超时定时器 |
WAITING_FOR_SKILL | Skill Runner 返回结果 | RUNNING(下一个 Skill)或COMPLETED或FAILED | 解析 Skill 输出,根据 Flow YAML 中的next或on_failure字段决定跳转;更新Context中的output字段 |
COMPLETED | 所有 Skill 执行完毕且成功 | TERMINATED | 将最终Context.Output序列化为 JSON,通过Result Publisher发布到消息队列(如 Redis Pub/Sub)供 Web UI 订阅;记录审计日志 |
FAILED | Skill 执行超时、返回错误或重试耗尽 | TERMINATED | 执行预设的on_failure处理逻辑(如发送告警邮件);记录详细错误堆栈 |
这个状态机的设计,使得 OpenClaw 具备了强大的可观测性。你可以随时执行openclaw flow status --id <flow_id>,Orchestrator 会直接从内存中读取该FlowInstanceActor 的当前State和Context,告诉你“现在卡在validate_contract_terms这一步,已重试 2 次,最后一次错误是HTTP 503 from ERP API”。这远比在一堆模型日志里 grep “error” 高效得多。
2.4 Skill 层:模型调用的“标准化插座”与能力单元
Skill 是 OpenClaw 架构中承上启下的关键枢纽。它既不是裸露的 LLM API 调用,也不是一个黑盒大模型服务,而是一个严格定义了输入/输出契约、具备独立生命周期、可被 Orchestrator 精确调度的计算单元。这正是 OpenClaw 区别于其他框架的核心创新。
一个 Skill 的物理形态可以是:
- 本地进程:一个用 Python 编写的脚本,遵循 OpenClaw 的 Skill Protocol(一个简单的 stdin/stdout JSON 协议)。Orchestrator 通过
os/exec启动它,将Context序列化为 JSON 写入 stdin,然后从 stdout 读取结果。 - Docker 容器:一个打包好的镜像,其入口点是一个符合 Skill Protocol 的二进制程序。Orchestrator 通过
docker run启动容器,并挂载Context作为环境变量或文件。 - 远程 gRPC 服务:一个长期运行的 gRPC Server,Orchestrator 作为 Client 与其通信。这种方式适合 CPU 密集型 Skill(如图像识别),可实现资源隔离。
无论哪种形态,Skill 的输入(Input)和输出(Output)都必须严格匹配其在 Flow YAML 中声明的 Schema。Orchestrator 在调用前会进行强类型校验。例如,如果extract_invoice_infoSkill 声明其输入 Schema 为{"email_body": "str"},而你传入了一个{"email_body": 123}(整数),Orchestrator 会在调用前就返回ValidationError,根本不会让请求到达 Skill。这杜绝了因数据类型错乱导致的模型静默失败。
实操心得:很多用户抱怨 “openclaw skill 执行失败”,往往是因为忽略了 Schema 校验。例如,Qwen 的
chat接口期望messages是一个数组,但你的 Skill 脚本可能错误地传入了一个对象{...}。正确的做法是在 Skill 脚本开头就做assert isinstance(input['messages'], list),并在捕获异常时返回符合 OpenClaw 错误格式的 JSON:{"error": {"code": "INVALID_INPUT", "message": "messages must be a list"}}。Orchestrator 会将此错误原样透传,方便你精准定位。
2.5 Model 层:真正的“大脑”,但被彻底解耦与封装
Model 层是 OpenClaw 架构中唯一不归其直接管理的部分。OpenClaw 本身不包含任何模型权重,不提供模型训练能力,也不硬编码任何模型 API。它只是一个“指挥官”,负责告诉 Skill “现在该调用哪个模型,用什么参数,处理什么数据”。
一个典型的 Skill 调用模型的流程如下:
- Skill 进程启动,从环境变量(如
MODEL_ENDPOINT=http://llm-service:8000/v1/chat/completions)或配置文件中读取目标模型服务地址。 - Skill 根据 Flow YAML 中的
input模板(如"{{ .trigger.payload.email_body }}")和自身逻辑,构造一个符合目标模型 API 规范的请求体(如 OpenAI 格式或 Ollama 格式)。 - Skill 发起 HTTP/gRPC 请求到模型服务。
- Skill 解析模型返回的原始 JSON,提取出
choices[0].message.content,并将其包装成 OpenClaw 要求的{"output": {...}}格式,写入 stdout 或 gRPC 响应。
这种彻底的解耦带来了巨大灵活性。你可以:
- 在同一个 Flow 中,让
extract_invoice_info调用本地llama.cpp(低延迟),让generate_payment_summary调用云端Qwen(高精度); - 为
initiate_paymentSkill 配置一个fallback_model,当主模型超时时,自动降级到一个更小、更快的模型; - 使用
openclaw skill switch --name qwen --model deepseek命令,在不修改 Flow YAML 的情况下,一键切换整个系统所依赖的底层大模型。
这也解释了热搜词中 “openclaw可以同时接多个大模型吗” 的答案:当然可以,而且这是它的默认工作模式。OpenClaw 不是“一个模型的框架”,而是“一个管理多个模型调用的框架”。
3. 运行时核心机制:状态持久化、错误恢复与资源治理
OpenClaw 的“运行原理”之所以能支撑起复杂的业务流程,其背后是一套精密的运行时(Runtime)保障机制。这些机制不像架构图那样显眼,却是系统稳定性的基石。它们共同回答了三个灵魂拷问:如果机器宕机了,流程会不会丢?如果某个 Skill 卡死,系统怎么知道?如果一百个 Flow 同时执行,会不会把服务器拖垮?下面逐一拆解。
3.1 状态持久化:从内存到磁盘的双重保险
Orchestrator 的FlowInstanceActor 默认驻留在内存中,这保证了极致的执行速度。但内存是易失的。OpenClaw 采用了一种混合持久化策略,确保即使在最坏情况下(如进程崩溃、服务器断电),业务流程也不会丢失。
第一道防线:内存快照(In-Memory Snapshot)Orchestrator 会定期(默认每 30 秒)将所有处于RUNNING或WAITING_FOR_SKILL状态的FlowInstance的当前State和Context序列化为一个紧凑的二进制快照(Snapshot),并写入一个环形缓冲区(Ring Buffer)内存区域。这个操作是原子的、无锁的,开销极小。当 Orchestrator 进程意外退出后重启,它会首先从这个环形缓冲区中加载最新的快照,将所有未完成的 Flow 实例恢复到崩溃前一刻的状态,然后继续执行。这解决了“秒级”故障的恢复问题。
第二道防线:磁盘持久化(Disk Persistence)对于需要更强保障的场景(如金融交易类 Flow),OpenClaw 支持开启--persistence-mode=full。此时,Orchestrator 会在每个关键状态跃迁点(如从PENDING到RUNNING,从WAITING_FOR_SKILL到RUNNING)将FlowInstance的完整状态写入一个持久化存储。默认存储是 SQLite 数据库(data/persistence.db),其表结构经过精心设计:
CREATE TABLE flow_instances ( id TEXT PRIMARY KEY, tenant_id TEXT NOT NULL, flow_name TEXT NOT NULL, state TEXT NOT NULL CHECK(state IN ('PENDING','RUNNING','WAITING_FOR_SKILL','COMPLETED','FAILED','TERMINATED')), context BLOB NOT NULL, -- 存储序列化的 Context 结构 created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); CREATE INDEX idx_tenant_state ON flow_instances(tenant_id, state); CREATE INDEX idx_updated_at ON flow_instances(updated_at);这个设计的关键在于context BLOB字段。它存储的是 Go 的gob编码后的Context对象,包含了从触发事件到当前步骤的所有输入、输出、临时变量和元数据。这意味着,即使 SQLite 数据库本身损坏,只要data/persistence.db文件还在,你就可以用openclaw flow recover --id <flow_id>命令,从磁盘中精确还原出该 Flow 的每一个中间状态,手动干预或重放。
经验分享:我在部署一个对接银行核心系统的 Flow 时,曾遇到过一个诡异问题:Flow 在
initiate_payment步骤总是卡住,日志显示 “Waiting for skill response…”,但 Skill 进程明明在运行。后来发现是 Skill 进程的 stdout 缓冲区未刷新,导致 Orchestrator 一直收不到 EOF。启用--persistence-mode=full后,我可以在数据库里查到该 Flow 的state是WAITING_FOR_SKILL,context里清楚地记录着它正在等待initiate_payment的输出。这让我能迅速定位到是 Skill 的 I/O 问题,而非 Orchestrator 的 Bug。
3.2 错误恢复:超时、重试与熔断的三级防御体系
在分布式系统中,失败是常态。OpenClaw 将错误处理视为一等公民,构建了一个覆盖全链路的防御体系。
第一级:Skill 级超时(Per-Skill Timeout)这是最细粒度的控制。每个 Skill 在 Flow YAML 中都可以声明timeout字段。Orchestrator 在启动 Skill 进程或容器时,会为其设置一个SIGALRM信号(Linux)或context.WithTimeout(Go)。一旦超时,Orchestrator 会立即kill -9该进程,并将状态置为FAILED。这个超时是硬性的,不依赖 Skill 自身的逻辑。
第二级:Flow 级重试(Per-Flow Retry)当一个 Skill 执行失败(返回非 0 状态码或错误 JSON),Orchestrator 不会立刻放弃。它会检查该 Skill 的retry策略。例如:
- name: call_erp_api retry: max_attempts: 3 backoff: exponential jitter: trueOrchestrator 会按照指数退避(Exponential Backoff)算法进行重试:第一次失败后等 1 秒,第二次失败后等 2 秒,第三次失败后等 4 秒。jitter: true会在此基础上加入一个随机抖动(0-1 秒),避免大量 Flow 同时重试造成雪崩。每次重试,Context中都会增加一个retry_count字段,供 Skill 脚本判断是否是重试请求。
第三级:系统级熔断(System-Level Circuit Breaker)这是最高级别的保护,作用于整个 OpenClaw 集群。Orchestrator 内置一个Service Health Monitor,它会持续统计所有 Skill 对某个外部服务(如erp-api)的调用成功率。当成功率在 1 分钟内低于 80%,熔断器就会“跳闸”,将该服务标记为UNHEALTHY。此后,所有试图调用erp-api的 Flow,都会被 Orchestrator 立即拦截,并返回CIRCUIT_BREAKER_OPEN错误,不再发起任何实际请求。熔断器会进入HALF_OPEN状态,每隔 30 秒允许一个试探性请求,如果成功,则恢复服务;否则继续保持OPEN。
注意事项:“openclaw 为什么会延迟” 这个热搜问题,很多时候就是熔断器在起作用。当你的 ERP 系统响应变慢,
call_erp_apiSkill 的成功率下降,熔断器打开,所有后续 Flow 都会立刻失败,从而避免了大量请求堆积在 ERP 前端,形成恶性循环。这不是 Bug,而是 Feature。你需要做的是优化 ERP 接口性能,或者调整熔断阈值(--circuit-breaker-failure-threshold=0.7)。
3.3 资源治理:CPU、内存与并发的硬性围栏
OpenClaw 运行时会主动监控和限制自身对系统资源的消耗,防止一个失控的 Flow 拖垮整个服务器。
CPU 与内存限制:Orchestrator 进程本身可以通过--cpu-limit=2和--memory-limit=4G参数启动,这会利用 Linux 的cgroups机制,为整个 OpenClaw 进程组设置硬性上限。更重要的是,它会对每个 Skill 的执行施加独立限制:
- 对于本地进程 Skill:Orchestrator 会调用
setrlimit(RLIMIT_CPU, ...)和setrlimit(RLIMIT_AS, ...),直接限制该进程的 CPU 时间和虚拟内存大小。 - 对于 Docker 容器 Skill:Orchestrator 会自动在
docker run命令中添加--cpus="1.0"和--memory="2g"参数。
并发控制:OpenClaw 通过一个全局的Concurrency Limiter来控制同一时刻最多有多少个 Flow Instance 在执行。这个 Limiter 是一个基于令牌桶(Token Bucket)算法的 Go channel。默认令牌数为runtime.NumCPU() * 2。当一个 Flow 被触发,Orchestrator 会尝试从 channel 中receive一个令牌;如果 channel 为空,该 Flow 就会进入QUEUED状态,等待其他 Flow 完成并send回令牌。你可以通过--concurrency-limit=10来手动设置这个上限。
这个设计的意义在于,它让 OpenClaw 的资源消耗变得完全可预测。你可以精确地计算出:一台 8 核 32G 的服务器,设置--concurrency-limit=16,每个 Skill 平均消耗 1G 内存,那么这台服务器理论上可以稳定支撑 16 个并发 Flow,而不会出现 OOM Kill。这为容量规划提供了坚实的依据。
4. 从零部署实战:Docker Compose 与 Windows 本地开发双路径详解
理论终需落地。OpenClaw 的部署方式多样,但最主流、最稳定的方案是 Docker Compose。而针对开发者,Windows 本地调试则是绕不开的一环。下面我将基于最新版(2026.2.5)的官方发布,手把手带你完成两种路径的部署,并揭示其中那些只有踩过坑才知道的细节。
4.1 Docker Compose 部署:生产环境的黄金标准
Docker Compose 部署的核心思想是:将 OpenClaw 的各个组件(Gateway、Orchestrator、Admin、Database)拆分为独立的、可水平扩展的容器,并通过一个docker-compose.yml文件统一编排。这是群晖 NAS 用户、云服务器用户以及企业 IT 部门的首选。
首先,创建一个项目目录,例如openclaw-prod,并在其中创建docker-compose.yml文件。以下是经过生产环境验证的精简版配置:
version: '3.8' services: # 1. PostgreSQL 数据库:存储用户、权限、Flow 定义等元数据 db: image: postgres:15-alpine restart: unless-stopped environment: POSTGRES_DB: openclaw POSTGRES_USER: openclaw POSTGRES_PASSWORD: your_strong_password_here volumes: - ./data/db:/var/lib/postgresql/data networks: - openclaw-net # 2. Redis 缓存:用于消息队列(Flow 结果发布)、Session 存储、熔断器状态 redis: image: redis:7-alpine restart: unless-stopped command: redis-server --save 60 1 --loglevel warning volumes: - ./data/redis:/data networks: - openclaw-net # 3. OpenClaw Admin Service:提供 Web UI、API Key 管理、用户权限配置 admin: image: openclaw/admin:v2026.2.5 restart: unless-stopped environment: DB_URL: postgresql://openclaw:your_strong_password_here@db:5432/openclaw REDIS_URL: redis://redis:6379/0 ADMIN_JWT_SECRET: your_very_secret_jwt_key_here SERVER_PORT: 8080 depends_on: - db - redis ports: - "8080:8080" networks: - openclaw-net # 4. OpenClaw Gateway:流量入口,处理认证与路由 gateway: image: openclaw/gateway:v2026.2.5 restart: unless-stopped environment: ADMIN_SERVICE_URL: http://admin:8080 ORCHESTRATOR_SERVICE_URL: http://orchestrator:9000 SERVER_PORT: 8000 depends_on: - admin - orchestrator ports: - "8000:8000" - "8443:8443" # 如果需要 HTTPS networks: - openclaw-net # 5. OpenClaw Orchestrator:核心运行时,执行 Flow orchestrator: image: openclaw/orchestrator:v2026.2.5 restart: unless-stopped environment: DB_URL: postgresql://openclaw:your_strong_password_here@db:5432/openclaw REDIS_URL: redis://redis:6379/0 ADMIN_SERVICE_URL: http://admin:8080 PERSISTENCE_MODE: full CONCURRENCY_LIMIT: 8 CPU_LIMIT: "4.0" MEMORY_LIMIT: "8g" depends_on: - db - redis - admin networks: - openclaw-net # 6. 可选:Nginx 反向代理,用于 HTTPS 终止和域名绑定 nginx: image: nginx:alpine restart: unless-stopped volumes: - ./nginx.conf:/etc/nginx/nginx.conf - ./ssl:/etc/nginx/ssl ports: - "80:80" - "443:443" depends_on: - gateway networks: - openclaw-net networks: openclaw-net: driver: bridge关键配置说明与避坑指南:
- 密码与密钥:
POSTGRES_PASSWORD和ADMIN_JWT_SECRET是绝对的安全红线。切勿使用默认值或弱密码。ADMIN_JWT_SECRET必须是至少 32 位的随机字符串,建议用openssl rand -hex 32生成。这两个值一旦写入,就决定了整个系统的安全基线。 - 网络隔离:所有服务都在
openclaw-net这个自定义桥接网络中。这意味着gateway容器可以通过http://admin:8080直接访问admin容器,而无需暴露admin的端口到宿主机。这是 Docker 最佳实践,也是openclaw gateway 启动又自动关闭问题的常见原因——如果gateway的ADMIN_SERVICE_URL写成了http://localhost:8080,它就无法在容器网络中找到admin服务,导致初始化失败。 - 持久化卷:
./data/db和./data/redis是两个至关重要的卷。它们确保了数据库和 Redis 的数据在容器重启后不会丢失。部署前务必确保宿主机上的./data目录存在且有足够空间。我曾见过因为磁盘满导致 PostgreSQL 容器反复崩溃的案例。 - 资源限制:
orchestrator容器的CPU_LIMIT和MEMORY_LIMIT环境变量,会直接传递给其内部的cgroups控制器。这比在docker run时加--cpus和--memory更可靠,因为它作用于进程内部的子进程(即 Skill 进程)。
部署命令极其简单:
# 1. 创建数据目录 mkdir -p ./data/db ./data/redis # 2. 启动所有服务(后台运行) docker-compose up -d # 3. 查看日志,确认所有服务都健康 docker-compose logs -f --tail=50 # 4. 访问 Web UI(假设宿主机 IP 是 192.168.1.100) # 浏览器打开 http://192.168.1.100:8080首次访问 Admin UI 时,系统会引导你创建第一个管理员账户。记住这个账户,它是后续所有权限配置的起点。
4.2 Windows 本地开发:WSL2 + VS Code 的高效组合
对于开发者而言,在 Windows 上直接运行 OpenClaw 的原生二进制文件是可行的,但体验远不如在 Linux 环境下流畅。最佳实践是:使用 WSL2(Windows Subsystem for Linux)作为开发环境,VS Code 作为 IDE,实现无缝的本地调试。
第一步:安装与配置 WSL2
- 以管理员身份打开 PowerShell,依次执行:
dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart - 重启电脑。
- 下载并安装 WSL2 内核更新包 。
- 在 PowerShell 中执行
wsl --set-default-version 2。 - 从 Microsoft Store 安装 Ubuntu 22.04。
第二步:在 WSL2 中安装 OpenClaw
# 1. 更新系统 sudo apt update && sudo apt upgrade -y # 2. 安装必要依赖 sudo apt install -y curl wget git build-essential # 3. 下载并安装 OpenClaw CLI(适用于 Linux x86_64) curl -L https://github.com/openclaw/cli/releases/download/v2026.2.5/openclaw-linux-amd64 -o /usr/local/bin/openclaw sudo chmod