29.2 Docker 部署

生成模型:Claude Opus 4.6 (anthropic/claude-opus-4-6) Token 消耗:输入 ~200k tokens,输出 ~6k tokens(本节)


Docker 是将 OpenClaw 部署到服务器的推荐方式,特别适合 VPS 和 NAS 场景。

29.2.1 Dockerfile 分析:多阶段构建、非 root 用户

OpenClaw 的主 Dockerfile 基于 node:22-bookworm

# Dockerfile
FROM node:22-bookworm

# 安装 Bun(构建脚本需要)
RUN curl -fsSL https://bun.sh/install | bash
ENV PATH="/root/.bun/bin:${PATH}"

RUN corepack enable

WORKDIR /app

# 可选的额外 apt 包(通过构建参数控制)
ARG OPENCLAW_DOCKER_APT_PACKAGES=""
RUN if [ -n "$OPENCLAW_DOCKER_APT_PACKAGES" ]; then \
      apt-get update && \
      DEBIAN_FRONTEND=noninteractive apt-get install -y \
        --no-install-recommends $OPENCLAW_DOCKER_APT_PACKAGES && \
      apt-get clean && rm -rf /var/lib/apt/lists/*; \
    fi

# 依赖安装(利用 Docker 层缓存)
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml .npmrc ./
COPY ui/package.json ./ui/package.json
COPY patches ./patches
COPY scripts ./scripts
RUN pnpm install --frozen-lockfile

# 构建
COPY . .
RUN OPENCLAW_A2UI_SKIP_MISSING=1 pnpm build
ENV OPENCLAW_PREFER_PNPM=1
RUN pnpm ui:build

ENV NODE_ENV=production

# 安全加固:非 root 用户运行
RUN chown -R node:node /app
USER node

# 默认命令:启动 Gateway
CMD ["node", "openclaw.mjs", "gateway", "--allow-unconfigured"]

关键设计决策:

决策
原因

node:22-bookworm 而非 alpine

需要完整的 glibc 和编译工具链(Sharp 图像库等原生模块)

安装 Bun

部分构建脚本使用 Bun 运行

OPENCLAW_PREFER_PNPM=1

ARM/Synology 架构上 Bun 可能失败,强制用 pnpm 构建 UI

先 COPY 依赖文件再 COPY 源码

利用 Docker 层缓存,依赖不变时跳过 pnpm install

USER node

以非 root 用户(uid 1000)运行,减少容器逃逸风险

--allow-unconfigured

允许无配置启动,方便首次运行

衍生解释 — Docker 层缓存

Docker 镜像由多个只读层组成。每条 RUN/COPY 指令创建一层。如果某层的输入没有变化,Docker 会复用缓存而不重新执行。将 package.jsonpnpm-lock.yaml 先单独 COPY 并 install,意味着只要依赖不变,即使源码改变也不需要重新安装依赖——这在开发迭代中能节省大量构建时间。

29.2.2 docker-compose.yml 解析

docker-compose.yml 定义了两个服务:

Gateway 服务是核心,长期运行。CLI 服务是按需使用的交互式容器,通过 docker compose run openclaw-cli chat 启动聊天。

关键配置解析:

配置
说明

init: true

使用 tini 作为 PID 1 进程,正确传递信号和回收僵尸进程

restart: unless-stopped

崩溃自动重启,除非手动停止

--bind lan

绑定到局域网地址(0.0.0.0),容器内必须如此才能从宿主访问

Volume 挂载

配置和工作区目录持久化到宿主机

BROWSER: echo

CLI 容器中禁止打开浏览器(容器内无 GUI)

衍生解释 — init: true 与 PID 1 问题

在 Linux 容器中,CMD 指定的进程直接作为 PID 1 运行。PID 1 有特殊责任:回收孤儿进程、正确响应 SIGTERM 信号。Node.js 进程不是为此设计的——它不会回收子进程的退出状态,也可能不会优雅响应信号。init: true 会在容器中注入 tini(一个极小的 init 进程)作为 PID 1,它负责信号转发和僵尸进程回收。

29.2.3 Docker 沙箱(Dockerfile.sandbox

OpenClaw 的代码执行沙箱可以运行在独立的 Docker 容器中:

这个沙箱容器极其精简——只有基础 CLI 工具,没有 Node.js 或其他运行时。AI 代理的 exec 工具在此容器中执行命令,与宿主系统完全隔离。

另外还有 Dockerfile.sandbox-browser,在沙箱基础上添加了浏览器自动化工具(Playwright/Puppeteer),用于需要浏览器能力的代理任务。

29.2.4 环境变量配置

Docker 部署中最重要的环境变量:

环境变量
说明
默认值

OPENCLAW_GATEWAY_TOKEN

Gateway 认证令牌

(无,需设置)

OPENCLAW_GATEWAY_PASSWORD

Gateway 密码认证

(无)

OPENCLAW_GATEWAY_BIND

绑定地址

lan

OPENCLAW_GATEWAY_PORT

Gateway 端口

18789

OPENCLAW_BRIDGE_PORT

Bridge 端口

18790

OPENCLAW_CONFIG_DIR

配置目录映射

(需设置)

OPENCLAW_WORKSPACE_DIR

工作区目录映射

(需设置)

API 密钥可以通过环境变量传递,也可以写在挂载的配置文件中。


本节小结

  1. Dockerfile 使用 node:22-bookworm,安装 Bun + pnpm,利用层缓存优化构建,以非 root 用户运行。

  2. docker-compose 定义两个服务:长期运行的 Gateway 和按需使用的 CLI,均使用 tini 作为 init 进程。

  3. 沙箱容器基于 debian:bookworm-slim,仅包含基础 CLI 工具,为代理的 exec 工具提供安全隔离环境。

  4. 环境变量控制认证、网络绑定和目录映射,是容器化部署的主要配置方式。

Last updated