Files
clawpanel/scripts/linux-deploy.sh
晴天 3687e26d5d feat: 飞书官方插件迁移 + 配对审批 + Gateway防卡死 + 微信升级修复 + 更新检测修复
- 飞书渠道从 @openclaw/feishu 迁移到 @larksuite/openclaw-lark 官方插件
- 保存飞书配置时自动禁用旧 feishu 插件,防止新旧插件冲突
- 所有主要渠道(飞书/Telegram/Discord/Slack)启用配对审批UI
- gateway_command 增加20s超时,超时后force-kill+fresh start
- 全平台启动前端口占用检查,防止Guardian无限拉起
- Linux gateway_command 补齐 Duration 导入和 cleanup_zombie 实现
- Guardian自动守护在Tauri桌面端也启用,轮询间隔30s→15s
- 微信渠道:升级操作不再弹出扫码二维码,按钮文案区分安装/升级
- 版本更新检测:CI不再将minAppVersion写死为当前版本
- 部署脚本增强OpenClaw检测,支持已安装的官方版
- 日间/夜间模式圆形扩散切换动画(View Transitions API)
- API错误信息完整展示(429限流等),URL自动转可点击链接
- 第三方API接入引导优化:移除内置密钥,引导式流程
- 修复全平台 Clippy 警告(strip_prefix/dead_code/unnecessary_unwrap等)
- Rust代码格式化修复(cargo fmt)
- toast组件支持HTML内容渲染
- Rust后端test_model返回详细错误信息
2026-03-23 21:51:34 +08:00

371 lines
11 KiB
Bash
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
set -e
echo "=========================================="
echo " ClawPanel Web 版 一键部署脚本"
echo " 在 Linux 上通过浏览器管理 OpenClaw"
echo "=========================================="
echo ""
PANEL_PORT=1420
REPO_URL="https://github.com/qingchencloud/clawpanel.git"
REPO_URL_GITEE="https://gitee.com/QtCodeCreators/clawpanel.git"
NPM_REGISTRY="https://registry.npmmirror.com"
# 检测权限模式
if [ "$(id -u)" = "0" ]; then
IS_ROOT=true
INSTALL_DIR="/opt/clawpanel"
SYSTEMD_DIR="/etc/systemd/system"
echo "🔑 以 root 身份运行,安装到 $INSTALL_DIR"
else
IS_ROOT=false
INSTALL_DIR="$HOME/.local/share/clawpanel"
SYSTEMD_DIR="$HOME/.config/systemd/user"
echo "👤 以普通用户身份运行,安装到 $INSTALL_DIR"
fi
# 带权限执行(安装系统包时需要)
run_pkg_cmd() {
if [ "$IS_ROOT" = true ]; then
"$@"
else
sudo "$@"
fi
}
# 检测系统
detect_os() {
if [ -f /etc/os-release ]; then
. /etc/os-release
OS=$ID
OS_LIKE=$ID_LIKE
elif [ -f /etc/redhat-release ]; then
OS="centos"
else
OS=$(uname -s | tr '[:upper:]' '[:lower:]')
fi
ARCH=$(uname -m)
echo "🖥️ 系统: $OS $ARCH"
# ARM 架构检测和提示
case "$ARCH" in
aarch64|arm64)
echo "✅ ARM64 架构Web 模式和 Docker 模式均支持"
;;
armv7*|armhf)
echo "⚠️ ARM 32位 ($ARCH)Web 模式可用Docker 镜像仅支持 arm64"
;;
armv6*)
echo "⚠️ ARM v6 ($ARCH):内存和性能可能不足,建议升级到 ARM64 设备"
;;
x86_64|amd64)
;;
*)
echo " 架构: $ARCH"
;;
esac
}
# 安装 Node.js
install_node() {
if command -v node &> /dev/null; then
local node_major=$(node -v | sed 's/v//' | cut -d. -f1)
if [ "$node_major" -ge 18 ]; then
echo "✅ Node.js $(node -v) 已安装"
return 0
else
echo "⚠️ Node.js $(node -v) 版本过低,需要 18+"
fi
fi
echo "📦 安装 Node.js 22 LTS..."
case "$OS" in
ubuntu|debian|linuxmint|pop)
curl -fsSL https://deb.nodesource.com/setup_22.x | run_pkg_cmd bash -
run_pkg_cmd apt-get install -y nodejs
;;
centos|rhel|fedora|rocky|alma)
curl -fsSL https://rpm.nodesource.com/setup_22.x | run_pkg_cmd bash -
run_pkg_cmd yum install -y nodejs
;;
alpine)
run_pkg_cmd apk add nodejs npm git
;;
arch|manjaro)
run_pkg_cmd pacman -Sy --noconfirm nodejs npm git
;;
*)
echo "❌ 不支持自动安装 Node.js请手动安装后重试"
echo " 参考: https://nodejs.org/en/download/"
exit 1
;;
esac
echo "✅ Node.js $(node -v) 安装完成"
}
# 安装 Git
install_git() {
if command -v git &> /dev/null; then
echo "✅ Git 已安装"
return 0
fi
echo "📦 安装 Git..."
case "$OS" in
ubuntu|debian|linuxmint|pop)
run_pkg_cmd apt-get update && run_pkg_cmd apt-get install -y git
;;
centos|rhel|fedora|rocky|alma)
run_pkg_cmd yum install -y git
;;
alpine)
run_pkg_cmd apk add git
;;
arch|manjaro)
run_pkg_cmd pacman -Sy --noconfirm git
;;
esac
echo "✅ Git 安装完成"
}
# 查找 openclaw 可执行文件(兼容各种安装方式)
find_openclaw() {
# 1. 直接在 PATH 中查找
if command -v openclaw &> /dev/null; then
echo "$(command -v openclaw)"
return 0
fi
# 2. 常见 npm 全局安装路径
local candidates=(
"/usr/local/bin/openclaw"
"/usr/bin/openclaw"
"$HOME/.npm-global/bin/openclaw"
"$HOME/.local/bin/openclaw"
)
# 3. 从 npm prefix 获取(不使用 sudo避免触发密码提示
local npm_prefix=$(npm config get prefix 2>/dev/null)
if [ -n "$npm_prefix" ]; then
candidates+=("$npm_prefix/bin/openclaw")
fi
for p in "${candidates[@]}"; do
if [ -x "$p" ]; then
echo "$p"
return 0
fi
done
return 1
}
# 检测 OpenClaw 版本来源(官方 vs 汉化版)
detect_openclaw_source() {
local oc_bin="$1"
local ver=$("$oc_bin" --version 2>/dev/null || echo "")
if echo "$ver" | grep -qi "zh\|汉化\|chinese"; then
echo "chinese"
else
echo "official"
fi
}
# 安装 OpenClaw
install_openclaw() {
local oc_path=$(find_openclaw)
if [ -n "$oc_path" ]; then
local oc_ver=$("$oc_path" --version 2>/dev/null || echo "未知版本")
local oc_src=$(detect_openclaw_source "$oc_path")
if [ "$oc_src" = "chinese" ]; then
echo "✅ OpenClaw 汉化版已安装: $oc_ver (${oc_path})"
else
echo "✅ OpenClaw 已安装: $oc_ver (${oc_path})"
fi
# 确保 openclaw 在 PATH 中(防止后续步骤找不到)
if ! command -v openclaw &> /dev/null; then
export PATH="$(dirname "$oc_path"):$PATH"
echo " 已将 $(dirname "$oc_path") 加入 PATH"
fi
else
echo "📦 安装 OpenClaw 汉化版..."
if [ "$IS_ROOT" = true ]; then
npm install -g @qingchencloud/openclaw-zh --registry "$NPM_REGISTRY" || \
npm install -g @qingchencloud/openclaw-zh --registry https://registry.npmjs.org
else
sudo -E npm install -g @qingchencloud/openclaw-zh --registry "$NPM_REGISTRY" || \
sudo -E npm install -g @qingchencloud/openclaw-zh --registry https://registry.npmjs.org
fi
echo "✅ OpenClaw 安装完成"
fi
# 初始化配置(如果不存在)
if [ ! -f "$HOME/.openclaw/openclaw.json" ]; then
echo "🔧 初始化 OpenClaw 配置..."
openclaw init 2>/dev/null || true
fi
}
# 克隆并安装 ClawPanel
install_clawpanel() {
if [ -d "$INSTALL_DIR" ] && [ -f "$INSTALL_DIR/package.json" ]; then
echo "📦 ClawPanel 已存在,更新中..."
cd "$INSTALL_DIR"
git pull origin main 2>/dev/null || true
npm install --registry "$NPM_REGISTRY"
else
echo "📦 克隆 ClawPanel..."
mkdir -p "$INSTALL_DIR"
if ! git clone "$REPO_URL" "$INSTALL_DIR" 2>/dev/null; then
echo "⚠️ GitHub 克隆失败,切换到 Gitee 国内镜像..."
git clone "$REPO_URL_GITEE" "$INSTALL_DIR"
fi
cd "$INSTALL_DIR"
npm install --registry "$NPM_REGISTRY"
fi
# 生产构建(生成优化后的静态文件)
echo "📦 构建生产版本..."
cd "$INSTALL_DIR"
npx vite build
echo "✅ ClawPanel 安装完成: $INSTALL_DIR"
echo "✅ 启动命令: npm run serve"
}
# 创建 systemd 服务
setup_systemd() {
if ! command -v systemctl &> /dev/null; then
echo "⚠️ systemd 不可用,请手动启动:"
echo " cd $INSTALL_DIR && npm run serve -- --port $PANEL_PORT"
return 0
fi
echo "🔧 创建 systemd 服务..."
mkdir -p "$SYSTEMD_DIR"
if [ "$IS_ROOT" = true ]; then
cat > "$SYSTEMD_DIR/clawpanel.service" << EOF
[Unit]
Description=ClawPanel Web - OpenClaw Management Panel
After=network.target
[Service]
Type=simple
User=$(whoami)
WorkingDirectory=$INSTALL_DIR
ExecStart=$(which node) scripts/serve.js --port $PANEL_PORT
Restart=on-failure
RestartSec=5
Environment=NODE_ENV=production
Environment=HOME=$HOME
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable clawpanel
systemctl start clawpanel
else
cat > "$SYSTEMD_DIR/clawpanel.service" << EOF
[Unit]
Description=ClawPanel Web - OpenClaw Management Panel
After=network.target
[Service]
Type=simple
WorkingDirectory=$INSTALL_DIR
ExecStart=$(which node) scripts/serve.js --port $PANEL_PORT
Restart=on-failure
RestartSec=5
Environment=NODE_ENV=production
Environment=HOME=$HOME
[Install]
WantedBy=default.target
EOF
systemctl --user daemon-reload
systemctl --user enable clawpanel
systemctl --user start clawpanel
# 允许用户服务在未登录时继续运行
loginctl enable-linger "$(whoami)" 2>/dev/null || true
fi
echo "✅ systemd 服务已创建并启动"
}
# 获取本机 IP
get_local_ip() {
ip route get 1 2>/dev/null | awk '{print $7; exit}' || \
hostname -I 2>/dev/null | awk '{print $1}' || \
echo "localhost"
}
# 生成默认访问密码
setup_default_password() {
local config_dir="$HOME/.openclaw"
local config_file="$config_dir/clawpanel.json"
mkdir -p "$config_dir"
# 已存在配置且有密码则跳过
if [ -f "$config_file" ]; then
local existing_pw=$(grep -o '"accessPassword"[[:space:]]*:[[:space:]]*"[^"]*"' "$config_file" | head -1)
if [ -n "$existing_pw" ]; then
echo " 已有访问密码,跳过生成"
DEFAULT_PASSWORD=""
return
fi
fi
DEFAULT_PASSWORD="123456"
cat > "$config_file" <<EOF
{
"accessPassword": "123456",
"mustChangePassword": true
}
EOF
echo "✅ 已设置默认访问密码: 123456"
}
# 主流程
main() {
detect_os
echo ""
install_git
install_node
install_openclaw
install_clawpanel
setup_default_password
setup_systemd
local ip=$(get_local_ip)
if [ "$IS_ROOT" = true ]; then
local ctl_cmd="systemctl"
else
local ctl_cmd="systemctl --user"
fi
echo ""
echo "=========================================="
echo " ✅ ClawPanel Web 版部署完成!"
echo "=========================================="
echo ""
echo " 🌐 访问地址: http://${ip}:${PANEL_PORT}"
echo " 📁 安装目录: $INSTALL_DIR"
echo " 📋 配置目录: $HOME/.openclaw/"
if [ -n "$DEFAULT_PASSWORD" ]; then
echo ""
echo " 🔑 默认访问密码: $DEFAULT_PASSWORD"
echo " ⚠️ 首次登录后会要求修改密码,请妥善保管新密码!"
fi
echo ""
echo " 常用命令:"
echo " $ctl_cmd status clawpanel # 查看状态"
echo " $ctl_cmd restart clawpanel # 重启面板"
if [ "$IS_ROOT" = true ]; then
echo " journalctl -u clawpanel -f # 查看日志"
else
echo " journalctl --user -u clawpanel -f # 查看日志"
fi
echo ""
echo " 用浏览器打开上面的地址,即可管理 OpenClaw。"
echo "=========================================="
}
main "$@"