sycnnj
发布于 2026-02-11 / 1,530 阅读
0
1

NAS Docker 环境下 OpenClaw 一键自动化部署脚本以及部署教程

关键词 (Keywords): OpenClaw 部署 (OpenClaw Deployment), 群晖 Docker (Synology Docker), Macvlan 网络配置 (Macvlan Networking), OpenClaw 1006 错误修复 (Fix OpenClaw 1006 Error), 自建网关管理 (Self-hosted Gateway Management)

内容摘要

在群晖 (Synology) NAS 上部署 OpenClaw 时,网络冲突和 WebSocket 1006 错误往往是初学者的噩梦。本文将深入探讨如何利用 Macvlan 技术为 OpenClaw 分配独立 IP,通过自动化脚本实现环境初始化、强制注入 allowInsecureAuth 配置以修复 HTTP 环境下的登录阻碍,并详细解析 --bind 参数的避坑逻辑。这是一份沉淀自实战的运维手册,旨在帮助 Homelab 玩家快速构建稳定的网关管理面板。


运维老兵的碎碎念:为什么你的 OpenClaw 总是跑不起来?

折腾过 OpenClaw 的朋友都知道,它的“脾气”有点古怪。作为一个旨在统一管理 Clash 内核的现代网关面板,它在设计之初就非常依赖安全的 Web 环境和精准的网络绑定。但在我们的家庭实验室(HomeLab)里,大多数场景是直接通过 IP 访问,或者在内网环境下使用不带证书的 HTTP 协议。这时候,你大概率会遇到连接断开或无法对齐 Token 的情况,报错信息往往指向神秘的 1006401

在群晖这种特定的环境中,直接使用 Docker 的 Host 模式虽然省事,但极易与系统自带的服务(如网盘、Web Station)产生端口冲突。而 Bridge 模式下,复杂的 NAT 转发又会让 OpenClaw 的网关发现机制失效。

今天分享的这套方案,核心思路只有两点:

  1. 给容器主权: 使用 Macvlan 让 OpenClaw 在你的局域网里拥有一个“平级”的独立 IP 地址。

  2. 强制“降级”安全检测: 通过脚本直接往容器内部“塞”配置文件,强制开启 allowInsecureAuth。别问我为什么不走 UI 勾选,因为当你进不去 UI 的时候,只有脚本能救命。


部署前的环境前置检查

在动笔写代码前,务必确认你的群晖 NAS 满足以下条件,否则脚本运行到一半卡死,排查起来非常痛苦:

  • SSH 权限: 你需要通过 SSH 登录群晖。在“控制面板 -> 终端机和 SNMP”中开启,并建议使用公钥登录,避免频繁输入密码。

  • 虚拟交换机 (Open vSwitch): 如果你的群晖运行了虚拟机(VMM),系统会自动创建 ovs_eth0。如果没有运行,物理网卡通常是 eth0。脚本已经做了自动适配,但建议你心里有数。

  • 子网规划: 确认你的局域网网段(比如 172.20.0.0/24),并预留一个未使用的 IP(如 172.20.0.18)给 OpenClaw。

  • Docker 套件: 确保已安装并正在运行 Container Manager(新版群晖名称)或 Docker。


核心自动化部署脚本

请直接复制以下代码,在群晖的 SSH 终端执行。该脚本已将所有避坑逻辑封装,特别针对 HTTP 环境下的 1006 错误做了物理级的配置文件补丁。

Bash

cat << 'EOF' > install_openclaw.sh
#!/bin/bash

# ================= 配置区域 =================
# 建议在此处根据你的实际网络环境进行微调
TARGET_IP="172.20.0.18"        # 容器固定 IP (请确保该 IP 未被占用)
GATEWAY="172.20.0.1"           # 你的主路由网关地址
SUBNET="172.20.0.0/24"         # 你的内网子网范围
DATA_DIR="/volume1/docker/openclaw" # 数据存储路径
IMAGE="ghcr.io/openclaw/openclaw:latest"
# ===========================================

echo ">>> [1/9] 开始执行 OpenClaw 自动化部署流程 (HTTP 修复版)..."

# 1. 网卡智能检测
# 群晖开启 VMM 后网卡名会变为 ovs_eth0,这里进行兼容性处理
if ip link show "ovs_eth0" > /dev/null 2>&1; then
    INTERFACE="ovs_eth0"
    echo "✅ 检测到群晖虚拟交换机,强制绑定物理接口: $INTERFACE"
else
    INTERFACE="eth0"
    echo "⚠️ 未检测到 ovs_eth0,降级绑定物理接口: $INTERFACE"
fi

# 2. 清理旧环境
echo ">>> [2/9] 清理旧容器实例..."
if docker ps -a | grep -q "openclaw"; then
    docker rm -f openclaw > /dev/null 2>&1
    echo "✅ 旧容器已强制移除"
else
    echo "✅ 无旧容器,跳过清理"
fi

# 3. 目录准备
echo ">>> [3/9] 配置数据持久化目录..."
if [ -d "$DATA_DIR" ]; then
    echo "📂 检测到现有目录: $DATA_DIR"
else
    mkdir -p "$DATA_DIR"
    echo "📂 新建目录: $DATA_DIR"
fi

CONFIG_DIR="$DATA_DIR/config"
WORKSPACE_DIR="$DATA_DIR/workspace"
mkdir -p "$CONFIG_DIR" "$WORKSPACE_DIR"

# 3.1 强制权限修正
# 这里直接给 777 是为了规避群晖复杂的 ACL 权限导致容器内 Node 进程无权写入
echo ">>> [3.1/9] 正在执行权限修正 (chmod 777)..."
chmod -R 777 "$DATA_DIR"

# ========================================================
# 3.2 核心修复:强制生成 openclaw.json
# 这是解决 1006 错误的关键:物理写入配置,允许 HTTP Token 登录
# 很多人在 Web UI 无法进入时根本没法改这个设置,所以我们先发制人
# ========================================================
echo ">>> [3.2/9] 正在生成 openclaw.json (强制开启非安全认证)..."
cat << JSONEOF > "$CONFIG_DIR/openclaw.json"
{
  "gateway": {
    "controlUi": {
      "allowInsecureAuth": true
    }
  }
}
JSONEOF
# 再次修正文件权限,确保容器内 Node 用户可读
chmod 666 "$CONFIG_DIR/openclaw.json"
echo "✅ 配置文件已写入: $CONFIG_DIR/openclaw.json"

# 4. Macvlan 网络构建
echo ">>> [4/9] 检查 Docker Macvlan 网络栈..."
if docker network inspect macvlan_net >/dev/null 2>&1; then
    echo "✅ 网络 macvlan_net 已存在,直接复用"
else
    echo "🔨 创建 Docker Macvlan 网络 (Parent: $INTERFACE)..."
    docker network create -d macvlan \
      --subnet=$SUBNET \
      --gateway=$GATEWAY \
      -o parent=$INTERFACE \
      macvlan_net || { echo "❌ 网络创建失败!请检查子网是否冲突"; exit 1; }
fi

# 5. 安全令牌生成
# 随机生成一个 32 位的 Hex 字符串作为 Gateway Token
echo ">>> [5/9] 生成 Gateway Token..."
if command -v openssl > /dev/null 2>&1; then
    GATEWAY_TOKEN=$(openssl rand -hex 32)
else
    GATEWAY_TOKEN=$(python3 -c "import secrets; print(secrets.token_hex(32))")
fi
echo "🔑 Token 生成完毕"

# 6. 启动容器
# 注意:这里我们覆盖了默认的 CMD,加入了 --bind lan 和 --allow-unconfigured
echo ">>> [6/9] 正在启动 OpenClaw 容器 (IP: $TARGET_IP)..."
echo "⚙️  配置模式: 本地 openclaw.json 优先"

docker run -d \
    --name openclaw \
    --restart always \
    --network macvlan_net \
    --ip $TARGET_IP \
    -e HOME=/home/node \
    -e TERM=xterm-256color \
    -e OPENCLAW_GATEWAY_TOKEN="$GATEWAY_TOKEN" \
    -v "$CONFIG_DIR":/home/node/.openclaw \
    -v "$WORKSPACE_DIR":/home/node/.openclaw/workspace \
    --init \
    $IMAGE \
    node dist/index.js gateway --bind lan --port 18789 --allow-unconfigured

# 7. 健康检查等待
echo ">>> [7/9] 等待服务初始化 (15秒)..."
sleep 15

# 8. 验证配置文件生效情况
echo ">>> [8/9] 验证配置注入..."
if docker exec openclaw ls -l /home/node/.openclaw/openclaw.json > /dev/null 2>&1; then
    echo "✅ 配置文件 openclaw.json 已成功挂载"
else
    echo "⚠️ 警告:容器内未检测到配置文件,可能导致连接失败"
fi

# 9. 最终状态
if docker ps | grep -q "openclaw"; then
    echo "✅ OpenClaw 容器运行状态: [正常]"
else
    echo "❌ 容器启动失败,查看日志: docker logs openclaw"
    exit 1
fi

echo "========================================================"
echo "🚀 OpenClaw 部署成功 (HTTP 1006 修复补丁已应用)"
echo "========================================================"
echo "⚠️  重要提示:由于使用 HTTP 协议,必须使用下方完整链接访问!"
echo ""
echo "👉 复制此链接到浏览器 (建议使用无痕模式):"
echo "   http://$TARGET_IP:18789/?token=$GATEWAY_TOKEN"
echo ""
echo "📋 操作说明:"
echo "   1. 必须带上 ?token=... 参数,否则浏览器会拦截配对"
echo "   2. 建议先清理浏览器缓存或使用隐身窗口打开"
echo "   3. 进入后如果仍提示连接断开,请检查 Token 是否正确填入设置页"
echo "========================================================"

rm -- "$0"
EOF

chmod +x install_openclaw.sh && ./install_openclaw.sh

关键参数解析与避坑指南

1. 关于 --bind 的大坑:0.0.0.0 还是 lan?

这是一个经常被误解的参数。很多用户习惯性地认为服务启动时应该 --bind 0.0.0.0 来监听所有网卡。

错误认知: “OpenClaw 不接受 0.0.0.0,必须填具体的 IP。”

实战真相: OpenClaw 的 CLI 设计更倾向于一种“模式化”的绑定。

  • --bind 0.0.0.0 在某些 Docker 映射环境下,由于 OpenClaw 会尝试探测本地子网掩码和广播地址,直接绑定 0.0.0.0 可能会导致它探测到错误的网关信息,从而在自动生成 Clash 配置时填入错误的 next-hop

  • --bind lan 这是作者推荐的“保命模式”。它会自动寻找容器内被标识为局域网接口的网卡(在 Macvlan 下通常就是 eth0)。使用 lan 模式,OpenClaw 会聪明地处理多网卡环境,确保 WebSocket 的握手地址与你访问的 IP 一致,从而规避 1006 错误。

避坑指南: 除非你有极其特殊的多网口叠加需求,否则在群晖 Macvlan 环境下,请死守 --bind lan。脚本中我已经为你设置好了。

2. 解决 1006 错误的深层逻辑

1006 错误通常是 WebSocket 连接非正常关闭。在 OpenClaw 中,这通常是因为:

  • 安全策略限制: 现代浏览器(尤其是 Chrome)禁止在非 HTTPS 环境下进行敏感的 Token 传输。

  • 配置未持久化: 即使你在 UI 里勾选了“允许非安全认证”,如果容器重启且没挂载 config 目录,设置就会重置,导致你再次被锁在门外。

我的脚本通过在启动前手动创建 openclaw.json 并写入 "allowInsecureAuth": true,从底层逻辑上告诉 OpenClaw:“别管那些安全限制,我是内网环境,听我的。”


容器初始化与 Onboarding 流程

部署完成后,虽然服务已经跑起来了,但你需要进行“接管”操作。这是最关键的一步,就像给新买的电脑设置管理员密码。

第一步:进入容器环境

在群晖 SSH 中输入以下命令进入容器:

Bash

docker exec -it openclaw sh

第二步:执行初始化脚本

在容器的 shell 中,执行 onboard 脚本。这一步会引导你设置系统的 Secret 和一些基础路径。

Bash

./openclaw.mjs onboard

操作重点:

  1. Secret 设置: 系统会提示你输入或生成一个 Secret。这个 Secret 必须和脚本生成的 GATEWAY_TOKEN 分开理解。Secret 是用于后端服务间认证的,请务必找个记事本记下来。

  2. 路径确认: 它会问你 workspace 放在哪,直接一路按回车保持默认即可(因为我们在 Docker 命令里已经挂载好了映射关系)。

  3. OpenClaw详细配置教程和使用命令,请参照:NAS Docker OpenClaw 初始化配置全参数调优与AI 助理进阶指南


进阶配置:多网段与防火墙优化

由于我们使用了 Macvlan,容器在群晖内部是“半透明”的。

  • 宿主机互通: 默认情况下,群晖宿主机无法直接访问 Macvlan 容器的 IP(这是 Linux kernel 的安全设计)。如果你需要在群晖的脚本里调用 OpenClaw 的 API,你需要建立一个网桥。

  • ADGuard Home 联动: 如果你的 OpenWrt 跑了 AdGuard Home,记得在 OpenClaw 的 DNS 设置里,将上游 DNS 指向 172.20.0.1(你的 OpenWrt IP)。


速查附录

常用管理命令汇总

任务

命令

备注

进入容器控制台

docker exec -it openclaw sh

调试必备

查看实时日志

docker logs -f openclaw

查 1006 错误首选

重新初始化

./openclaw.mjs onboard

忘记 Secret 时使用

更新镜像

docker pull ghcr.io/openclaw/openclaw:latest

定期维护

强制重启

docker restart openclaw

修改配置后执行

核心参数对照表

  • --port 18789: 控制面板的 HTTP 监听端口。

  • --allow-unconfigured: 允许在未完成向导时启动服务(非常重要,防止初始化失败导致容器死循环重启)。

  • --bind lan: 监听局域网接口。


引用与参考资料

  1. OpenClaw 官方文档: https://github.com/openclaw/openclaw (核心逻辑参考)

  2. Docker Macvlan 官方手册: https://docs.docker.com/network/drivers/macvlan/ (网络原理参考)

  3. 群晖 OVS 网络架构解析: https://www.synology.com/zh-cn/knowledgebase/DSM/tutorial/Network/How_to_configure_OVS


隐私保护说明:

文中出现的 172.20.0.x 为示例私有子网,实际部署时脚本会自动清理生成的临时文件。请勿在任何公网论坛泄露您的 GATEWAY_TOKENSecret

版权脚注:

本文首发于 E路领航 (blog.oool.cc),转载请注明出处。作者:苏杨 基于 2026 年最新 Docker 架构实践。


评论