189 lines
6.0 KiB
Bash
189 lines
6.0 KiB
Bash
#!/bin/bash
|
||
# ============================================================
|
||
# autoClaude-TGbot 一键部署脚本
|
||
# 用法: chmod +x deploy.sh && sudo ./deploy.sh
|
||
# ============================================================
|
||
|
||
set -e
|
||
|
||
# --- 颜色 ---
|
||
RED='\033[0;31m'
|
||
GREEN='\033[0;32m'
|
||
YELLOW='\033[1;33m'
|
||
CYAN='\033[0;36m'
|
||
NC='\033[0m'
|
||
|
||
info() { echo -e "${CYAN}[INFO]${NC} $1"; }
|
||
ok() { echo -e "${GREEN}[✔]${NC} $1"; }
|
||
warn() { echo -e "${YELLOW}[!]${NC} $1"; }
|
||
err() { echo -e "${RED}[✘]${NC} $1"; exit 1; }
|
||
|
||
# --- 检查 root ---
|
||
if [ "$EUID" -ne 0 ]; then
|
||
err "请使用 sudo 运行: sudo ./deploy.sh"
|
||
fi
|
||
|
||
# --- 变量 ---
|
||
APP_NAME="autoclaude-tgbot"
|
||
APP_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||
SERVICE_FILE="/etc/systemd/system/${APP_NAME}.service"
|
||
RUN_USER="${SUDO_USER:-$(whoami)}"
|
||
RUN_GROUP="$(id -gn "$RUN_USER")"
|
||
|
||
echo ""
|
||
echo -e "${CYAN}╔══════════════════════════════════════════╗${NC}"
|
||
echo -e "${CYAN}║ autoClaude-TGbot 一键部署 ║${NC}"
|
||
echo -e "${CYAN}╚══════════════════════════════════════════╝${NC}"
|
||
echo ""
|
||
info "项目目录: ${APP_DIR}"
|
||
info "运行用户: ${RUN_USER}"
|
||
echo ""
|
||
|
||
# ============================================================
|
||
# 1. 安装系统依赖
|
||
# ============================================================
|
||
info "检查系统依赖..."
|
||
|
||
# 确保 uv 路径在 PATH 中
|
||
export PATH="$HOME/.local/bin:/root/.local/bin:$PATH"
|
||
|
||
# 安装 uv(如果不存在)
|
||
if ! command -v uv &> /dev/null; then
|
||
info "安装 uv..."
|
||
curl -LsSf https://astral.sh/uv/install.sh | sh
|
||
ok "uv 已安装"
|
||
else
|
||
ok "uv 已存在 ($(uv --version))"
|
||
fi
|
||
|
||
# ============================================================
|
||
# 2. 安装 Python 依赖
|
||
# ============================================================
|
||
info "安装 Python 依赖..."
|
||
cd "$APP_DIR"
|
||
if uv sync; then
|
||
ok "依赖安装完成"
|
||
else
|
||
warn "uv sync 失败,尝试 uv pip install..."
|
||
if uv pip install -r pyproject.toml; then
|
||
ok "依赖安装完成 (pip fallback)"
|
||
else
|
||
err "依赖安装失败,请手动检查"
|
||
fi
|
||
fi
|
||
|
||
# ============================================================
|
||
# 3. 检查配置文件
|
||
# ============================================================
|
||
if [ ! -f "${APP_DIR}/config.toml" ]; then
|
||
warn "config.toml 不存在,从模板复制..."
|
||
cp "${APP_DIR}/config.toml.example" "${APP_DIR}/config.toml"
|
||
chown "$RUN_USER:$RUN_GROUP" "${APP_DIR}/config.toml"
|
||
echo ""
|
||
echo -e "${YELLOW}════════════════════════════════════════════${NC}"
|
||
echo -e "${YELLOW} ⚠️ 请编辑 config.toml 填入实际配置:${NC}"
|
||
echo -e "${YELLOW} nano ${APP_DIR}/config.toml${NC}"
|
||
echo -e "${YELLOW}════════════════════════════════════════════${NC}"
|
||
echo ""
|
||
read -p "编辑完成后按 Enter 继续,或 Ctrl+C 退出..." _
|
||
else
|
||
ok "config.toml 已存在"
|
||
fi
|
||
|
||
# ============================================================
|
||
# 4. 获取 uv 和 python 路径
|
||
# ============================================================
|
||
UV_PATH="$(which uv 2>/dev/null || echo '')"
|
||
if [ -z "$UV_PATH" ]; then
|
||
# 尝试常见路径
|
||
for p in "$HOME/.local/bin/uv" "/root/.local/bin/uv" "/usr/local/bin/uv"; do
|
||
if [ -x "$p" ]; then UV_PATH="$p"; break; fi
|
||
done
|
||
fi
|
||
if [ -z "$UV_PATH" ]; then
|
||
err "找不到 uv,请检查安装是否成功"
|
||
fi
|
||
info "uv 路径: ${UV_PATH}"
|
||
|
||
# ============================================================
|
||
# 5. 创建 systemd 服务
|
||
# ============================================================
|
||
info "创建 systemd 服务: ${APP_NAME}"
|
||
|
||
cat > "$SERVICE_FILE" <<EOF
|
||
[Unit]
|
||
Description=autoClaude Telegram Bot
|
||
After=network.target
|
||
Wants=network-online.target
|
||
|
||
[Service]
|
||
Type=simple
|
||
User=${RUN_USER}
|
||
Group=${RUN_GROUP}
|
||
WorkingDirectory=${APP_DIR}
|
||
ExecStart=${UV_PATH} run python bot.py
|
||
Restart=on-failure
|
||
RestartSec=10
|
||
StartLimitIntervalSec=60
|
||
StartLimitBurst=3
|
||
|
||
# 环境
|
||
Environment=PYTHONUNBUFFERED=1
|
||
|
||
# 日志
|
||
StandardOutput=journal
|
||
StandardError=journal
|
||
SyslogIdentifier=${APP_NAME}
|
||
|
||
# 安全加固
|
||
NoNewPrivileges=true
|
||
ProtectSystem=strict
|
||
ReadWritePaths=${APP_DIR}
|
||
PrivateTmp=true
|
||
|
||
[Install]
|
||
WantedBy=multi-user.target
|
||
EOF
|
||
|
||
ok "服务文件已创建: ${SERVICE_FILE}"
|
||
|
||
# ============================================================
|
||
# 6. 启用并启动服务
|
||
# ============================================================
|
||
info "重载 systemd 配置..."
|
||
systemctl daemon-reload
|
||
|
||
info "启用开机自启..."
|
||
systemctl enable "$APP_NAME"
|
||
|
||
info "启动服务..."
|
||
systemctl restart "$APP_NAME"
|
||
|
||
# 等一会检查状态
|
||
sleep 2
|
||
|
||
if systemctl is-active --quiet "$APP_NAME"; then
|
||
ok "服务已启动!"
|
||
else
|
||
warn "服务启动可能失败,请检查日志"
|
||
fi
|
||
|
||
# ============================================================
|
||
# 7. 完成
|
||
# ============================================================
|
||
echo ""
|
||
echo -e "${GREEN}╔══════════════════════════════════════════╗${NC}"
|
||
echo -e "${GREEN}║ ✅ 部署完成! ║${NC}"
|
||
echo -e "${GREEN}╚══════════════════════════════════════════╝${NC}"
|
||
echo ""
|
||
echo -e " ${CYAN}常用命令:${NC}"
|
||
echo ""
|
||
echo -e " 查看状态 ${GREEN}systemctl status ${APP_NAME}${NC}"
|
||
echo -e " 查看日志 ${GREEN}journalctl -u ${APP_NAME} -f${NC}"
|
||
echo -e " 重启服务 ${GREEN}systemctl restart ${APP_NAME}${NC}"
|
||
echo -e " 停止服务 ${GREEN}systemctl stop ${APP_NAME}${NC}"
|
||
echo -e " 编辑配置 ${GREEN}nano ${APP_DIR}/config.toml${NC}"
|
||
echo ""
|
||
echo -e " ${YELLOW}修改配置后记得重启: systemctl restart ${APP_NAME}${NC}"
|
||
echo ""
|