以下提供完整的 OpenClaw + Chrome + noVNC 中文环境 Docker 解决方案,包含所有必需文件及详细说明,可直接用于构建和部署。
文件共享服务
创建目录
bash
mkdir -p /data/openclaw_data
useradd -u 1000 -m -s /bin/bash openclaw安装
bash
# CentOS/RHEL/Rocky
# 安装Samba服务
sudo yum install -y samba samba-client
# 启动并启用开机自启
sudo systemctl enable smb
sudo systemctl start smb
# Ubuntu/Debian
sudo apt update
sudo apt install -y samba
sudo systemctl enable smbd
sudo systemctl start smbd
# 设置密码
smbpasswd -a openclaw配置Samba共享
ini
# /etc/samba/smb.conf
[openclaw_share]
path = /data/openclaw_data
browseable = yes
writable = yes
guest ok = yes
create mask = 0777
directory mask = 0777从Windows访问
- 打开文件资源管理器,在地址栏输入
\\<虚拟机IP>\OpenClawData(如果使用方案A)或\\<虚拟机IP>\OpenClawConfig(方案B)。 - 输入用户名
openclaw和您设置的Samba密码。 - 您应该能看到容器内的配置文件目录,并可以进行读写操作。
构建OpenClaw镜像服务
文件结构
.
├── Dockerfile
├── entrypoint.sh
└── docker-compose.yml1. Dockerfile
dockerfile
# 基于 OpenClaw 官方镜像,版本可配置
ARG VERSION="2026.3.28"
# FROM ghcr.io/openclaw/openclaw:latest
FROM ghcr.nju.edu.cn/openclaw/openclaw:${VERSION}
USER root
ENV DEBIAN_FRONTEND=noninteractive\
LANG=zh_CN.UTF-8 \
LANGUAGE=zh_CN:zh \
LC_ALL=zh_CN.UTF-8
# 替换为国内 Debian 源(阿里云)
RUN sed -i 's/deb.debian.org/mirrors.aliyun.com/g' /etc/apt/sources.list.d/debian.sources && \
sed -i 's|security.debian.org/debian-security|mirrors.aliyun.com/debian-security|g' /etc/apt/sources.list.d/debian.sources && \
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo "Asia/Shanghai" > /etc/timezone
# 安装基础软件包(包含中文字体、Chrome 依赖等)
RUN apt-get update --allow-releaseinfo-change && \
apt-get install -y --no-install-recommends \
vim xvfb fluxbox tigervnc-standalone-server \
novnc websockify x11vnc \
procps wget gnupg2 fonts-wqy-zenhei fonts-noto-cjk libxss1 \
libasound2 libnspr4 libnss3 libx11-xcb1 libxtst6 \
libdrm2 libgbm1 libgtk-3-0 libvulkan1 libu2f-udev xdg-utils \
fonts-liberation locales && \
sed -i '/zh_CN.UTF-8/s/^# //g' /etc/locale.gen && locale-gen zh_CN.UTF-8 && \
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
echo "Asia/Shanghai" > /etc/timezone && \
apt-get clean && rm -rf /var/lib/apt/lists/*
# 在线下载并安装 Google Chrome
RUN wget -q -O - https://dl.google.com/linux/linux_signing_key.pub | gpg --dearmor -o /usr/share/keyrings/google-chrome-keyring.gpg && \
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/google-chrome-keyring.gpg] http://dl.google.com/linux/chrome/deb/ stable main" > /etc/apt/sources.list.d/google-chrome.list && \
apt-get update && \
apt-get install -y --no-install-recommends google-chrome-stable && \
apt-get clean && rm -rf /var/lib/apt/lists/*
# 安装skill
RUN curl -fsSL https://skillhub-1388575217.cos.ap-guangzhou.myqcloud.com/install/install.sh | bash && \
export PATH="/root/.local/bin:$PATH" && \
skillhub install self-improving-agent && \
skillhub install find-skills && \
skillhub install skill-vetter && \
skillhub install openclaw-tavily-search && \
skillhub install skill-scanner
# 安装微信插件(会遇到限流)
# RUN npx -y @tencent-weixin/openclaw-weixin-cli@latest install
# 复制自定义启动脚本
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
# 暴露端口
EXPOSE 18789 6080
# 切换回 node 用户
USER node
ENTRYPOINT ["/entrypoint.sh"]
CMD ["node", "openclaw.mjs", "gateway", "--allow-unconfigured"]2. entrypoint.sh
bash
#!/bin/bash
set -e
# 设置中文环境
export LANG=zh_CN.UTF-8
export LANGUAGE=zh_CN:zh
export LC_ALL=zh_CN.UTF-8
# ----- 家目录初始化 -----
if [ ! -f /home/node/.openclaw/openclaw.json ]; then
# ----- 动态生成 OpenClaw 配置 -----
echo "[Config] Generating configuration via openclaw config set..."
# Gateway
openclaw config set gateway '{
"mode": "local",
"bind": "lan",
"controlUi": {
"allowedOrigins": ["*"],
"allowInsecureAuth": true,
"dangerouslyDisableDeviceAuth": true
},
"auth": {
"mode": "token",
"token": "'"${OPENCLAW_AUTH_TOKEN}"'"
}
}'
# Browser
openclaw config set browser '{
"enabled": true,
"defaultProfile": "external",
"profiles": {
"external": {
"cdpUrl": "http://127.0.0.1:9222",
"attachOnly": true,
"color": "#00AA00"
}
}
}'
# Models (OpenRouter)
openclaw config set models.providers.openrouter '{
"baseUrl": "https://openrouter.ai/api/v1",
"apiKey": "'"${OPENROUTER_API_KEY}"'",
"api": "openai-completions",
"models": [
{
"id": "stepfun/step-3.5-flash:free",
"name": "openrouter/stepfun/step-3.5-flash:free",
"reasoning": false,
"input": ["text"],
"contextWindow": 256000,
"maxTokens": 8192
},
{
"id": "qwen/qwen3-next-80b-a3b-instruct:free",
"name": "openrouter/qwen/qwen3-next-80b-a3b-instruct:free",
"reasoning": false,
"input": ["text"],
"contextWindow": 262144,
"maxTokens": 8192
},
{
"id": "nvidia/nemotron-3-super-120b-a12b:free",
"name": "openrouter/nvidia/nemotron-3-super-120b-a12b:free",
"api": "openai-completions",
"reasoning": false,
"input": ["text"],
"contextWindow": 262144,
"maxTokens": 8192
}
]
}'
# Agents
openclaw config set agents.defaults '{
"model": {
"primary": "openrouter/stepfun/step-3.5-flash:free",
"fallbacks": [
"openrouter/qwen/qwen3-next-80b-a3b-instruct:free",
"openrouter/nvidia/nemotron-3-super-120b-a12b:free"
]
},
"models": {
"openrouter/stepfun/step-3.5-flash:free": {},
"openrouter/qwen/qwen3-next-80b-a3b-instruct:free": {},
"openrouter/nvidia/nemotron-3-super-120b-a12b:free": {}
},
"memorySearch": {
"enabled": false
}
}'
fi
# 确保环境变量已设置
if [ -z "${SILICONFLOW_API_KEY}" ]; then
echo "⚠️ SILICONFLOW_API_KEY not set, embedding will not work"
fi
if [ -z "${OPENROUTER_API_KEY}" ]; then
echo "⚠️ OPENROUTER_API_KEY not set, summarization will not work"
fi
# 清理旧进程
echo "[$(date)] Killing old Chrome..."
pkill -f "google-chrome" || true
sleep 2
# ----- 启动 Xvfb -----
echo "[Init] 启动 Xvfb..."
rm -f /tmp/.X99-lock /tmp/.X11-unix/X99
Xvfb :99 -screen 0 1280x720x24 &
XVFB_PID=$!
echo "[Init] 等待 Xvfb..."
# 等待 Xvfb 就绪
for i in {1..10}; do
if [ -S /tmp/.X11-unix/X99 ]; then
echo "[$(date)] Xvfb ready on display :99"
break
fi
sleep 1
done
fluxbox -display :99 &
sleep 1
# ----- 准备 Chrome 数据目录 -----
USER_DATA_DIR="/home/node/chrome_user"
# 清理锁
echo "[$(date)] 清理锁文件..."
rm -rf "$USER_DATA_DIR/SingletonLock" "$USER_DATA_DIR/SingletonSocket" "$USER_DATA_DIR/SingletonCookie"
# 确保开发者模式
mkdir -p "$USER_DATA_DIR/Default"
node -e "
const fs = require('fs');
const path = '$USER_DATA_DIR/Default/Preferences';
let prefs = {};
try {
if (fs.existsSync(path)) prefs = JSON.parse(fs.readFileSync(path));
} catch (e) {
console.warn('Preferences parse error, will create new.');
}
prefs.extensions = prefs.extensions || {};
prefs.extensions.ui = prefs.extensions.ui || {};
prefs.extensions.ui.developer_mode = true;
prefs.intl = { accept_languages: 'zh-CN,zh', selected_languages: 'zh-CN' };
fs.writeFileSync(path, JSON.stringify(prefs, null, 2));
console.log('Developer mode enabled in Preferences');
"
echo "[$(date)] 浏览器用户目录: $USER_DATA_DIR"
# ----- 启动 Chrome -----
echo "[$(date)] 启动 Chrome..."
google-chrome-stable \
--no-sandbox \
--disable-gpu \
--disable-dev-shm-usage \
--disable-setuid-sandbox \
--remote-debugging-port=9222 \
--display=:99 \
--user-data-dir="$USER_DATA_DIR" \
--no-first-run \
--disable-default-apps \
--lang=zh-CN \
--enable-logging=stderr \
--v=1 \
--start-maximized \
"https://www.baidu.com" > /home/node/chrome.log 2>&1 &
CHROME_PID=$!
echo "[$(date)] Chrome PID: $CHROME_PID"
sleep 5
# ----- 启动 VNC -----
echo "[$(date)] 启动 VNC server..."
x11vnc -display :99 -forever -shared -passwd 123456 -rfbport 5900 -bg > /dev/null 2>&1
websockify --web /usr/share/novnc 6080 localhost:5900 &
WEBSOCKIFY_PID=$!
# ----- 最终状态检查 -----
sleep 2
if ps -p $CHROME_PID > /dev/null; then
echo "=================================================="
echo "✅ SUCCESS: Chrome is running (PID: $CHROME_PID)"
echo " - CDP: http://127.0.0.1:9222"
echo " - VNC: port 5900 / noVNC: http://localhost:6080"
echo ""
echo "⚠️ 注意:扩展必须附加到 HTTP/HTTPS 网页,不能是 chrome:// 页面"
echo "=================================================="
else
echo "[$(date)] [ERROR] Chrome stopped."
fi
trap "kill $CHROME_PID $XVFB_PID $WEBSOCKIFY_PID 2>/dev/null; exit 0" SIGTERM SIGINT
if [ -x /usr/local/bin/docker-entrypoint.sh ]; then
/usr/local/bin/docker-entrypoint.sh "$@" &
fi
wait $!3. docker-compose.yml
yaml
services:
openclaw-desktop:
build: .
image: openclaw-with-chrome:2026.3.28
environment:
- OPENCLAW_AUTH_TOKEN="123456"
- OPENROUTER_API_KEY="sk-or-v1-1c984a3f7b"
#- SILICONFLOW_API_KEY=sk-...
- DISPLAY=:99
# 若需要额外权限,可取消注释
# cap_add:
# - SYS_ADMIN
# security_opt:
# - seccomp:unconfined
container_name: openclaw-desktop
restart: unless-stopped
# 使用 host 网络模式(与命令行 --net=host 一致)
network_mode: host
# 若希望使用桥接模式,注释掉上面 network_mode 并取消下面 ports 的注释
#ports:
# - "18789:18789"
# - "6080:6080"
# - "9222:9222"
ulimits:
nofile:
soft: 65535
hard: 65535
volumes:
# 持久化 OpenClaw 配置(可选)
- /data/openclaw_data:/home/node/.openclaw4. 构建与运行步骤
4.1 构建镜像
bash
docker build --network=host -t openclaw-with-chrome:2026.3.28 .4.2 启动容器
bash
docker-compose up -d4.3 查看日志
bash
docker-compose logs -f访问服务
noVNC 桌面:
http://<宿主机IP>:6080/vnc.html,密码123456- 扩展要点击扩展开启才可以被控制
- 端口18792
OpenClaw Web UI:
http://<宿主机IP>:18789,令牌123456Chrome 远程调试:
http://<宿主机IP>:9222/json/version
模型配置
Agent
Model
json
{
"primary": "openrouter/stepfun/step-3.5-flash:free"
}skills技能推荐
腾讯:https://skillhub.tencent.com/
| 技能名称 | 版本 | 功能简介 |
|---|---|---|
| agent-browser | 0.2.0 | Rust 无头浏览器自动化 CLI,支持导航、点击、输入、截图、PDF 导出 |
| find-skills | 0.1.0 | 技能发现助手,搜索并安装来自技能生态的技能 |
| nano-pdf | 1.0.0 | 使用自然语言指令编辑 PDF 文件 |
| openclaw-tavily-search | 0.1.0 | Tavily API 搜索(Brave 替代方案),支持 JSON/Markdown 输出 |
| skill-creator | 0.1.0 | 创建和优化 OpenClaw 技能的完整指南 |
| skill-vetter | 1.0.0 | 安全优先的技能审查工具,检测风险信号和可疑模式 |
| tavily-search | 1.0.0 | AI 优化的 Tavily 网络搜索,支持深度搜索和新闻主题 |
插件推荐
微信插件
bash
# 安装
npx -y @tencent-weixin/openclaw-weixin-cli@latest install
# 启动
openclaw config plugins.entries.openclaw-weixin.enabled true
# 登录
openclaw channels login --channel openclaw-weixin说明
- 中文环境:已在 entrypoint.sh 中设置系统环境变量,并通过 Chrome 启动参数
--lang=zh-CN和预置 Preferences 文件强制使用中文界面。 - 扩展加载:扩展已通过 Dockerfile 复制到
/home/node/chrome-extensions,Chrome 启动时自动加载。 - 网络模式:默认使用
host网络模式,直接暴露宿主机端口。若需桥接模式,请按注释修改docker-compose.yml。 - 持久化:通过卷挂载可保存 OpenClaw 配置和 Chrome 用户数据,避免重复登录。
此方案可直接用于生产或测试环境,已集成所有必要组件。如有特殊需求,可根据实际情况调整。
