Appearance
Docker 是 OpenClaw 的可选部署方式,适合需要隔离 Gateway 环境、在无本地安装的主机上运行,或验证容器化流程的用户。本文覆盖从镜像构建(本地或预构建)、引导配置、Control UI 访问、频道添加,到 Agent 沙箱启用、存储持久化、环境变量说明、健康检查及常见错误(如 OOM-killed、配对失败、DNS 解析失败)的排查方法。先在 Docker Desktop 或 Docker Engine + Compose v2 环境准备好至少 2 GB 内存;设置脚本 scripts/docker/setup.sh 自动完成大部分步骤。
OpenClaw Docker 容器化部署:docker-compose 完整配置指南
Docker 是可选的。仅在你需要容器化 Gateway 或验证 Docker 流程时使用。
Docker 适合我吗?
- 适合:你需要一个隔离的一次性 Gateway 环境,或想在不做本地安装的主机上运行 OpenClaw。
- 不适合:你在自己的机器上运行,想要最快的开发循环。直接使用常规安装流程即可。
- 沙箱说明:默认沙箱后端使用 Docker,但沙箱默认关闭,且不需要整个 Gateway 运行在 Docker 中。SSH 和 OpenShell 沙箱后端也可用。详见 Sandboxing。
前置条件
- Docker Desktop(或 Docker Engine)+ Docker Compose v2
- 至少 2 GB RAM 用于镜像构建(
pnpm install在 1 GB 主机上可能因 OOM 被 kill,退出码 137) - 足够的磁盘空间用于镜像和日志
- 如果在 VPS/公网主机上运行,请参阅 Security hardening for network exposure,特别是 Docker
DOCKER-USER防火墙策略。
容器化 Gateway
构建镜像
从仓库根目录运行安装脚本:
bash
./scripts/docker/setup.sh这会在本地构建 Gateway 镜像。如需使用预构建镜像:
bash
export OPENCLAW_IMAGE="ghcr.io/openclaw/openclaw:latest"
./scripts/docker/setup.sh预构建镜像发布在 GitHub Container Registry。常用标签:main、latest、<version>(如 2026.2.26)。
完成引导配置
安装脚本会自动运行引导配置,它会:
- 提示输入 Provider API keys
- 生成 Gateway 令牌并写入
.env - 通过 Docker Compose 启动 Gateway
在安装过程中,预启动的引导配置和配置写入通过 openclaw-gateway 直接运行。openclaw-cli 是 Gateway 容器已存在后使用的命令工具。
打开 Control UI
在浏览器中打开 http://127.0.0.1:18789/,将配置的共享密钥粘贴到 Settings 中。设置脚本默认将令牌写入 .env;如果你切换容器配置为密码认证,则使用该密码。
需要再次查看 URL?
bash
docker compose run --rm openclaw-cli dashboard --no-open配置频道(可选)
使用 CLI 容器添加消息频道:
bash
# WhatsApp(二维码)
docker compose run --rm openclaw-cli channels login
# Telegram
docker compose run --rm openclaw-cli channels add --channel telegram --token "<token>"
# Discord
docker compose run --rm openclaw-cli channels add --channel discord --token "<token>"手动流程
如果你倾向于自己逐步执行而不使用安装脚本:
bash
docker build -t openclaw:local -f Dockerfile .
docker compose run --rm --no-deps --entrypoint node openclaw-gateway \
dist/index.js onboard --mode local --no-install-daemon
docker compose run --rm --no-deps --entrypoint node openclaw-gateway \
dist/index.js config set --batch-json '[{"path":"gateway.mode","value":"local"},{"path":"gateway.bind","value":"lan"},{"path":"gateway.controlUi.allowedOrigins","value":["http://localhost:18789","http://127.0.0.1:18789"]}]'
docker compose up -d openclaw-gateway注意:从仓库根目录运行 docker compose。如果启用了 OPENCLAW_EXTRA_MOUNTS 或 OPENCLAW_HOME_VOLUME,安装脚本会写入 docker-compose.extra.yml;使用 -f docker-compose.yml -f docker-compose.extra.yml 引入它。
注意:由于 openclaw-cli 共享 openclaw-gateway 的网络命名空间,它是启动后的工具。在 docker compose up -d openclaw-gateway 之前,通过 openclaw-gateway 配合 --no-deps --entrypoint node 运行引导配置和安装时的配置写入。
环境变量
安装脚本接受以下可选环境变量:
| 变量 | 用途 |
|---|---|
OPENCLAW_IMAGE | 使用远程镜像而非本地构建 |
OPENCLAW_IMAGE_APT_PACKAGES | 构建时安装额外 apt 包(空格分隔) |
OPENCLAW_IMAGE_PIP_PACKAGES | 构建时安装额外 Python 包(空格分隔) |
OPENCLAW_EXTENSIONS | 构建时预安装扩展依赖(空格分隔名称) |
OPENCLAW_EXTRA_MOUNTS | 额外宿主机绑定挂载(逗号分隔 source:target[:opts]) |
OPENCLAW_HOME_VOLUME | 在命名 Docker volume 中持久化 /home/node |
OPENCLAW_SANDBOX | 启用沙箱引导(1、true、yes、on) |
OPENCLAW_SKIP_ONBOARDING | 跳过交互式引导步骤(1、true、yes、on) |
OPENCLAW_DOCKER_SOCKET | 覆盖 Docker socket 路径 |
OPENCLAW_DISABLE_BONJOUR | 禁用 Bonjour/mDNS 广播(Docker 下默认为 1) |
OPENCLAW_DISABLE_BUNDLED_SOURCE_OVERLAYS | 禁用内置插件源码绑定挂载覆盖 |
OTEL_EXPORTER_OTLP_ENDPOINT | 用于 OpenTelemetry 导出的共享 OTLP/HTTP 收集器端点 |
OTEL_EXPORTER_OTLP_*_ENDPOINT | 信号特定的 OTLP 端点(trace、metrics、logs) |
OTEL_EXPORTER_OTLP_PROTOCOL | OTLP 协议覆盖。当前仅支持 http/protobuf |
OTEL_SERVICE_NAME | OpenTelemetry 资源的服务名称 |
OTEL_SEMCONV_STABILITY_OPT_IN | 选择最新的实验性 GenAI 语义属性 |
OPENCLAW_OTEL_PRELOADED | 当已有预加载的 OpenTelemetry SDK 时跳过启动第二个 SDK |
官方 Docker 镜像不附带 Homebrew。在引导过程中,如果在没有 brew 的 Linux 容器中运行,OpenClaw 会隐藏仅限 brew 的技能依赖安装器;这些依赖需要通过自定义镜像或手动安装提供。对于 Debian 包可用的依赖,在镜像构建时使用 OPENCLAW_IMAGE_APT_PACKAGES。旧名称 OPENCLAW_DOCKER_APT_PACKAGES 仍被接受。对于 Python 依赖,使用 OPENCLAW_IMAGE_PIP_PACKAGES。这会在镜像构建时运行 python3 -m pip install --break-system-packages,因此请固定包版本并使用你信任的包索引。
维护者可以通过将一个插件源码目录挂载到其打包的源码路径上来测试内置插件源码,例如 OPENCLAW_EXTRA_MOUNTS=/path/to/fork/extensions/synology-chat:/app/extensions/synology-chat:ro。该挂载的源码目录会覆盖同一插件 ID 对应的已编译 /app/dist/extensions/synology-chat 包。
可观测性
OpenTelemetry 从 Gateway 容器向外导出到你的 OTLP 收集器。不需要发布 Docker 端口。如果本地构建镜像并希望镜像中包含 OpenTelemetry 导出器,请包含其运行时依赖:
bash
export OPENCLAW_EXTENSIONS="diagnostics-otel"
export OTEL_EXPORTER_OTLP_ENDPOINT="http://otel-collector:4318"
export OTEL_SERVICE_NAME="openclaw-gateway"
./scripts/docker/setup.sh打包的 Docker 安装中,在启用导出前,从 ClawHub 安装官方 @openclaw/diagnostics-otel 插件。自定义源码构建的镜像仍然可以使用 OPENCLAW_EXTENSIONS=diagnostics-otel 包含本地插件源码。要启用导出,在配置中允许并启用 diagnostics-otel 插件,然后设置 diagnostics.otel.enabled=true 或使用 OpenTelemetry export 中的配置示例。收集器认证头通过 diagnostics.otel.headers 配置,而不是 Docker 环境变量。
Prometheus 指标使用已经发布的 Gateway 端口。安装 clawhub:@openclaw/diagnostics-prometheus,启用 diagnostics-prometheus 插件,然后抓取:
text
http://<gateway-host>:18789/api/diagnostics/prometheus该路由受 Gateway 认证保护。不要暴露单独的公共 /metrics 端口或未经身份验证的反向代理路径。参见 Prometheus metrics。
健康检查
容器探针端点(无需认证):
bash
curl -fsS http://127.0.0.1:18789/healthz # 存活检查
curl -fsS http://127.0.0.1:18789/readyz # 就绪检查Docker 镜像内置了 HEALTHCHECK,会定时请求 /healthz。如果持续失败,Docker 会将容器标记为 unhealthy,编排系统可以重启或替换它。
带认证的深度健康快照:
bash
docker compose exec openclaw-gateway node dist/index.js health --token "$OPENCLAW_GATEWAY_TOKEN"LAN 与 loopback
scripts/docker/setup.sh 默认设置 OPENCLAW_GATEWAY_BIND=lan,使宿主机可以通过 http://127.0.0.1:18789 访问 Docker 发布的 Gateway 端口。
lan(默认):宿主机浏览器和宿主机 CLI 可以访问发布的 Gateway 端口。loopback:只有容器网络命名空间内的进程才能直接访问 Gateway。
注意:在 gateway.bind 中使用绑定模式值(lan / loopback / custom / tailnet / auto),不要用 0.0.0.0 或 127.0.0.1 这样的主机别名。
宿主机本地 Provider
当 OpenClaw 在 Docker 中运行时,容器内的 127.0.0.1 是容器本身,而不是你的宿主机。对于运行在宿主机上的 AI Provider,使用 host.docker.internal:
| Provider | 宿主机默认 URL | Docker 设置 URL |
|---|---|---|
| LM Studio | http://127.0.0.1:1234 | http://host.docker.internal:1234 |
| Ollama | http://127.0.0.1:11434 | http://host.docker.internal:11434 |
捆绑的 Docker 设置使用这些宿主机 URL 作为 LM Studio 和 Ollama 的引导默认值,并且 docker-compose.yml 将 host.docker.internal 映射到 Docker 的宿主机网关(适用于 Linux Docker Engine)。Docker Desktop 在 macOS 和 Windows 上已经提供相同的主机名。
宿主机服务还必须监听 Docker 可访问的地址:
bash
lms server start --port 1234 --bind 0.0.0.0
OLLAMA_HOST=0.0.0.0:11434 ollama serve如果你使用自己的 Compose 文件或 docker run 命令,请自行添加相同的主机映射,例如 --add-host=host.docker.internal:host-gateway。
Bonjour / mDNS
Docker 桥接网络通常无法可靠地转发 Bonjour/mDNS 多播(224.0.0.251:5353)。因此,捆绑的 Compose 设置默认 OPENCLAW_DISABLE_BONJOUR=1,这样 Gateway 不会在桥接丢弃多播流量时崩溃循环或反复重启广播。
对 Docker 主机使用已发布的 Gateway URL、Tailscale 或广域 DNS-SD。仅当使用主机网络、macvlan 或其他已知 mDNS 多播可用的网络时,设置 OPENCLAW_DISABLE_BONJOUR=0。
有关问题和故障排查,请参见 Bonjour discovery。
存储和持久化
Docker Compose 将 OPENCLAW_CONFIG_DIR 绑定挂载到 /home/node/.openclaw,将 OPENCLAW_WORKSPACE_DIR 绑定挂载到 /home/node/.openclaw/workspace,将 OPENCLAW_AUTH_PROFILE_SECRET_DIR 绑定挂载到 /home/node/.config/openclaw,以便这些路径在容器替换后仍能保留。当任何变量未设置时,捆绑的 docker-compose.yml 回退到 ${HOME},或者当 HOME 本身也丢失时回退到 /tmp。这防止了 docker compose up 在裸环境上发出空源卷规范。
挂载的配置目录是 OpenClaw 保存以下内容的地方:
openclaw.json— 行为配置agents/<agentId>/agent/auth-profiles.json— 存储的 Provider OAuth/API-key 认证.env— 环境变量支持的运行时密钥,如OPENCLAW_GATEWAY_TOKEN
认证配置文件密钥目录保存用于 OAuth 支持认证配置文件的本地加密密钥。请将其与 Docker 宿主机状态一起保存,但不要与 OPENCLAW_CONFIG_DIR 混合。
已安装的可下载插件将其包状态存储在挂载的 OpenClaw home 下,因此插件安装记录和包根在容器替换后仍能保留。Gateway 启动不会生成捆绑插件的依赖树。
VM 部署的完整持久化细节,详见 Docker VM Runtime - What persists where。
磁盘增长热点: 注意 media/、会话 JSONL 文件、cron/runs/*.jsonl、已安装的插件包根,以及 /tmp/openclaw/ 下的滚动文件日志。
Shell 助手(可选)
安装 ClawDock 可以更方便地进行日常 Docker 管理:
bash
mkdir -p ~/.clawdock && curl -sL https://raw.githubusercontent.com/openclaw/openclaw/main/scripts/clawdock/clawdock-helpers.sh -o ~/.clawdock/clawdock-helpers.sh
echo 'source ~/.clawdock/clawdock-helpers.sh' >> ~/.zshrc && source ~/.zshrc如果你从旧的 scripts/shell-helpers/clawdock-helpers.sh 原始路径安装了 ClawDock,请重新运行上面的安装命令,以便你的本地帮助文件跟踪新的位置。
然后使用 clawdock-start、clawdock-stop、clawdock-dashboard 等命令。运行 clawdock-help 查看所有命令。参见 ClawDock 获取完整帮助指南。
为 Docker Gateway 启用 Agent 沙箱
bash
export OPENCLAW_SANDBOX=1
./scripts/docker/setup.sh自定义 socket 路径(例如 rootless Docker):
bash
export OPENCLAW_SANDBOX=1
export OPENCLAW_DOCKER_SOCKET=/run/user/1000/docker.sock
./scripts/docker/setup.sh脚本只有在沙箱前置条件满足后才会挂载 docker.sock。如果沙箱初始化无法完成,脚本会将 agents.defaults.sandbox.mode 重置为 off。Codex 代码模式回合仍然受限于 Codex workspace-write,在 OpenClaw 沙箱激活时;不要将宿主机 Docker socket 挂载到 Agent 沙箱容器中。
自动化 / CI(非交互式)
使用 -T 禁用 Compose 伪 TTY 分配:
bash
docker compose run -T --rm openclaw-cli gateway probe
docker compose run -T --rm openclaw-cli devices list --json共享网络安全说明
openclaw-cli 使用 network_mode: "service:openclaw-gateway",因此 CLI 命令可以通过 127.0.0.1 访问 Gateway。将此视为共享信任边界。Compose 配置在 openclaw-gateway 和 openclaw-cli 上都移除了 NET_RAW/NET_ADMIN 并启用了 no-new-privileges。
Docker Desktop DNS 在 openclaw-cli 中失败
某些 Docker Desktop 配置在共享网络的 openclaw-cli 边车中 DNS 查找失败(在丢弃 NET_RAW 后),这会在 npm 支持的命令(如 openclaw plugins install)中显示为 EAI_AGAIN。为正常 Gateway 操作保留默认的 hardening Compose 文件。以下本地覆盖会通过恢复 Docker 的默认能力来放宽 CLI 容器的安全态势,因此仅用于需要包注册表访问的一次性 CLI 命令,不要作为默认 Compose 调用:
bash
printf '%s\n' \
'services:' \
' openclaw-cli:' \
' cap_drop: !reset []' \
> docker-compose.cli-no-dropped-caps.local.yml
docker compose -f docker-compose.yml -f docker-compose.cli-no-dropped-caps.local.yml run --rm openclaw-cli plugins install <package>如果你已经创建了一个长期运行的 openclaw-cli 容器,请使用相同的覆盖重新创建它。docker compose exec 和 docker exec 无法更改已创建容器的 Linux 能力。
权限问题和 EACCES
镜像以 node(uid 1000)运行。如果在 /home/node/.openclaw 上遇到权限错误,确保宿主机绑定挂载的目录归 uid 1000 所有:
bash
sudo chown -R 1000:1000 /path/to/openclaw-config /path/to/openclaw-workspace同样的不匹配也会显示为插件警告,例如 blocked plugin candidate: suspicious ownership (... uid=1000, expected uid=0 or root),随后 plugin present but blocked。这意味着进程 uid 与挂载的插件目录所有者不一致。首选以默认 uid 1000 运行容器并修复绑定挂载所有权。仅在你打算长期以 root 身份运行 OpenClaw 时,才将 /path/to/openclaw-config/npm 更改为 root:root。
加快重建速度
合理安排 Dockerfile 中的层顺序以利用缓存,避免在 lockfile 未变化时重新运行 pnpm install:
dockerfile
FROM node:24-bookworm
RUN curl -fsSL https://bun.sh/install | bash
ENV PATH="/root/.bun/bin:${PATH}"
RUN corepack enable
WORKDIR /app
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml .npmrc ./
COPY ui/package.json ./ui/package.json
COPY scripts ./scripts
RUN pnpm install --frozen-lockfile
COPY . .
RUN pnpm build
RUN pnpm ui:install
RUN pnpm ui:build
ENV NODE_ENV=production
CMD ["node","dist/index.js"]进阶容器选项
默认镜像以安全优先,以非 root 的 node 用户运行。如需功能更完整的容器:
- 持久化
/home/node:export OPENCLAW_HOME_VOLUME="openclaw_home" - 内置系统依赖:
export OPENCLAW_IMAGE_APT_PACKAGES="git curl jq" - 内置 Python 依赖:
export OPENCLAW_IMAGE_PIP_PACKAGES="requests==2.32.5 humanize==4.14.0" - 内置 Playwright Chromium:
export OPENCLAW_INSTALL_BROWSER=1 - 或将 Playwright 浏览器安装到持久化卷中:bash
docker compose run --rm openclaw-cli \ node /app/node_modules/playwright-core/cli.js install chromium - 持久化浏览器下载:使用
OPENCLAW_HOME_VOLUME或OPENCLAW_EXTRA_MOUNTS。OpenClaw 自动检测 Docker 映像中 Playwright 管理的 Chromium(Linux)。
OpenAI Codex OAuth(无头 Docker)
如果在向导中选择了 OpenAI Codex OAuth,它会打开一个浏览器 URL。在 Docker 或无头环境中,复制你最终落地的完整重定向 URL,粘贴回向导以完成认证。
基础镜像元数据
主 Docker 运行时镜像使用 node:24-bookworm-slim,并包含 tini 作为入口点 init 进程(PID 1),以确保僵尸进程被回收并且信号在长期运行的容器中正确处理。它发布 OCI 基础镜像注解,包括 org.opencontainers.image.base.name、org.opencontainers.image.source 等。Node 基础镜像摘要通过 Dependabot Docker 基础镜像 PR 刷新;发布版本不运行发行版升级层。参见 OCI image annotations。
在 VPS 上运行?
参见 Hetzner (Docker VPS) 和 Docker VM Runtime,了解共享 VM 部署步骤,包括二进制内置、持久化和更新流程。
Agent 沙箱
当 agents.defaults.sandbox 启用且使用 Docker 后端时,Gateway 在隔离的 Docker 容器中运行 Agent 工具执行(shell、文件读写等),而 Gateway 本身保留在宿主机上。这在不容器化整个 Gateway 的情况下为不受信任或多租户的 Agent 会话提供了硬隔离。
沙箱范围可以是按 Agent(默认)、按会话或共享。每个范围都有自己的工作区挂载在 /workspace。你还可以配置允许/拒绝工具策略、网络隔离、资源限制和浏览器容器。
完整配置、镜像、安全说明和多 Agent 配置,参见:
- Sandboxing — 完整沙箱参考
- OpenShell — 沙箱容器的交互式 shell 访问
- Multi-Agent Sandbox and Tools — 按 Agent 覆盖配置
快速启用
json5
{
agents: {
defaults: {
sandbox: {
mode: "non-main", // off | non-main | all
scope: "agent", // session | agent | shared
},
},
},
}构建默认沙箱镜像(从源码检出):
bash
scripts/sandbox-setup.sh对于没有源码检出的 npm 安装,参见 Sandboxing § Images and setup 了解内联 docker build 命令。
故障排查
镜像缺失或沙箱容器无法启动
使用 scripts/sandbox-setup.sh(源码检出)或来自 Sandboxing § Images and setup(npm 安装)的内联 docker build 命令构建沙箱镜像,或将 agents.defaults.sandbox.docker.image 设置为你的自定义镜像。容器按需在每个会话自动创建。
沙箱中的权限错误
将 docker.user 设置为与挂载工作区所有权匹配的 UID:GID,或对工作区目录执行 chown。
沙箱中找不到自定义工具
OpenClaw 使用 sh -lc(登录 shell)运行命令,会 source /etc/profile 并可能重置 PATH。在 docker.env.PATH 中添加自定义工具路径,或在 Dockerfile 的 /etc/profile.d/ 下添加脚本。
镜像构建时 OOM killed(exit 137)
VM 需要至少 2 GB RAM。使用更大的机器规格后重试。
Control UI 中显示 Unauthorized 或需要配对
获取新的 dashboard 链接并审批浏览器设备:
bash
docker compose run --rm openclaw-cli dashboard --no-open
docker compose run --rm openclaw-cli devices list
docker compose run --rm openclaw-cli devices approve <requestId>Gateway 目标显示 ws://172.x.x.x 或 Docker CLI 配对报错
重置 Gateway 模式和绑定:
bash
docker compose run --rm openclaw-cli config set --batch-json '[{"path":"gateway.mode","value":"local"},{"path":"gateway.bind","value":"lan"}]'
docker compose run --rm openclaw-cli devices list --url ws://127.0.0.1:18789常见问题
Docker 部署 OpenClaw 时如何设置本地 AI Provider?
在 Docker 中,容器内的 127.0.0.1 指向容器自身而非宿主机。对于运行在宿主机上的 Provider(如 LM Studio、Ollama),使用 host.docker.internal 替换 127.0.0.1。例如 http://host.docker.internal:1234。同时确保宿主机服务绑定到 0.0.0.0(例如 lms server start --port 1234 --bind 0.0.0.0)。Docker Desktop 和 Linux Docker Engine 均支持 host.docker.internal。
OpenClaw 容器启动失败,提示 OOM killed(exit 137)怎么解决?
镜像构建阶段 pnpm install 需要至少 2 GB 内存。如果使用 1 GB 的小型 VM,升级到更大内存规格后重新运行 ./scripts/docker/setup.sh。如果使用预构建镜像,OOM 可能发生在其他进程,检查宿主机可用内存。
为什么 Control UI 显示 Unauthorized,或 CLI 配对报错?
可能是令牌不匹配或设备未审批。运行 docker compose run --rm openclaw-cli dashboard --no-open 获取最新 dashboard URL 和令牌。然后使用 docker compose run --rm openclaw-cli devices list 查看待审批的请求,再用 devices approve <requestId> 完成配对。如果网关绑定模式不正确,重置为 local 和 lan。