作者:PySuper | 来源:zhengxingtao.com
前一篇 OpenClaw 实战讲了架构和日常使用,但部署部分一笔带过了。这篇专门补上——从 Docker 一键拉起到云服务器生产加固,给你一条龙搞定。末尾附一个真的能跑的一键部署脚本,不是摆设。
目录
部署前规划
方案一:Docker 一键部署(推荐)
方案二:裸机部署
方案三:云服务器一键部署
多渠道接入配置
模型配置
Skill 管理
生产加固
一键部署脚本(完整版)
常见问题排查
一、部署前规划
部署之前先想清楚三件事:跑在哪、用什么模型、接哪些渠道。别上来就 docker run,后面改配置比重新部署还麻烦。
1.1 硬件需求
表格
关键点:
OpenClaw 本身很轻,内存占用 200-500MB。瓶颈在 LLM API 调用,不在 Gateway。
如果跑 Ollama 本地模型,7B 参数模型需要至少 8GB 内存,70B 需要 40GB+。建议用带 GPU 的机器。
磁盘主要被会话记录和 Skill 缓存吃掉,SQLite 数据库增长不快,但日志要定期清理。
1.2 操作系统支持
表格
1.3 网络要求
plaintext
┌─────────────────────────────────────────────────────────┐
│ 网络端口规划 │
├──────────────┬──────────┬───────────────────────────────┤
│ 端口 │ 协议 │ 用途 │
├──────────────┼──────────┼───────────────────────────────┤
│ 18789 │ TCP/WS │ Gateway 主端口(WebSocket) │
│ 18793 │ TCP │ Canvas Host(可选) │
│ 3000/8080 │ TCP/HTTP │ Web UI(部分镜像默认) │
│ 6379 │ TCP │ Redis(如果用 Docker Compose) │
│ 80/443 │ TCP/HTTP │ Nginx 反向代理(生产必选) │
│ 11434 │ TCP/HTTP │ Ollama 本地模型(可选) │
└──────────────┴──────────┴───────────────────────────────┘
域名和 SSL:
测试环境:
localhost就行,不需要域名和证书。生产环境:必须配域名 + SSL。Telegram/Discord Webhook 要求 HTTPS 回调地址。
域名解析:A 记录指向服务器 IP,TTL 建议 300(5 分钟),方便切换。
SSL:用 Let's Encrypt 免费证书,Certbot 自动续期。Caddy 也能自动签发。
1.4 模型选择
这是影响成本最大的决策:
plaintext
┌────────────────────────────────────────────────────────────┐
│ 模型选择决策树 │
│ │
│ 数据能出公网吗? │
│ ├── 是 → 预算充足吗? │
│ │ ├── 是 → Claude Sonnet 4 / GPT-4o(最佳质量) │
│ │ └── 否 → GPT-4o-mini / Claude Haiku(性价比之王)│
│ └── 否 → 必须本地模型 │
│ ├── 有 GPU 吗? │
│ │ ├── 是 → Ollama + Qwen2.5-Coder:32B │
│ │ └── 否 → Ollama + Qwen2.5:7B(勉强可用) │
│ └── 混合方案:简单任务本地,复杂任务走 API │
└────────────────────────────────────────────────────────────┘
表格
我的建议:起步用 GPT-4o-mini 或 Claude Haiku,月花几块钱够用。等发现不够了再升级,别一上来就用最贵的。
二、方案一:Docker 一键部署(推荐)
Docker 是部署 OpenClaw 最省心的方式。不挑系统、不污染宿主、一条命令搞定。据《Deploying OpenClaw with Docker》(https://openclaw-ai.online/tutorials/deployment/)和《Self-Host OpenClaw with Docker Compose》(https://rolandsoftwares.com/content/self-host-openclaw-docker-compose-setup/),Docker 部署是官方推荐的首选方案。
2.1 完整 docker-compose.yml
这个 Compose 文件包含 OpenClaw Gateway + Redis + 日志配置 + 健康检查,开箱即用:
yaml
# docker-compose.yml
# OpenClaw 生产级 Docker Compose 配置
# 作者: PySuper | zhengxingtao.com
version: "3.8"
services:
openclaw-gateway:
image: ghcr.io/openclaw/openclaw:latest
container_name: openclaw
restart: unless-stopped
ports:
- "18789:18789" # Gateway WebSocket 主端口
- "18793:18793" # Canvas Host(可选,用于浏览器技能)
volumes:
# 配置目录:openclaw.json、SOUL.md、凭证、会话数据
- ./openclaw-config:/root/.openclaw
# 工作区:Agent 可以读写的文件目录
- ./openclaw-workspace:/root/workspace
env_file:
- .env
environment:
- NODE_ENV=production
- TZ=Asia/Shanghai
depends_on:
redis:
condition: service_healthy
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:18789/healthz"]
interval: 30s
timeout: 10s
retries: 3
start_period: 30s
deploy:
resources:
limits:
cpus: "2"
memory: 2G
reservations:
cpus: "0.5"
memory: 512M
logging:
driver: json-file
options:
max-size: "10m"
max-file: "5"
command: openclaw gateway
redis:
image: redis:7-alpine
container_name: openclaw-redis
restart: unless-stopped
ports:
- "127.0.0.1:6379:6379" # 只绑定本地,不对外暴露
volumes:
- redis-data:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 3
deploy:
resources:
limits:
memory: 256M
volumes:
redis-data:
driver: local
2.2 环境变量详解
创建 .env 文件,和 docker-compose.yml 放同一目录:
bash
# .env — OpenClaw 环境变量配置
# ⚠️ 此文件包含敏感信息,不要提交到 Git!
# ============================================
# 模型 Provider 配置(至少填一个)
# ============================================
# Anthropic Claude(推荐)
ANTHROPIC_API_KEY=sk-ant-your-key-here
# OpenAI GPT
# OPENAI_API_KEY=sk-your-key-here
# Google Gemini
# GOOGLE_AI_API_KEY=AIza-your-key-here
# OpenRouter(多模型聚合)
# OPENROUTER_API_KEY=sk-or-your-key-here
# 本地 Ollama(不需要真实 key,任意值即可)
# OLLAMA_API_KEY=ollama-local
# ============================================
# Gateway 认证
# ============================================
# Gateway Token — 访问 Control UI 和 API 的凭证
# 生产环境务必设置,用以下命令生成:
# openssl rand -hex 32
OPENCLAW_GATEWAY_TOKEN=your-secure-random-token-here
# ============================================
# 渠道 Token(按需启用)
# ============================================
# Telegram Bot
# TELEGRAM_BOT_TOKEN=123456:ABCdefGHIjklMNO
# Discord Bot
# DISCORD_BOT_TOKEN=MTIxxxxx
# Slack
# SLACK_APP_TOKEN=xapp-your-app-token
# SLACK_BOT_TOKEN=xoxb-your-bot-token
# ============================================
# 可选配置
# ============================================
# 默认模型
# DEFAULT_MODEL=claude-sonnet-4-20250514
# 月度消费上限(美元),防止 API 跑飞
# MAX_MONTHLY_SPEND=50
# 循环检测,防止 Agent 无限循环
# LOOP_DETECTION=true
# Redis 配置(Docker Compose 内部网络自动解析)
REDIS_HOST=redis
REDIS_PORT=6379
# REDIS_PASSWORD=your-redis-password
# 时区
TZ=Asia/Shanghai
环境变量优先级(从高到低):
进程环境变量(Docker runtime 传入)
.env文件(工作目录下)全局
.env(~/.openclaw/.env)openclaw.json中的 config 块
如果同一变量在多处定义,优先级高的覆盖低的。这个设计保证你不会意外覆盖系统级配置。
2.3 数据持久化
plaintext
┌──────────────────────────────────────────────────────────┐
│ Volume 挂载方案 │
│ │
│ 宿主机 容器内 │
│ ───────── ───────── │
│ ./openclaw-config/ → /root/.openclaw/ │
│ ├── openclaw.json ├── openclaw.json │
│ ├── SOUL.md ├── SOUL.md │
│ ├── credentials/ ├── credentials/ │
│ ├── skills/ ├── skills/ │
│ └── data/ └── data/ │
│ ├── conversations/ ├── conversations/ │
│ └── users/ └── users/ │
│ │
│ ./openclaw-workspace/ → /root/workspace/ │
│ ├── projects/ ├── projects/ │
│ └── temp/ └── temp/ │
│ │
│ redis-data (named vol) → /data/ (Redis 持久化) │
└──────────────────────────────────────────────────────────┘
关键提醒:
openclaw-config是 Agent 的"大脑",丢了就失忆。务必备份。openclaw-workspace是 Agent 的工作台,放它操作的文件。Redis 数据可以不备份,OpenClaw 只用它做缓存和会话临时存储,丢了会自动重建。
权限问题:如果容器内报权限错误,执行
docker exec openclaw chown -R node:node /root/.openclaw。
2.4 一键启动/停止/重启命令
bash
# ===== 首次部署 =====
# 1. 创建目录结构
mkdir -p openclaw-config openclaw-workspace
# 2. 创建 .env 文件(参考上面 2.2 节)
cp .env.example .env
nano .env # 填入你的 API Key 和 Token
# 3. 启动所有服务
docker compose up -d
# 4. 查看启动日志
docker compose logs -f openclaw-gateway
# 5. 运行交互式配置向导(首次部署推荐)
docker compose run --rm openclaw-gateway openclaw onboard
# ===== 日常运维 =====
# 启动
docker compose up -d
# 停止
docker compose stop
# 重启(配置变更后)
docker compose restart openclaw-gateway
# 查看状态
docker compose ps
# 查看日志(实时跟踪)
docker compose logs -f openclaw-gateway
# 查看最近 50 行日志
docker compose logs --tail 50 openclaw-gateway
# ===== 升级 =====
# 拉取最新镜像
docker compose pull openclaw-gateway
# 重建并启动(镜像更新后)
docker compose up -d openclaw-gateway
# ===== 清理 =====
# 停止并删除容器(数据保留在 volume 中)
docker compose down
# 停止并删除容器 + volume(⚠️ 数据全丢)
docker compose down -v
2.5 验证部署
bash
# 1. 检查容器状态
docker ps | grep openclaw
# 应该看到 openclaw 和 openclaw-redis 两个容器都是 Up
# 2. 健康检查
curl -s http://localhost:18789/healthz
# 应该返回 200
# 3. 访问 Control UI
# 浏览器打开 http://localhost:18789
# 输入 .env 中设置的 OPENCLAW_GATEWAY_TOKEN
# 4. 检查 Gateway 日志中的启动信息
docker compose logs openclaw-gateway 2>&1 | grep "listening"
# 应该看到: [gateway] listening on ws://0.0.0.0:18789
三、方案二:裸机部署
不用 Docker,直接在主机上跑。适合不想装 Docker 的场景,或者 macOS 本地开发。
3.1 系统依赖安装
Ubuntu/Debian:
bash
# 更新系统
sudo apt update && sudo apt upgrade -y
# 安装基础工具
sudo apt install -y curl git build-essential
# 安装 Node.js 22+(推荐用 nvm)
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash
source ~/.bashrc
nvm install 22
nvm use 22
node --version # 确认 v22+
# 安装 Redis(可选,推荐)
sudo apt install -y redis-server
sudo systemctl enable redis-server
sudo systemctl start redis-server
redis-cli ping # 应该返回 PONG
# 安装 Chromium(浏览器自动化技能需要)
sudo apt install -y chromium-browser libnss3 libatk-bridge2.0-0 \
libdrm2 libxkbcommon0 libxcomposite1 libxdamage1 libxfixes3 \
libxrandr2 libgbm1 libasound2
macOS:
bash
# 安装 Homebrew(如果没有)
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
# 安装 Node.js
brew install node@22
# 安装 Redis
brew install redis
brew services start redis
# 安装 OpenClaw(通过 npm)
npm install -g openclaw
Fedora/RHEL:
bash
# 安装依赖
sudo dnf install -y curl git gcc make
# 安装 Node.js 22
curl -fsSL https://rpm.nodesource.com/setup_22.x | sudo bash -
sudo dnf install -y nodejs
# 安装 Redis
sudo dnf install -y redis
sudo systemctl enable --now redis
3.2 从源码编译安装
bash
# 克隆仓库
git clone https://github.com/openclaw/openclaw.git
cd openclaw
# 安装依赖
npm install
# 构建项目
npm run build
# 运行交互式配置向导
npm run onboard
# 启动 Gateway
npm start
或者用全局安装方式(更简洁):
bash
# 全局安装
npm install -g openclaw
# 运行 onboarding 向导
openclaw onboard
# 启动 Gateway
openclaw gateway
3.3 Systemd 服务配置
让 OpenClaw 开机自启、崩溃自恢复。OpenClaw 官方支持 --install-daemon 参数自动创建 systemd 服务(据《OpenClaw for Linux》https://openclaw-ai.online/platforms/linux/)。
方式一:用 OpenClaw 自带命令(推荐)
bash
# 安装时自动创建 systemd 用户服务
openclaw onboard --install-daemon
方式二:手动创建 systemd 服务
bash
# 创建 systemd 用户服务文件
mkdir -p ~/.config/systemd/user/
cat > ~/.config/systemd/user/openclaw-gateway.service << 'EOF'
[Unit]
Description=OpenClaw Gateway - AI Agent Runtime
After=network.target
[Service]
Type=simple
ExecStart=/home/%u/.nvm/versions/node/v22.16.0/bin/openclaw gateway
Restart=on-failure
RestartSec=10
StandardOutput=journal
StandardError=journal
# 环境变量
Environment=NODE_ENV=production
Environment=TZ=Asia/Shanghai
# 安全限制
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=read-only
ReadWritePaths=/home/%u/.openclaw /home/%u/workspace
# 资源限制
LimitNOFILE=65536
MemoryMax=2G
[Install]
WantedBy=default.target
EOF
# 重新加载 systemd
systemctl --user daemon-reload
# 启用开机自启
systemctl --user enable openclaw-gateway
# 启动服务
systemctl --user start openclaw-gateway
# 确保用户注销后服务继续运行(重要!)
loginctl enable-linger $USER
服务管理命令速查:
bash
systemctl --user start openclaw-gateway # 启动
systemctl --user stop openclaw-gateway # 停止
systemctl --user restart openclaw-gateway # 重启
systemctl --user status openclaw-gateway # 查看状态
systemctl --user enable openclaw-gateway # 开机自启
systemctl --user disable openclaw-gateway # 取消自启
journalctl --user -u openclaw-gateway -f # 查看实时日志
journalctl --user -u openclaw-gateway -n 100 # 查看最近 100 行日志
3.4 日志轮转配置
bash
# 创建 journald 配置,限制日志大小
sudo mkdir -p /etc/systemd/journald.conf.d/
cat > /etc/systemd/journald.conf.d/openclaw.conf << 'EOF'
[Journal]
# 日志最大占用 500MB
SystemMaxUse=500M
# 单个日志文件最大 50MB
SystemMaxFileSize=50M
# 保留最近 7 天
MaxRetentionSec=7day
EOF
sudo systemctl restart systemd-journald
四、方案三:云服务器一键部署
在云服务器上部署 OpenClaw,让它 7×24 小时在线。以下以 Ubuntu 24.04 为例,阿里云/腾讯云/AWS 通用。
4.1 云厂商最小成本方案
表格
腾讯云捷径:Lighthouse 应用市场有 OpenClaw 预装镜像,选了就能用,免手动部署。据《OpenClaw完全指南:部署你的7×24小时开源AI助手》(https://www.tencentcloud.com/techpedia/141458),一键即可在几秒内完成部署。
4.2 一键脚本:从裸机到 OpenClaw 运行
这是一个完整的部署脚本,从 SSH 登录到 OpenClaw 运行,一条命令搞定:
bash
#!/bin/bash
# quick-deploy.sh — 快速部署 OpenClaw 到云服务器
# 用法: curl -fsSL https://your-host/quick-deploy.sh | bash
# 或: wget -qO- https://your-host/quick-deploy.sh | bash
set -euo pipefail
# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
info() { echo -e "${GREEN}[INFO]${NC} $*"; }
warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
error() { echo -e "${RED}[ERROR]${NC} $*"; exit 1; }
# ===== 第一步:系统检测 =====
info "检测系统环境..."
if [[ ! -f /etc/os-release ]]; then
error "无法检测操作系统,仅支持 Ubuntu/Debian"
fi
source /etc/os-release
info "操作系统: $PRETTY_NAME"
# 检查是否 root
if [[ $EUID -ne 0 ]]; then
error "请使用 root 用户运行此脚本: sudo bash quick-deploy.sh"
fi
# 检查内存
TOTAL_MEM=$(grep MemTotal /proc/meminfo | awk '{print int($2/1024)}')
info "内存: ${TOTAL_MEM}MB"
if [[ $TOTAL_MEM -lt 2000 ]]; then
warn "内存不足 2GB,可能导致运行不稳定"
fi
# ===== 第二步:安装 Docker =====
if command -v docker &>/dev/null; then
info "Docker 已安装: $(docker --version)"
else
info "安装 Docker..."
curl -fsSL https://get.docker.com | sh
systemctl enable docker
systemctl start docker
info "Docker 安装完成: $(docker --version)"
fi
# 安装 Docker Compose 插件
if ! docker compose version &>/dev/null; then
info "安装 Docker Compose 插件..."
apt-get update -qq
apt-get install -y docker-compose-plugin
fi
# ===== 第三步:创建目录和配置 =====
INSTALL_DIR="/opt/openclaw"
info "创建部署目录: $INSTALL_DIR"
mkdir -p "$INSTALL_DIR"/{openclaw-config,openclaw-workspace}
cd "$INSTALL_DIR"
# 生成 Gateway Token
GATEWAY_TOKEN=$(openssl rand -hex 32)
info "已生成 Gateway Token"
# 创建 .env 文件(需要用户交互输入 API Key)
cat > .env << EOF
# OpenClaw 环境变量 — 由 quick-deploy.sh 自动生成
# 生成时间: $(date)
# Gateway 认证
OPENCLAW_GATEWAY_TOKEN=${GATEWAY_TOKEN}
# 模型 Provider(请填入你的 API Key)
ANTHROPIC_API_KEY=sk-ant-YOUR-KEY-HERE
# OPENAI_API_KEY=sk-YOUR-KEY-HERE
# 时区
TZ=Asia/Shanghai
EOF
chmod 600 .env
warn "请编辑 ${INSTALL_DIR}/.env 填入你的 API Key!"
# 创建 docker-compose.yml
cat > docker-compose.yml << 'COMPOSE'
version: "3.8"
services:
openclaw-gateway:
image: ghcr.io/openclaw/openclaw:latest
container_name: openclaw
restart: unless-stopped
ports:
- "18789:18789"
volumes:
- ./openclaw-config:/root/.openclaw
- ./openclaw-workspace:/root/workspace
env_file:
- .env
environment:
- NODE_ENV=production
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:18789/healthz"]
interval: 30s
timeout: 10s
retries: 3
deploy:
resources:
limits:
memory: 2G
logging:
driver: json-file
options:
max-size: "10m"
max-file: "5"
command: openclaw gateway
redis:
image: redis:7-alpine
container_name: openclaw-redis
restart: unless-stopped
ports:
- "127.0.0.1:6379:6379"
volumes:
- redis-data:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 3
volumes:
redis-data:
COMPOSE
# ===== 第四步:配置防火墙 =====
info "配置防火墙..."
# UFW
if command -v ufw &>/dev/null; then
ufw allow 80/tcp
ufw allow 443/tcp
ufw allow 18789/tcp
ufw --force enable
info "UFW 防火墙已配置"
else
warn "未检测到 UFW,请手动配置防火墙开放 80/443/18789 端口"
fi
# ===== 第五步:启动服务 =====
info "拉取 OpenClaw 镜像..."
docker compose pull
info "启动 OpenClaw..."
docker compose up -d
# 等待启动
info "等待服务启动..."
sleep 15
# ===== 第六步:验证 =====
if curl -sf http://localhost:18789/healthz > /dev/null 2>&1; then
info "✅ OpenClaw 启动成功!"
else
warn "Gateway 尚未就绪,请查看日志: docker compose logs -f openclaw-gateway"
fi
# 输出访问信息
PUBLIC_IP=$(curl -sf ifconfig.me || echo "YOUR_SERVER_IP")
echo ""
echo -e "${BLUE}========================================${NC}"
echo -e "${GREEN} OpenClaw 部署完成!${NC}"
echo -e "${BLUE}========================================${NC}"
echo ""
echo -e " Control UI: http://${PUBLIC_IP}:18789"
echo -e " Gateway Token: ${GATEWAY_TOKEN}"
echo ""
echo -e " ⚠️ 下一步:"
echo -e " 1. 编辑 ${INSTALL_DIR}/.env 填入 API Key"
echo -e " 2. 重启服务: cd ${INSTALL_DIR} && docker compose restart"
echo -e " 3. 运行 onboarding: docker compose run --rm openclaw-gateway openclaw onboard"
echo ""
echo -e " 📖 生产环境建议配置 Nginx + SSL,见本文第四章。"
echo ""
4.3 防火墙/安全组配置
UFW(Ubuntu 默认防火墙):
bash
# 开放必要端口
sudo ufw allow 22/tcp # SSH
sudo ufw allow 80/tcp # HTTP
sudo ufw allow 443/tcp # HTTPS
sudo ufw allow 18789/tcp # OpenClaw Gateway(如果不用 Nginx 代理)
# 如果用 Nginx 反向代理,可以不开放 18789
# sudo ufw deny 18789/tcp
sudo ufw enable
sudo ufw status
云安全组(阿里云/腾讯云/AWS 控制台):
表格
⚠️ 绝对不要把 18789 端口直接暴露到公网,除非你清楚自己在做什么。Gateway Token 走的是 HTTP 明文,不配 HTTPS 就是在裸奔。
4.4 Nginx 反向代理 + SSL(Let's Encrypt)
生产环境必须配。据《Deploy OpenClaw Securely on a VPS》(https://www.virtua.cloud/learn/en/tutorials/deploy-openclaw-securely-vps)和《OpenClaw Reverse Proxy Setup Guide》(https://remoteopenclaw.com/blog/openclaw-reverse-proxy-setup),这是标准配置流程。
bash
# 1. 安装 Nginx 和 Certbot
sudo apt update
sudo apt install -y nginx certbot python3-certbot-nginx
# 2. 创建 Nginx 配置
sudo tee /etc/nginx/sites-available/openclaw.conf > /dev/null << 'NGINX'
server {
listen 80;
listen [::]:80;
server_name openclaw.example.com; # ← 换成你的域名
# Let's Encrypt 验证
location /.well-known/acme-challenge/ {
root /var/www/html;
}
# HTTP 强制跳转 HTTPS
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name openclaw.example.com; # ← 换成你的域名
# SSL 证书(Certbot 会自动填入,这里先占位)
ssl_certificate /etc/letsencrypt/live/openclaw.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/openclaw.example.com/privkey.pem;
# SSL 加固
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# 安全头
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
# 隐藏 Nginx 版本
server_tokens off;
# 反向代理到 OpenClaw Gateway
location / {
proxy_pass http://127.0.0.1:18789;
# WebSocket 支持(关键!)
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# 信任头(注意:用 $remote_addr 覆盖,不用 append)
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $host;
# 超时设置(Agent 会话可能很长)
proxy_read_timeout 86400s;
proxy_send_timeout 86400s;
}
}
NGINX
# 3. 启用站点配置
sudo ln -sf /etc/nginx/sites-available/openclaw.conf /etc/nginx/sites-enabled/
sudo rm -f /etc/nginx/sites-enabled/default
# 4. 测试 Nginx 配置
sudo nginx -t
# 5. 先用 HTTP 模式启动 Nginx(SSL 证书还没有)
# 临时注释掉 SSL 相关配置,或者直接获取证书
sudo systemctl reload nginx
# 6. 获取 SSL 证书(确保域名已解析到服务器 IP)
sudo certbot --nginx -d openclaw.example.com
# 7. 验证自动续期
sudo certbot renew --dry-run
配置 OpenClaw 信任代理:
编辑 ~/.openclaw/openclaw.json(或 Docker 挂载的 openclaw-config/openclaw.json):
json
{
"gateway": {
"bind": "loopback",
"port": 18789,
"trustedProxies": ["127.0.0.1", "172.16.0.0/12"],
"auth": {
"mode": "token",
"token": "${OPENCLAW_GATEWAY_TOKEN}"
},
"controlUi": {
"allowInsecureAuth": false
}
}
}
验证 HTTPS:
bash
# 从本地机器测试(不是服务器上)
curl -I https://openclaw.example.com/healthz
# 应该返回 200
# 检查证书信息
openssl s_client -connect openclaw.example.com:443 -servername openclaw.example.com </dev/null 2>/dev/null | openssl x509 -noout -dates
五、多渠道接入配置
OpenClaw 的核心竞争力之一就是多渠道统一接入。下面逐个渠道讲配置步骤。
5.1 Telegram Bot 接入
这是最简单的渠道,5 分钟搞定。
plaintext
┌───────────────────────────────────────────────────────────┐
│ Telegram Bot 接入流程 │
│ │
│ ① @BotFather 创建 Bot → 获取 Bot Token │
│ │ │
│ ▼ │
│ ② 配置 Token 到 OpenClaw │
│ 方式 A: .env 中 TELEGRAM_BOT_TOKEN=xxx │
│ 方式 B: openclaw.json 中 channels.telegram.token │
│ │ │
│ ▼ │
│ ③ 重启 Gateway → Bot 自动上线 │
│ │ │
│ ▼ │
│ ④ 在 Telegram 中找到 Bot → 发消息测试 │
└───────────────────────────────────────────────────────────┘
步骤详解:
bash
# 第一步:在 Telegram 中找 @BotFather
# 1. 打开 Telegram,搜索 @BotFather
# 2. 发送 /newbot
# 3. 输入 Bot 名称(显示名),如 "My OpenClaw Assistant"
# 4. 输入 Bot 用户名(必须以 bot 结尾),如 "my_openclaw_bot"
# 5. @BotFather 返回 Bot Token,格式如: 7123456789:AAH...xxx
# 6. 保存这个 Token!
配置方式一:环境变量(推荐,简单)
bash
# 在 .env 文件中添加
echo 'TELEGRAM_BOT_TOKEN=7123456789:AAH...xxx' >> /opt/openclaw/.env
# 重启
cd /opt/openclaw && docker compose restart openclaw-gateway
配置方式二:openclaw.json(更灵活,可以配 DM 策略等)
json
{
"channels": {
"telegram": {
"enabled": true,
"token": "7123456789:AAH...xxx",
"dm": {
"enabled": true,
"policy": "pairing",
"allowFrom": ["your_telegram_user_id"]
}
}
}
}
获取你的 Telegram User ID:
在 Telegram 中找 @userinfobot,发一条消息,它会返回你的 User ID。
5.2 Discord Bot 接入
plaintext
┌───────────────────────────────────────────────────────────┐
│ Discord Bot 接入流程 │
│ │
│ ① Discord Developer Portal 创建应用 │
│ https://discord.com/developers/applications │
│ │ │
│ ▼ │
│ ② 创建 Bot → 获取 Bot Token │
│ 开启 Message Content Intent(Privileged Intents) │
│ │ │
│ ▼ │
│ ③ 生成 OAuth2 邀请链接 → 邀请 Bot 到服务器 │
│ 权限: Send Messages, Read Message History │
│ │ │
│ ▼ │
│ ④ 配置 Token 到 OpenClaw → 重启 │
└───────────────────────────────────────────────────────────┘
步骤详解:
bash
# 1. 访问 https://discord.com/developers/applications
# 2. 点击 "New Application",输入名称
# 3. 左侧菜单 → Bot → "Add Bot"
# 4. 复制 Bot Token(只显示一次!)
# 5. 开启 Privileged Gateway Intents:
# - PRESENCE INTENT: 关
# - SERVER MEMBERS INTENT: 按需
# - MESSAGE CONTENT INTENT: 开(必须!否则 Bot 收不到消息内容)
# 6. 生成邀请链接:
# 左侧 → OAuth2 → URL Generator
# Scopes: bot
# Bot Permissions: Send Messages, Read Message History, Attach Files
# 复制生成的 URL,在浏览器中打开,选择你的 Discord 服务器
配置到 OpenClaw:
json
{
"channels": {
"discord": {
"enabled": true,
"token": "MTIxxxxx.your-bot-token",
"dm": {
"enabled": true,
"policy": "pairing"
},
"guilds": {
"your-guild-id": {
"requireMention": false,
"channels": {
"general": { "allow": true },
"bot-commands": {
"allow": true,
"requireMention": true
}
}
}
}
}
}
}
5.3 Slack 接入
plaintext
┌───────────────────────────────────────────────────────────┐
│ Slack App 接入流程 │
│ │
│ ① https://api.slack.com/apps → Create New App │
│ 选择 "From scratch" │
│ │ │
│ ▼ │
│ ② 启用 Socket Mode → 获取 App-Level Token (xapp-) │
│ │ │
│ ▼ │
│ ③ 配置 Event Subscriptions → 订阅 message.events │
│ │ │
│ ▼ │
│ ④ Install App to Workspace → 获取 Bot Token (xoxb-) │
│ │ │
│ ▼ │
│ ⑤ 配置两个 Token 到 OpenClaw → 重启 │
└───────────────────────────────────────────────────────────┘
配置到 OpenClaw:
bash
# .env 文件
SLACK_APP_TOKEN=xapp-1-Axxx-Bxxx
SLACK_BOT_TOKEN=xoxb-xxx-xxx
或在 openclaw.json 中:
json
{
"channels": {
"slack": {
"enabled": true,
"appToken": "xapp-1-Axxx-Bxxx",
"botToken": "xoxb-xxx-xxx"
}
}
}
Slack 配置注意事项:
Slack 使用 Socket Mode(WebSocket),不需要公网回调地址,本地部署也行。
Event Subscriptions 要订阅
message.channels、message.groups、message.im、message.mpim。Bot Token Scopes 需要:
chat:write、channels:history、groups:history、im:history。
5.4 微信/飞书接入说明
飞书(Feishu):
OpenClaw 原生支持飞书。配置流程:
飞书开放平台(https://open.feishu.cn)创建企业自建应用
添加"机器人"能力
配置事件订阅(消息接收)
获取 App ID 和 App Secret
配置到
openclaw.json:
json
{
"channels": {
"feishu": {
"enabled": true,
"appId": "cli_xxx",
"appSecret": "your-app-secret",
"verificationToken": "your-verification-token",
"encryptKey": "your-encrypt-key"
}
}
}
微信(WeChat):
微信没有官方 Bot API,需要通过以下方式间接实现:
表格
建议:个人用 Telegram/Discord 就够了。微信渠道仅限企业公众号场景,走公众号消息接口最稳定。
六、模型配置
OpenClaw 支持 14+ 家模型 Provider,配置方式灵活。据《How to Add Custom Models to OpenClaw》(https://blog.laozhang.ai/en/posts/openclaw-custom-model)和《OpenClaw Ollama 配置文档》(https://openclaws.io/docs/providers/ollama/),以下是各 Provider 的详细配置。
6.1 OpenAI API 配置
bash
# .env
OPENAI_API_KEY=sk-your-key-here
json
{
"agents": {
"defaults": {
"model": {
"primary": "openai/gpt-4o"
}
}
}
}
可用模型:openai/gpt-4o、openai/gpt-4o-mini、openai/o3-mini、openai/gpt-4.1 等。
6.2 Anthropic Claude API 配置
bash
# .env
ANTHROPIC_API_KEY=sk-ant-your-key-here
json
{
"agents": {
"defaults": {
"model": {
"primary": "anthropic/claude-sonnet-4-20250514"
}
}
}
}
可用模型:anthropic/claude-sonnet-4-20250514、anthropic/claude-haiku-4-20250414、anthropic/claude-opus-4-20250514。
6.3 本地 Ollama 对接
bash
# 1. 安装 Ollama
curl -fsSL https://ollama.com/install.sh | sh
# 2. 拉取模型
ollama pull qwen2.5:7b # 通用对话,4.7GB
ollama pull qwen2.5-coder:32b # 代码生成,需 24GB+ 内存
ollama pull gemma4 # Google Gemma 4
ollama pull glm-4.7 # 智谱 GLM
# 3. 验证 Ollama 运行
ollama list
curl http://localhost:11434/api/tags
OpenClaw 配置(最简方式):
bash
# .env — 只需设置一个环境变量,OpenClaw 自动发现本地 Ollama 模型
OLLAMA_API_KEY=ollama-local
OpenClaw 配置(指定模型和参数):
json
{
"models": {
"providers": {
"ollama": {
"baseUrl": "http://127.0.0.1:11434",
"apiKey": "ollama-local",
"api": "ollama",
"models": [
{
"id": "qwen2.5:7b",
"name": "Qwen2.5 7B",
"reasoning": false,
"input": ["text"],
"cost": { "input": 0, "output": 0, "cacheRead": 0, "cacheWrite": 0 },
"contextWindow": 32768,
"maxTokens": 8192
},
{
"id": "qwen2.5-coder:32b",
"name": "Qwen2.5 Coder 32B",
"reasoning": false,
"input": ["text"],
"cost": { "input": 0, "output": 0, "cacheRead": 0, "cacheWrite": 0 },
"contextWindow": 32768,
"maxTokens": 8192
}
]
}
}
},
"agents": {
"defaults": {
"model": {
"primary": "ollama/qwen2.5:7b"
}
}
}
}
⚠️ 重要:Ollama 的 baseUrl 不要加 /v1 后缀!用 http://host:11434 而不是 http://host:11434/v1。/v1 是 OpenAI 兼容模式,会导致 Tool Calling 不可靠。
Docker 中连接宿主机 Ollama:
yaml
# docker-compose.yml 中的 environment 追加
environment:
- OLLAMA_API_KEY=ollama-local
# Linux: host.docker.internal 不可用,用宿主机 IP
# 查宿主机 IP: ip route | grep default | awk '{print $9}'
或者把 Ollama 也放进 Docker Compose:
yaml
ollama:
image: ollama/ollama:latest
container_name: openclaw-ollama
restart: unless-stopped
ports:
- "127.0.0.1:11434:11434"
volumes:
- ollama-data:/root/.ollama
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: 1
capabilities: [gpu]
volumes:
ollama-data:
6.4 OpenRouter 多模型切换
OpenRouter 是一个模型聚合服务,一个 API Key 访问 200+ 模型。
bash
# .env
OPENROUTER_API_KEY=sk-or-your-key-here
json
{
"models": {
"providers": {
"openrouter": {
"apiKey": "sk-or-your-key-here"
}
}
},
"agents": {
"defaults": {
"model": {
"primary": "openrouter/anthropic/claude-sonnet-4-20250514"
}
}
}
}
使用 OpenRouter 的好处:可以在不同模型之间自由切换,不用每个都注册账号。模型名格式是 openrouter/厂商/模型名。
6.5 模型回退策略
当主模型不可用(限速、宕机)时,自动切换到备选模型:
json
{
"agents": {
"defaults": {
"model": {
"primary": "anthropic/claude-sonnet-4-20250514",
"fallbacks": [
"openai/gpt-4o",
"openai/gpt-4o-mini",
"ollama/qwen2.5:7b"
]
}
}
}
}
回退逻辑:
plaintext
┌───────────────────────────────────────────────────────────┐
│ 模型回退链路 │
│ │
│ 请求 → Claude Sonnet 4 │
│ │ │
│ ├── 成功 → 返回结果 │
│ │ │
│ └── 失败(限速/错误)→ GPT-4o │
│ │ │
│ ├── 成功 → 返回 │
│ │ │
│ └── 失败 → GPT-4o-mini
│ │ │
│ ├── 成功 → 返回
│ │ │
│ └── 失败 → Ollama 本地
│ │
│ └── 最后兜底
└───────────────────────────────────────────────────────────┘
建议:回退链的最后一环放一个本地 Ollama 模型,确保即使所有云 API 都挂了,Agent 也能响应(虽然质量下降)。
七、Skill 管理
Skill 是 OpenClaw 的插件系统。ClawHub 是官方 Skill 市场,被称为 "AI Agent 的 npm"。据《What is Claw Hub? The Complete OpenClaw Hub Guide》(https://claw-hub.net/what-is-clawhub.html),目前有 3,286+ 个验证过的 Skill。
7.1 ClawHub 热门 Skill 一键安装脚本
以下是根据安装量和社区评价整理的 Top 20 必装 Skill。据《ClawHub 与 Claude Code 技能生态专题报告》(https://blog.csdn.net/u012565112/article/details/160113455)整理。
bash
#!/bin/bash
# install-top-skills.sh — 安装 ClawHub Top 20 必装 Skill
# 前提: OpenClaw 已部署并运行
SKILLS=(
# === 生存层(必装)===
"web-browsing" # 180K+ 安装 | 网页浏览、数据抓取
"tavily-search" # 85K+ 安装 | 高质量 AI 搜索
"felo-search" # 60K+ 安装 | 带引用来源的 AI 搜索
# === 效率层(强烈推荐)===
"capability-evolver" # 35K+ 安装 | Agent 自我学习新技能
"gog" # 48K+ 安装 | Google 全家桶(Gmail/Calendar/Drive)
"context7" # 28K+ 安装 | 查询最新库/框架文档
"summarize" # 37K+ 安装 | 多格式内容摘要
"github" # 高安装量 | GitHub 完整操作能力
# === 协作层(推荐)===
"notion" # 20K+ 安装 | Notion 笔记管理
"telegram-bot" # 145K+ 安装 | Telegram 远程控制
# === 安全层(重要)===
"secret-scanner" # 密钥泄露检测
"skill-vetter" # Skill 安全审查
# === 开发工具 ===
"docker" # Docker 容器管理
"sql-query" # 数据库查询
# === 内容创作 ===
"image-gen" # AI 图片生成
# === 数据分析 ===
"data-viz" # 数据可视化
"excel" # Excel 处理
# === 自进化 ===
"ontology-agent" # 知识本体管理
)
echo "🦞 开始安装 ClawHub Top ${#SKILLS[@]} 必装 Skill..."
echo ""
INSTALLED=0
FAILED=0
for skill in "${SKILLS[@]}"; do
echo -n " 安装 ${skill}... "
if npx clawhub@latest install "$skill" 2>/dev/null; then
echo "✅"
((INSTALLED++))
else
echo "❌"
((FAILED++))
fi
done
echo ""
echo "==================================="
echo " 安装完成: ✅ ${INSTALLED} ❌ ${FAILED}"
echo "==================================="
echo ""
echo " 查看已安装 Skill: openclaw skills list"
echo " 更新全部 Skill: openclaw skills update --all"
echo ""
echo " ⚠️ 安全提醒:"
echo " - 禁用自动更新: openclaw config set skills.autoUpdate false"
echo " - 安装前务必审查 Skill 内容"
echo " - 参考 ClawHavoc 事件: https://claw-hub.net/what-is-clawhub.html"
7.2 自定义 Skill 开发和部署
Skill 的核心就是一个 SKILL.md 文件 + 可选的脚本。据《Part 23: ClawHub Skills Marketplace》(https://github.com/OnlyTerp/openclaw-optimization-guide/blob/master/part23-clawhub-skills-marketplace.md),Skill 的结构如下:
plaintext
my-custom-skill/
├── SKILL.md # 必须 - Skill 定义文件
├── scripts/ # 可选 - 执行脚本
│ ├── main.py # Python 脚本
│ └── helper.sh # Bash 脚本
└── references/ # 可选 - 参考文档
└── template.md # 模板文件
SKILL.md 模板:
markdown
---
name: my-custom-skill
version: 1.0.0
description: 简洁描述这个 Skill 做什么
author: your-username
---
# My Custom Skill
## 接口定义
这个 Skill 接受以下输入:
- `text`: 要处理的文本(必需)
- `format`: 输出格式,可选 json/markdown(可选,默认 markdown)
## 执行逻辑
1. 接收输入文本
2. 使用 `scripts/main.py` 处理
3. 返回格式化结果
## 使用示例
用户说:用 my-custom-skill 处理这段文字
安装自定义 Skill:
bash
# 方式一:本地安装(开发阶段)
mkdir -p ~/.openclaw/skills/my-custom-skill
cp -r my-custom-skill/* ~/.openclaw/skills/my-custom-skill/
# 方式二:发布到 ClawHub
npx clawhub@latest publish ./my-custom-skill
# 方式三:从 ClawHub 安装
npx clawhub@latest install your-username/my-custom-skill
7.3 Skill 更新和版本管理
bash
# 查看已安装的 Skill
openclaw skills list
# 更新单个 Skill
openclaw skills update author/skill-name
# 更新全部 Skill
openclaw skills update --all
# ⚠️ 重要:生产环境建议禁用自动更新
# ClawHavoc 事件证明自动更新是安全隐患
openclaw config set skills.autoUpdate false
openclaw config set skills.updateNotify true
# 安装时锁定版本(推荐)
npx clawhub@latest install author/skill-name --ref v1.2.0
# 移除 Skill
openclaw skills remove author/skill-name
Skill 安全最佳实践(据《ClawHub Skills Analyzed: 48% Show Security Issues》https://www.gradually.ai/en/clawhub-skills-analysis/):
安装前审查:读 SKILL.md 和脚本,检查有没有
exec、eval、网络请求到可疑地址禁用自动更新:防止 Sleeper Update 攻击
锁定版本:
--ref v1.2.0安装特定版本优先选验证作者:ClawHub 上只有 6.8% 的开发者是验证过的
最小权限原则:Skill 不需要访问的文件/目录就不给权限
八、生产加固
部署完只是开始,生产环境需要安全、备份、监控三件套。
8.1 安全加固
1. API Key 加密
bash
# .env 文件权限锁定
chmod 600 /opt/openclaw/.env
chown root:root /opt/openclaw/.env
# 确保 .env 在 .gitignore 中
echo ".env" >> /opt/openclaw/.gitignore
2. Docker 网络隔离
yaml
# docker-compose.yml 中使用内部网络
services:
openclaw-gateway:
networks:
- frontend # 连接 Nginx
- backend # 连接 Redis
# 不暴露端口到宿主机(由 Nginx 代理)
redis:
networks:
- backend # 只有 Gateway 能访问
# 不暴露任何端口
networks:
frontend:
driver: bridge
backend:
driver: bridge
internal: true # 不能访问外网
3. 非 root 运行
yaml
# docker-compose.yml
services:
openclaw-gateway:
user: "1000:1000" # 用非 root UID 运行
read_only: true # 只读文件系统
tmpfs:
- /tmp
- /run
4. Gateway 安全配置
json
{
"gateway": {
"bind": "loopback",
"auth": {
"mode": "token",
"token": "${OPENCLAW_GATEWAY_TOKEN}"
},
"trustedProxies": ["127.0.0.1"],
"controlUi": {
"allowInsecureAuth": false
}
},
"skills": {
"autoUpdate": false,
"updateNotify": true
}
}
5. 安全检查清单
plaintext
┌───────────────────────────────────────────────────────────┐
│ 生产安全检查清单 │
├───────────────────────────────────────────────────────────┤
│ ☐ Gateway 不直接暴露到公网(走 Nginx/Caddy 代理) │
│ ☐ HTTPS 已启用(Let's Encrypt 或自签证书) │
│ ☐ Gateway Token 已设置且足够随机 │
│ ☐ .env 文件权限 600,不在 Git 仓库中 │
│ ☐ Redis 不暴露到公网(127.0.0.1 或 internal network) │
│ ☐ Skill 自动更新已关闭 │
│ ☐ Docker 容器设了内存限制 │
│ ☐ 日志不含敏感信息(API Key、Token) │
│ ☐ 定期轮换 API Key │
│ ☐ 安装的 Skill 都审查过源码 │
│ ☐ UFW/防火墙已启用,仅开放必要端口 │
│ ☐ SSH 禁用密码登录,仅用 Key 认证 │
└───────────────────────────────────────────────────────────┘
8.2 备份方案
据《OpenClaw 备份与恢复指南》(https://github.com/lancelot3777-svg/openclaw-backup-guide),核心备份数据如下:
表格
自动备份脚本:
bash
#!/bin/bash
# openclaw-backup.sh — OpenClaw 自动备份脚本
# 建议加入 crontab: 0 3 * * * /opt/openclaw/openclaw-backup.sh
set -euo pipefail
# ===== 配置 =====
BACKUP_DIR="/opt/openclaw/backups"
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="openclaw-backup-${DATE}.tar.gz"
RETENTION_DAYS=30
# OpenClaw 数据路径(Docker 挂载的宿主机路径)
OPENCLAW_CONFIG="/opt/openclaw/openclaw-config"
OPENCLAW_WORKSPACE="/opt/openclaw/openclaw-workspace"
ENV_FILE="/opt/openclaw/.env"
# ===== 创建备份目录 =====
mkdir -p "$BACKUP_DIR"
# ===== SQLite 安全备份 =====
# 如果有 SQLite 数据库,使用 .backup API 而不是直接拷贝
# 直接拷贝正在使用的 SQLite 可能导致数据损坏
if command -v sqlite3 &>/dev/null; then
for db in "$OPENCLAW_CONFIG"/data/*.db; do
if [[ -f "$db" ]]; then
db_name=$(basename "$db")
sqlite3 "$db" ".backup '${BACKUP_DIR}/${db_name}.backup-${DATE}'"
fi
done
fi
# ===== 导出环境变量(脱敏) =====
ENV_BACKUP="/tmp/openclaw-env-${DATE}.txt"
if [[ -f "$ENV_FILE" ]]; then
# 复制 .env 但替换 API Key 为占位符
sed -E 's/(KEY=).+/\1 ***REDACTED***/g; s/(TOKEN=).+/\1 ***REDACTED***/g' \
"$ENV_FILE" > "$ENV_BACKUP"
fi
# ===== 创建压缩备份 =====
echo "[$(date)] 开始备份 OpenClaw..."
tar -czf "${BACKUP_DIR}/${BACKUP_FILE}" \
"$OPENCLAW_CONFIG" \
"$OPENCLAW_WORKSPACE" \
"$ENV_FILE" \
2>/dev/null || true
# 清理临时文件
rm -f "$ENV_BACKUP"
# ===== 备份验证 =====
BACKUP_SIZE=$(du -h "${BACKUP_DIR}/${BACKUP_FILE}" | cut -f1)
echo "[$(date)] 备份完成: ${BACKUP_FILE} (${BACKUP_SIZE})"
# ===== 清理过期备份 =====
find "$BACKUP_DIR" -name "openclaw-backup-*.tar.gz" -mtime +${RETENTION_DAYS} -delete
echo "[$(date)] 已清理 ${RETENTION_DAYS} 天前的备份"
# ===== 可选:上传到远程存储 =====
# 取消注释以下行来启用远程备份
# AWS S3:
# aws s3 cp "${BACKUP_DIR}/${BACKUP_FILE}" s3://your-bucket/openclaw-backups/
# 阿里云 OSS:
# ossutil cp "${BACKUP_DIR}/${BACKUP_FILE}" oss://your-bucket/openclaw-backups/
# Rsync 到另一台机器:
# rsync -avz "${BACKUP_DIR}/${BACKUP_FILE}" user@backup-server:/backups/openclaw/
设置定时备份:
bash
# 加入 crontab,每天凌晨 3 点执行
(crontab -l 2>/dev/null; echo "0 3 * * * /opt/openclaw/openclaw-backup.sh >> /opt/openclaw/backups/backup.log 2>&1") | crontab -
# 验证
crontab -l
8.3 监控方案
1. 健康检查
bash
# 简单的健康检查脚本
#!/bin/bash
# health-check.sh — OpenClaw 健康检查
GATEWAY_URL="http://localhost:18789"
ALERT_WEBHOOK="https://your-webhook-url" # 替换为你的告警地址
response=$(curl -sf -o /dev/null -w "%{http_code}" "${GATEWAY_URL}/healthz")
if [[ "$response" != "200" ]]; then
echo "[ALERT] OpenClaw Gateway 健康检查失败! HTTP ${response}"
# 发送告警(Telegram/Slack/DingTalk)
# curl -s -X POST "$ALERT_WEBHOOK" -d "OpenClaw Gateway DOWN! HTTP ${response}"
exit 1
fi
echo "[OK] OpenClaw Gateway 健康, HTTP ${response}"
2. Docker 内置健康检查
已在 docker-compose.yml 中配置。查看状态:
bash
docker inspect --format='{{.State.Health.Status}}' openclaw
# 应该返回 "healthy"
# 查看健康检查历史
docker inspect --format='{{range .State.Health.Log}}{{.Output}}{{end}}' openclaw
3. Prometheus 指标(可选)
如果需要接入 Prometheus 监控体系:
yaml
# docker-compose.yml 追加
prometheus:
image: prom/prometheus:latest
container_name: openclaw-prometheus
restart: unless-stopped
ports:
- "127.0.0.1:9090:9090"
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
- prometheus-data:/prometheus
volumes:
prometheus-data:
yaml
# prometheus.yml
global:
scrape_interval: 30s
scrape_configs:
- job_name: 'openclaw'
static_configs:
- targets: ['openclaw-gateway:18789']
metrics_path: /metrics
8.4 日志管理
Docker 日志轮转(已在 docker-compose.yml 中配置):
yaml
logging:
driver: json-file
options:
max-size: "10m" # 单个日志文件最大 10MB
max-file: "5" # 最多保留 5 个文件
集中式日志(Loki + Grafana) :
yaml
# docker-compose.yml 追加
loki:
image: grafana/loki:latest
container_name: openclaw-loki
restart: unless-stopped
ports:
- "127.0.0.1:3100:3100"
volumes:
- loki-data:/loki
grafana:
image: grafana/grafana:latest
container_name: openclaw-grafana
restart: unless-stopped
ports:
- "127.0.0.1:3001:3000"
volumes:
- grafana-data:/var/lib/grafana
depends_on:
- loki
volumes:
loki-data:
grafana-data:
日志查看命令速查:
bash
# Docker 部署
docker compose logs -f openclaw-gateway # 实时日志
docker compose logs --tail 100 openclaw-gateway # 最近 100 行
docker compose logs --since 1h openclaw-gateway # 最近 1 小时
# 裸机部署
journalctl --user -u openclaw-gateway -f # 实时日志
journalctl --user -u openclaw-gateway --since "1 hour ago"
journalctl --user -u openclaw-gateway --since today
# 搜索特定关键词
docker compose logs openclaw-gateway 2>&1 | grep -i "error"
docker compose logs openclaw-gateway 2>&1 | grep -i "channel.*connected"
九、一键部署脚本(完整版)
这是本文的重头戏——一个真的能跑的一键部署脚本。支持交互式选择渠道、模型、存储方式,自动检测环境,自动安装依赖。
bash
#!/bin/bash
# openclaw-setup.sh — OpenClaw 一键部署脚本
# 版本: 1.0.0
# 作者: PySuper | zhengxingtao.com
#
# 用法:
# chmod +x openclaw-setup.sh
# sudo ./openclaw-setup.sh
#
# 或一行命令:
# curl -fsSL https://your-host/openclaw-setup.sh | sudo bash
#
# 功能:
# 1. 检测系统环境(OS/内存/Docker/网络)
# 2. 安装依赖(Docker/Docker Compose/其他)
# 3. 生成配置文件(.env + docker-compose.yml)
# 4. 交互式选择:渠道/模型/存储
# 5. 拉取镜像并启动
# 6. 自动配置 Nginx + SSL(可选)
# 7. 健康检查和验证
# 8. 输出访问地址和管理命令
set -euo pipefail
# ========================================
# 全局变量和工具函数
# ========================================
SCRIPT_VERSION="1.0.0"
INSTALL_DIR="/opt/openclaw"
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
BOLD='\033[1m'
NC='\033[0m'
info() { echo -e "${GREEN}[INFO]${NC} $*"; }
warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
error() { echo -e "${RED}[ERROR]${NC} $*"; }
section() { echo -e "\n${CYAN}${BOLD}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"; echo -e "${CYAN}${BOLD} $*${NC}"; echo -e "${CYAN}${BOLD}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}\n"; }
# 交互式选择函数
ask_yes_no() {
local prompt="$1"
local default="${2:-Y}"
local yn=""
while true; do
echo -ne "${BLUE}?${NC} ${prompt} [${default}] "
read -r yn
yn=${yn:-$default}
case "$yn" in
[Yy]*) return 0 ;;
[Nn]*) return 1 ;;
*) echo "请输入 Y 或 N" ;;
esac
done
}
ask_input() {
local prompt="$1"
local default="$2"
local value=""
echo -ne "${BLUE}?${NC} ${prompt} [${default}] "
read -r value
echo "${value:-$default}"
}
ask_select() {
local prompt="$1"
shift
local options=("$@")
local i=1
echo -e "${BLUE}?${NC} ${prompt}"
for opt in "${options[@]}"; do
echo -e " ${CYAN}${i}${NC}) ${opt}"
((i++))
done
local choice=""
while true; do
echo -ne " 请选择 [1]: "
read -r choice
choice=${choice:-1}
if [[ "$choice" =~ ^[0-9]+$ ]] && [[ "$choice" -ge 1 ]] && [[ "$choice" -le "${#options[@]}" ]]; then
SELECTED_INDEX=$((choice - 1))
return 0
fi
echo " 无效选择,请重试"
done
}
# ========================================
# 第一步:系统检测
# ========================================
detect_system() {
section "第 1 步:系统环境检测"
# 检查 root
if [[ $EUID -ne 0 ]]; then
error "请使用 root 用户运行此脚本"
echo " sudo ./openclaw-setup.sh"
exit 1
fi
# 检测操作系统
if [[ -f /etc/os-release ]]; then
source /etc/os-release
OS_NAME="$NAME"
OS_VERSION="$VERSION_ID"
OS_ID="$ID"
info "操作系统: ${OS_NAME} ${OS_VERSION}"
elif [[ "$(uname)" == "Darwin" ]]; then
OS_NAME="macOS"
OS_ID="macos"
OS_VERSION="$(sw_vers -productVersion)"
info "操作系统: macOS ${OS_VERSION}"
warn "macOS 建议使用 Homebrew 安装,此脚本针对 Linux 优化"
else
error "无法检测操作系统"
exit 1
fi
# 检测架构
ARCH=$(uname -m)
info "系统架构: ${ARCH}"
# 检测内存
TOTAL_MEM_KB=$(grep MemTotal /proc/meminfo 2>/dev/null | awk '{print $2}' || echo "0")
TOTAL_MEM=$((TOTAL_MEM_KB / 1024))
info "内存: ${TOTAL_MEM}MB"
if [[ $TOTAL_MEM -lt 2000 ]]; then
warn "内存不足 2GB,OpenClaw 可能运行不稳定"
if ! ask_yes_no "是否继续?" "N"; then
exit 0
fi
fi
# 检测磁盘空间
DISK_AVAIL=$(df -BG / | awk 'NR==2 {print $4}' | tr -d 'G')
info "可用磁盘: ${DISK_AVAIL}GB"
if [[ $DISK_AVAIL -lt 10 ]]; then
warn "可用磁盘不足 10GB,建议清理空间"
fi
# 检测 Docker
if command -v docker &>/dev/null; then
DOCKER_VERSION=$(docker --version | grep -oP '\d+\.\d+\.\d+')
info "Docker: 已安装 (v${DOCKER_VERSION})"
HAS_DOCKER=true
else
info "Docker: 未安装"
HAS_DOCKER=false
fi
# 检测 Docker Compose
if docker compose version &>/dev/null 2>&1; then
COMPOSE_VERSION=$(docker compose version | grep -oP '\d+\.\d+\.\d+' || echo "unknown")
info "Docker Compose: 已安装 (v${COMPOSE_VERSION})"
HAS_COMPOSE=true
else
info "Docker Compose: 未安装"
HAS_COMPOSE=false
fi
# 检测网络
info "检测网络连通性..."
if curl -sf --connect-timeout 5 https://ghcr.io > /dev/null 2>&1; then
info "网络: 可访问 ghcr.io ✅"
NETWORK_OK=true
else
warn "网络: 无法访问 ghcr.io(可能需要配置代理)"
NETWORK_OK=false
fi
# 检测端口占用
PORT_18789_IN_USE=false
if ss -tlnp 2>/dev/null | grep -q ':18789 '; then
warn "端口 18789 已被占用"
PORT_18789_IN_USE=true
fi
info "系统检测完成"
}
# ========================================
# 第二步:安装依赖
# ========================================
install_dependencies() {
section "第 2 步:安装依赖"
# 安装 Docker
if [[ "$HAS_DOCKER" == "false" ]]; then
info "安装 Docker..."
if [[ "$OS_ID" == "ubuntu" ]] || [[ "$OS_ID" == "debian" ]]; then
apt-get update -qq
apt-get install -y curl
curl -fsSL https://get.docker.com | sh
systemctl enable docker
systemctl start docker
elif [[ "$OS_ID" == "fedora" ]] || [[ "$OS_ID" == "rhel" ]]; then
dnf install -y curl
curl -fsSL https://get.docker.com | sh
systemctl enable docker
systemctl start docker
else
error "不支持的操作系统: ${OS_ID},请手动安装 Docker"
exit 1
fi
info "Docker 安装完成: $(docker --version)"
HAS_DOCKER=true
fi
# 安装 Docker Compose
if [[ "$HAS_COMPOSE" == "false" ]]; then
info "安装 Docker Compose 插件..."
if [[ "$OS_ID" == "ubuntu" ]] || [[ "$OS_ID" == "debian" ]]; then
apt-get update -qq
apt-get install -y docker-compose-plugin
elif [[ "$OS_ID" == "fedora" ]] || [[ "$OS_ID" == "rhel" ]]; then
dnf install -y docker-compose-plugin
else
# 手动安装
mkdir -p /usr/local/lib/docker/cli-plugins
curl -SL "https://github.com/docker/compose/releases/latest/download/docker-compose-linux-$(uname -m)" \
-o /usr/local/lib/docker/cli-plugins/docker-compose
chmod +x /usr/local/lib/docker/cli-plugins/docker-compose
fi
HAS_COMPOSE=true
info "Docker Compose 安装完成"
fi
# 安装辅助工具
info "安装辅助工具 (curl, openssl)..."
if [[ "$OS_ID" == "ubuntu" ]] || [[ "$OS_ID" == "debian" ]]; then
apt-get install -y curl openssl
elif [[ "$OS_ID" == "fedora" ]] || [[ "$OS_ID" == "rhel" ]]; then
dnf install -y curl openssl
fi
info "依赖安装完成"
}
# ========================================
# 第三步:交互式配置
# ========================================
interactive_config() {
section "第 3 步:交互式配置"
# ----- 选择模型 -----
echo -e "${BOLD}选择 AI 模型 Provider:${NC}"
ask_select "选择你的主要 AI 模型 Provider" \
"Anthropic Claude (推荐)" \
"OpenAI GPT" \
"Google Gemini" \
"OpenRouter (多模型聚合)" \
"Ollama (本地模型,零 API 成本)" \
"混合模式 (API + 本地)"
MODEL_CHOICE=$SELECTED_INDEX
case $MODEL_CHOICE in
0) # Anthropic
ANTHROPIC_KEY=$(ask_input "输入 Anthropic API Key (sk-ant-...)" "")
DEFAULT_MODEL="anthropic/claude-sonnet-4-20250514"
MODEL_PROVIDER="anthropic"
;;
1) # OpenAI
OPENAI_KEY=$(ask_input "输入 OpenAI API Key (sk-...)" "")
DEFAULT_MODEL="openai/gpt-4o"
MODEL_PROVIDER="openai"
;;
2) # Google Gemini
GOOGLE_KEY=$(ask_input "输入 Google AI API Key (AIza...)" "")
DEFAULT_MODEL="google/gemini-2.5-pro"
MODEL_PROVIDER="google"
;;
3) # OpenRouter
OPENROUTER_KEY=$(ask_input "输入 OpenRouter API Key (sk-or-...)" "")
DEFAULT_MODEL="openrouter/anthropic/claude-sonnet-4-20250514"
MODEL_PROVIDER="openrouter"
;;
4) # Ollama
OLLAMA_KEY="ollama-local"
DEFAULT_MODEL="ollama/qwen2.5:7b"
MODEL_PROVIDER="ollama"
info "确保 Ollama 已安装并在 11434 端口运行"
;;
5) # 混合模式
ANTHROPIC_KEY=$(ask_input "输入 Anthropic API Key (留空跳过)" "")
OPENAI_KEY=$(ask_input "输入 OpenAI API Key (留空跳过)" "")
OLLAMA_KEY="ollama-local"
DEFAULT_MODEL="anthropic/claude-sonnet-4-20250514"
MODEL_PROVIDER="hybrid"
;;
esac
# ----- 选择渠道 -----
echo -e "\n${BOLD}选择消息渠道 (可多选):${NC}"
ENABLE_TELEGRAM=false
ENABLE_DISCORD=false
ENABLE_SLACK=false
if ask_yes_no "启用 Telegram Bot?" "Y"; then
ENABLE_TELEGRAM=true
TELEGRAM_TOKEN=$(ask_input "输入 Telegram Bot Token" "")
fi
if ask_yes_no "启用 Discord Bot?" "N"; then
ENABLE_DISCORD=true
DISCORD_TOKEN=$(ask_input "输入 Discord Bot Token" "")
fi
if ask_yes_no "启用 Slack?" "N"; then
ENABLE_SLACK=true
SLACK_APP_TOKEN=$(ask_input "输入 Slack App Token (xapp-...)" "")
SLACK_BOT_TOKEN=$(ask_input "输入 Slack Bot Token (xoxb-...)" "")
fi
# ----- 存储配置 -----
echo -e "\n${BOLD}存储配置:${NC}"
INSTALL_DIR=$(ask_input "安装目录" "/opt/openclaw")
# ----- Nginx + SSL -----
SETUP_NGINX=false
if ask_yes_no "配置 Nginx 反向代理 + SSL?(生产环境推荐)" "N"; then
SETUP_NGINX=true
DOMAIN=$(ask_input "输入域名 (如 openclaw.example.com)" "")
fi
# ----- 月度预算 -----
MAX_SPEND=$(ask_input "月度 API 消费上限 (美元,0=不限制)" "50")
}
# ========================================
# 第四步:生成配置文件
# ========================================
generate_configs() {
section "第 4 步:生成配置文件"
# 创建目录
mkdir -p "${INSTALL_DIR}"/{openclaw-config,openclaw-workspace,backups}
cd "$INSTALL_DIR"
# 生成 Gateway Token
GATEWAY_TOKEN=$(openssl rand -hex 32)
info "Gateway Token: ${GATEWAY_TOKEN}"
# 生成 .env
info "生成 .env 文件..."
cat > .env << EOF
# ============================================
# OpenClaw 环境变量配置
# 由 openclaw-setup.sh v${SCRIPT_VERSION} 自动生成
# 生成时间: $(date)
# ============================================
# Gateway 认证
OPENCLAW_GATEWAY_TOKEN=${GATEWAY_TOKEN}
# 模型 Provider
EOF
# 根据选择写入 API Key
case $MODEL_PROVIDER in
anthropic)
echo "ANTHROPIC_API_KEY=${ANTHROPIC_KEY}" >> .env
;;
openai)
echo "OPENAI_API_KEY=${OPENAI_KEY}" >> .env
;;
google)
echo "GOOGLE_AI_API_KEY=${GOOGLE_KEY}" >> .env
;;
openrouter)
echo "OPENROUTER_API_KEY=${OPENROUTER_KEY}" >> .env
;;
ollama)
echo "OLLAMA_API_KEY=ollama-local" >> .env
;;
hybrid)
[[ -n "$ANTHROPIC_KEY" ]] && echo "ANTHROPIC_API_KEY=${ANTHROPIC_KEY}" >> .env
[[ -n "$OPENAI_KEY" ]] && echo "OPENAI_API_KEY=${OPENAI_KEY}" >> .env
echo "OLLAMA_API_KEY=ollama-local" >> .env
;;
esac
# 写入渠道 Token
cat >> .env << EOF
# 消息渠道
EOF
[[ "$ENABLE_TELEGRAM" == "true" ]] && echo "TELEGRAM_BOT_TOKEN=${TELEGRAM_TOKEN}" >> .env
[[ "$ENABLE_DISCORD" == "true" ]] && echo "DISCORD_BOT_TOKEN=${DISCORD_TOKEN}" >> .env
[[ "$ENABLE_SLACK" == "true" ]] && cat >> .env << EOF
SLACK_APP_TOKEN=${SLACK_APP_TOKEN}
SLACK_BOT_TOKEN=${SLACK_BOT_TOKEN}
EOF
# 写入可选配置
cat >> .env << EOF
# 可选配置
TZ=Asia/Shanghai
NODE_ENV=production
EOF
[[ "$MAX_SPEND" != "0" ]] && echo "MAX_MONTHLY_SPEND=${MAX_SPEND}" >> .env
chmod 600 .env
info ".env 文件已生成"
# 生成 docker-compose.yml
info "生成 docker-compose.yml..."
cat > docker-compose.yml << 'COMPOSE'
version: "3.8"
services:
openclaw-gateway:
image: ghcr.io/openclaw/openclaw:latest
container_name: openclaw
restart: unless-stopped
ports:
- "18789:18789"
- "18793:18793"
volumes:
- ./openclaw-config:/root/.openclaw
- ./openclaw-workspace:/root/workspace
env_file:
- .env
environment:
- NODE_ENV=production
- TZ=Asia/Shanghai
depends_on:
redis:
condition: service_healthy
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:18789/healthz"]
interval: 30s
timeout: 10s
retries: 3
start_period: 30s
deploy:
resources:
limits:
cpus: "2"
memory: 2G
reservations:
cpus: "0.5"
memory: 512M
logging:
driver: json-file
options:
max-size: "10m"
max-file: "5"
command: openclaw gateway
redis:
image: redis:7-alpine
container_name: openclaw-redis
restart: unless-stopped
ports:
- "127.0.0.1:6379:6379"
volumes:
- redis-data:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 3
deploy:
resources:
limits:
memory: 256M
volumes:
redis-data:
driver: local
COMPOSE
info "docker-compose.yml 已生成"
# 生成 openclaw.json
info "生成 openclaw.json..."
cat > openclaw-config/openclaw.json << JSON
{
"gateway": {
"bind": "loopback",
"port": 18789,
"trustedProxies": ["127.0.0.1", "172.16.0.0/12"],
"auth": {
"mode": "token",
"token": "\${OPENCLAW_GATEWAY_TOKEN}"
}
},
"agents": {
"defaults": {
"model": {
"primary": "${DEFAULT_MODEL}"
JSON
# 混合模式添加回退
if [[ "$MODEL_PROVIDER" == "hybrid" ]]; then
cat >> openclaw-config/openclaw.json << 'JSON'
,
"fallbacks": ["openai/gpt-4o", "openai/gpt-4o-mini", "ollama/qwen2.5:7b"]
JSON
fi
cat >> openclaw-config/openclaw.json << 'JSON'
}
}
},
"skills": {
"autoUpdate": false,
"updateNotify": true
}
}
JSON
info "openclaw.json 已生成"
# 生成备份脚本
info "生成备份脚本..."
cat > openclaw-backup.sh << 'BACKUP'
#!/bin/bash
# OpenClaw 自动备份脚本
set -euo pipefail
BACKUP_DIR="BACKUP_DIR_PLACEHOLDER/backups"
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="openclaw-backup-${DATE}.tar.gz"
RETENTION_DAYS=30
mkdir -p "$BACKUP_DIR"
tar -czf "${BACKUP_DIR}/${BACKUP_FILE}" \
BACKUP_DIR_PLACEHOLDER/openclaw-config \
BACKUP_DIR_PLACEHOLDER/openclaw-workspace \
BACKUP_DIR_PLACEHOLDER/.env \
2>/dev/null || true
find "$BACKUP_DIR" -name "openclaw-backup-*.tar.gz" -mtime +${RETENTION_DAYS} -delete
BACKUP_SIZE=$(du -h "${BACKUP_DIR}/${BACKUP_FILE}" | cut -f1)
echo "[$(date)] 备份完成: ${BACKUP_FILE} (${BACKUP_SIZE})"
BACKUP
# 替换占位符
sed -i "s|BACKUP_DIR_PLACEHOLDER|${INSTALL_DIR}|g" openclaw-backup.sh
chmod +x openclaw-backup.sh
# 加入 crontab
(crontab -l 2>/dev/null | grep -v "openclaw-backup"; echo "0 3 * * * ${INSTALL_DIR}/openclaw-backup.sh >> ${INSTALL_DIR}/backups/backup.log 2>&1") | crontab -
info "自动备份已配置(每天凌晨 3 点)"
info "配置文件生成完成"
}
# ========================================
# 第五步:拉取镜像并启动
# ========================================
start_services() {
section "第 5 步:拉取镜像并启动"
cd "$INSTALL_DIR"
info "拉取 OpenClaw 镜像(可能需要几分钟)..."
docker compose pull
info "启动服务..."
docker compose up -d
info "等待服务就绪..."
local retry=0
local max_retry=30
while [[ $retry -lt $max_retry ]]; do
if curl -sf http://localhost:18789/healthz > /dev/null 2>&1; then
info "Gateway 已就绪 ✅"
break
fi
((retry++))
echo -n "."
sleep 2
done
echo ""
if [[ $retry -eq $max_retry ]]; then
warn "Gateway 未在预期时间内就绪,请查看日志:"
echo " docker compose -f ${INSTALL_DIR}/docker-compose.yml logs -f openclaw-gateway"
fi
}
# ========================================
# 第六步:配置 Nginx + SSL(可选)
# ========================================
setup_nginx_ssl() {
if [[ "$SETUP_NGINX" != "true" ]]; then
return 0
fi
section "第 6 步:配置 Nginx + SSL"
if [[ -z "$DOMAIN" ]]; then
warn "未提供域名,跳过 Nginx + SSL 配置"
return 0
fi
# 安装 Nginx 和 Certbot
info "安装 Nginx 和 Certbot..."
if [[ "$OS_ID" == "ubuntu" ]] || [[ "$OS_ID" == "debian" ]]; then
apt-get install -y nginx certbot python3-certbot-nginx
elif [[ "$OS_ID" == "fedora" ]] || [[ "$OS_ID" == "rhel" ]]; then
dnf install -y nginx certbot python3-certbot-nginx
fi
# 创建 Nginx 配置
info "创建 Nginx 配置..."
cat > /etc/nginx/sites-available/openclaw.conf << NGINX
server {
listen 80;
listen [::]:80;
server_name ${DOMAIN};
location /.well-known/acme-challenge/ {
root /var/www/html;
}
location / {
return 301 https://\$host\$request_uri;
}
}
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name ${DOMAIN};
ssl_certificate /etc/letsencrypt/live/${DOMAIN}/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/${DOMAIN}/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
ssl_prefer_server_ciphers on;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
server_tokens off;
location / {
proxy_pass http://127.0.0.1:18789;
proxy_http_version 1.1;
proxy_set_header Upgrade \$http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Forwarded-For \$remote_addr;
proxy_set_header X-Forwarded-Proto \$scheme;
proxy_set_header Host \$host;
proxy_read_timeout 86400s;
proxy_send_timeout 86400s;
}
}
NGINX
# 启用站点
ln -sf /etc/nginx/sites-available/openclaw.conf /etc/nginx/sites-enabled/
rm -f /etc/nginx/sites-enabled/default
# 先用 HTTP 模式获取证书
info "获取 SSL 证书..."
nginx -t && systemctl reload nginx
if certbot --nginx -d "$DOMAIN" --non-interactive --agree-tos --register-unsafely-without-email 2>/dev/null; then
info "SSL 证书获取成功 ✅"
systemctl reload nginx
else
warn "SSL 证书获取失败,请确保域名已正确解析到本服务器"
warn "你可以稍后手动运行: certbot --nginx -d ${DOMAIN}"
fi
# 防火墙
if command -v ufw &>/dev/null; then
ufw allow 80/tcp
ufw allow 443/tcp
ufw --force enable
fi
info "Nginx + SSL 配置完成"
}
# ========================================
# 第七步:健康检查和验证
# ========================================
health_check() {
section "第 7 步:健康检查"
cd "$INSTALL_DIR"
# 容器状态
info "检查容器状态..."
docker compose ps
# 健康检查
info "检查 Gateway 健康..."
local health_status
health_status=$(docker inspect --format='{{.State.Health.Status}}' openclaw 2>/dev/null || echo "unknown")
if [[ "$health_status" == "healthy" ]]; then
info "Gateway: 健康 ✅"
else
warn "Gateway 状态: ${health_status}(可能需要等待启动完成)"
fi
# Redis
info "检查 Redis..."
if docker exec openclaw-redis redis-cli ping 2>/dev/null | grep -q "PONG"; then
info "Redis: 正常 ✅"
else
warn "Redis: 未响应"
fi
# 磁盘使用
info "磁盘使用:"
df -h "$INSTALL_DIR" | tail -1 | awk '{print " 已用: "$3" / 总量: "$2" ("$5")"}'
}
# ========================================
# 第八步:输出部署信息
# ========================================
print_summary() {
section "部署完成!"
PUBLIC_IP=$(curl -sf --connect-timeout 5 ifconfig.me 2>/dev/null || echo "YOUR_SERVER_IP")
if [[ "$SETUP_NGINX" == "true" ]] && [[ -n "$DOMAIN" ]]; then
ACCESS_URL="https://${DOMAIN}"
else
ACCESS_URL="http://${PUBLIC_IP}:18789"
fi
cat << SUMMARY
${GREEN}${BOLD}🦞 OpenClaw 部署成功!${NC}
${BOLD}访问信息:${NC}
┌─────────────────────────────────────────────────────┐
│ Control UI: ${CYAN}${ACCESS_URL}${NC}
│ Gateway Token: ${CYAN}${GATEWAY_TOKEN}${NC}
│ 安装目录: ${INSTALL_DIR}
└─────────────────────────────────────────────────────┘
${BOLD}常用命令:${NC}
┌─────────────────────────────────────────────────────┐
│ 启动: cd ${INSTALL_DIR} && docker compose up -d
│ 停止: cd ${INSTALL_DIR} && docker compose stop
│ 重启: cd ${INSTALL_DIR} && docker compose restart
│ 日志: cd ${INSTALL_DIR} && docker compose logs -f
│ 状态: cd ${INSTALL_DIR} && docker compose ps
│ 更新: cd ${INSTALL_DIR} && docker compose pull && docker compose up -d
│ 备份: ${INSTALL_DIR}/openclaw-backup.sh
└─────────────────────────────────────────────────────┘
${BOLD}下一步:${NC}
1. 打开浏览器访问 Control UI
2. 输入 Gateway Token 登录
3. 运行 onboarding: docker compose run --rm openclaw-gateway openclaw onboard
4. 安装 Skill: npx clawhub@latest install web-browsing
5. 在 Telegram/Discord 中给你的 Bot 发消息测试
${BOLD}文档:${NC}
- 官方文档: https://docs.openclaw.ai
- ClawHub: https://clawhub.ai
- 博客: https://zhengxingtao.com
${YELLOW}${BOLD}安全提醒:${NC}
- 保管好 Gateway Token 和 API Key
- Skill 自动更新已关闭,更新前请审查
- 生产环境务必启用 HTTPS
SUMMARY
}
# ========================================
# 主流程
# ========================================
main() {
echo -e "${CYAN}${BOLD}"
echo " ╔══════════════════════════════════════════╗"
echo " ║ 🦞 OpenClaw 一键部署脚本 v${SCRIPT_VERSION} ║"
echo " ║ zhengxingtao.com | PySuper ║"
echo " ╚══════════════════════════════════════════╝"
echo -e "${NC}"
detect_system
install_dependencies
interactive_config
generate_configs
start_services
setup_nginx_ssl
health_check
print_summary
}
main "$@"
使用方式:
bash
# 方式一:下载后运行
curl -fsSL https://your-host/openclaw-setup.sh -o openclaw-setup.sh
chmod +x openclaw-setup.sh
sudo ./openclaw-setup.sh
# 方式二:一行命令运行
curl -fsSL https://your-host/openclaw-setup.sh | sudo bash
十、常见问题排查
10.1 端口冲突
症状:启动失败,日志显示 EADDRINUSE 或 port already in use。
bash
# 查看占用 18789 端口的进程
sudo lsof -i :18789
# 或
sudo ss -tlnp | grep 18789
# 解决方案 1:杀掉占用进程
sudo kill -9 <PID>
# 解决方案 2:改 OpenClaw 端口
# 在 .env 中添加:
OPENCLAW_PORT=28789
# 同时修改 docker-compose.yml 的 ports 映射
# 解决方案 3:Docker 容器残留
docker rm -f openclaw 2>/dev/null
docker compose up -d
10.2 Docker 权限问题
症状:permission denied while trying to connect to the Docker daemon socket。
bash
# 把当前用户加入 docker 组
sudo usermod -aG docker $USER
# 重新登录或执行
newgrp docker
# 验证
docker ps
# 如果还不行,检查 Docker socket 权限
ls -la /var/run/docker.sock
# 应该是 srw-rw---- root docker
# 临时方案(不推荐,安全风险)
sudo chmod 666 /var/run/docker.sock
10.3 模型连接失败
症状:Bot 能收到消息但不回复,或回复错误信息。
bash
# 1. 检查 API Key 是否正确
docker compose exec openclaw-gateway env | grep API_KEY
# 2. 测试 API 连通性
# Anthropic
curl -s https://api.anthropic.com/v1/messages \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d '{"model":"claude-sonnet-4-20250514","max_tokens":10,"messages":[{"role":"user","content":"hi"}]}' | head -20
# OpenAI
curl -s https://api.openai.com/v1/chat/completions \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-H "content-type: application/json" \
-d '{"model":"gpt-4o-mini","max_tokens":10,"messages":[{"role":"user","content":"hi"}]}' | head -20
# 3. Ollama 连接问题
curl http://localhost:11434/api/tags # 宿主机上
curl http://host.docker.internal:11434/api/tags # Docker 容器内(macOS)
# Linux Docker 中访问宿主机 Ollama:
# 用 ip route | grep default | awk '{print $9}' 获取宿主机 IP
# 4. 检查模型配置
docker compose exec openclaw-gateway openclaw models list
# 5. 常见错误码
# 401: API Key 无效或过期
# 429: 速率限制,等一会儿再试
# 500/503: 模型服务端问题,检查模型回退配置
10.4 渠道 Webhook 不通
症状:Bot 在平台上显示在线,但收不到消息。
bash
# Telegram: 不需要 Webhook,用 Polling
# 确认 Token 正确:
curl https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/getMe
# 应该返回 bot 信息
# Discord: 需要 MESSAGE CONTENT INTENT
# 检查 Developer Portal → Bot → Privileged Gateway Intents
# MESSAGE CONTENT INTENT 必须开启
# Slack: 检查 Socket Mode
# 确认 App-Level Token (xapp-) 和 Bot Token (xoxb-) 都配置了
# 检查 Event Subscriptions 是否订阅了 message.* 事件
# 通用:查看 Gateway 日志中的渠道连接状态
docker compose logs openclaw-gateway 2>&1 | grep -i "channel\|connect\|error"
10.5 内存不足 OOM
症状:容器突然退出,日志显示 OOMKilled。
bash
# 检查容器是否被 OOM Kill
docker inspect openclaw --format='{{.State.OOMKilled}}'
# 查看内存使用
docker stats openclaw --no-stream
# 解决方案 1:增加内存限制
# 修改 docker-compose.yml:
# deploy:
# resources:
# limits:
# memory: 4G # 从 2G 提高到 4G
# 解决方案 2:减少会话上下文长度
# 在 openclaw.json 中:
# {
# "agents": {
# "defaults": {
# "contextWindow": 4096 # 减小上下文窗口
# }
# }
# }
# 解决方案 3:增加 swap
sudo fallocate -l 4G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
# 解决方案 4:清理 Docker 资源
docker system prune -a --volumes # ⚠️ 会删除所有未使用的容器和镜像
10.6 日志查看命令速查表
bash
# ============================================
# OpenClaw 日志查看命令速查
# ============================================
# --- Docker 部署 ---
# 实时跟踪日志
docker compose logs -f openclaw-gateway
# 最近 N 行
docker compose logs --tail 100 openclaw-gateway
# 最近时间段
docker compose logs --since 30m openclaw-gateway
docker compose logs --since 2h openclaw-gateway
# 搜索错误
docker compose logs openclaw-gateway 2>&1 | grep -i "error"
docker compose logs openclaw-gateway 2>&1 | grep -i "crash"
docker compose logs openclaw-gateway 2>&1 | grep -i "timeout"
# 搜索渠道相关
docker compose logs openclaw-gateway 2>&1 | grep -i "telegram"
docker compose logs openclaw-gateway 2>&1 | grep -i "discord"
docker compose logs openclaw-gateway 2>&1 | grep -i "channel.*connect"
# 搜索模型调用
docker compose logs openclaw-gateway 2>&1 | grep -i "model\|llm\|completion"
docker compose logs openclaw-gateway 2>&1 | grep -i "rate.limit\|429"
# 容器事件
docker events --filter container=openclaw
# --- 裸机部署 ---
# 实时日志
journalctl --user -u openclaw-gateway -f
# 最近 100 行
journalctl --user -u openclaw-gateway -n 100
# 时间范围
journalctl --user -u openclaw-gateway --since "1 hour ago"
journalctl --user -u openclaw-gateway --since today
# 搜索
journalctl --user -u openclaw-gateway | grep -i "error"
journalctl --user -u openclaw-gateway | grep -i "gateway.*listen"
# --- 通用 ---
# 检查 Gateway 是否在监听
curl -s http://localhost:18789/healthz
# 检查进程
ps aux | grep openclaw
# 检查端口
ss -tlnp | grep 18789
# 磁盘使用
du -sh /opt/openclaw/*/
# Docker 磁盘使用
docker system df
附录
A. 环境变量完整参考
表格
* 至少需要一个模型 Provider 的 API Key
B. 常用端口速查
表格
C. 版本升级流程
bash
# 1. 备份
/opt/openclaw/openclaw-backup.sh
# 2. 拉取最新镜像
cd /opt/openclaw
docker compose pull
# 3. 滚动升级(停机时间 < 10 秒)
docker compose up -d
# 4. 验证
docker compose ps
curl -s http://localhost:18789/healthz
# 5. 查看变更日志
docker compose logs --tail 20 openclaw-gateway
# 如果升级出问题,回滚:
docker compose down
# 修改 image tag 到上一个版本
docker compose up -d
# 或从备份恢复
D. 相关资源
表格
作者:PySuper | 来源:zhengxingtao.com
本文是 #47 OpenClaw 实战文章的部署篇,专注于"怎么跑起来"和"怎么跑得稳"。如果你想了解 OpenClaw 的架构设计、Skill 系统和日常使用,请看上一篇。
有问题?在博客评论区讨论,或者直接来 Telegram 群组找我们。
评论区