#!/bin/bash # zsglpt 一键部署脚本 # 用法: curl -sSL https://your-domain/install.sh | bash # 或: bash install.sh [install|uninstall|ssl|status] set -e # ==================== 配置 ==================== APP_NAME="zsglpt" APP_PORT="51233" CONTAINER_NAME="knowledge-automation-multiuser" GIT_REPO="https://git.workyai.cn/237899745/zsglpt.git" INSTALL_DIR="/opt/$APP_NAME" # ==================== 颜色 ==================== RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' log_info() { echo -e "${GREEN}[INFO]${NC} $1"; } log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } log_error() { echo -e "${RED}[ERROR]${NC} $1"; exit 1; } log_step() { echo -e "${BLUE}[STEP]${NC} $1"; } # ==================== 检测环境 ==================== detect_os() { if [ -f /etc/os-release ]; then . /etc/os-release OS=$ID else log_error "无法检测操作系统" fi } detect_bt_panel() { if [ -d "/www/server/panel" ] && [ -f "/etc/init.d/bt" ]; then BT_PANEL=true BT_NGINX_VHOST="/www/server/panel/vhost/nginx" BT_NGINX_BIN="/www/server/nginx/sbin/nginx" log_info "检测到宝塔面板" else BT_PANEL=false log_info "未检测到宝塔面板,使用系统 nginx" fi } check_root() { if [ "$EUID" -ne 0 ]; then log_error "请使用 root 用户运行此脚本" fi } # ==================== 安装依赖 ==================== install_deps() { log_step "安装依赖..." if command -v apt &> /dev/null; then apt update -qq apt install -y -qq git curl docker.io docker-compose nginx certbot python3-certbot-nginx 2>/dev/null || true elif command -v yum &> /dev/null; then yum install -y -q git curl docker docker-compose nginx certbot python3-certbot-nginx 2>/dev/null || true fi # 启动 docker systemctl enable docker 2>/dev/null || true systemctl start docker 2>/dev/null || true } # ==================== 交互式配置 ==================== get_config() { echo "" echo -e "${BLUE}========== $APP_NAME 部署配置 ==========${NC}" echo "" # 域名 read -p "请输入域名 (例: zsglpt.example.com): " DOMAIN if [ -z "$DOMAIN" ]; then log_error "域名不能为空" fi # 端口 read -p "请输入服务端口 [默认: $APP_PORT]: " INPUT_PORT APP_PORT=${INPUT_PORT:-$APP_PORT} # Git 认证 read -p "Git 用户名 [默认: 237899745]: " GIT_USER GIT_USER=${GIT_USER:-237899745} read -sp "Git 密码: " GIT_PASS echo "" if [ -z "$GIT_PASS" ]; then log_error "Git 密码不能为空" fi # SSL read -p "是否配置 SSL? [Y/n]: " SETUP_SSL SETUP_SSL=${SETUP_SSL:-Y} if [[ "$SETUP_SSL" =~ ^[Yy]$ ]]; then read -p "SSL 证书邮箱 (用于 Let's Encrypt): " SSL_EMAIL SSL_EMAIL=${SSL_EMAIL:-admin@$DOMAIN} fi # 确认 echo "" echo -e "${YELLOW}========== 配置确认 ==========${NC}" echo "域名: $DOMAIN" echo "端口: $APP_PORT" echo "安装目录: $INSTALL_DIR" echo "SSL: $SETUP_SSL" echo "" read -p "确认安装? [Y/n]: " CONFIRM if [[ ! "$CONFIRM" =~ ^[Yy]?$ ]]; then log_error "安装已取消" fi } # ==================== 克隆代码 ==================== clone_repo() { log_step "克隆代码..." if [ -d "$INSTALL_DIR" ]; then log_warn "目录已存在,更新代码..." cd "$INSTALL_DIR" git fetch origin git reset --hard origin/master else GIT_URL="https://${GIT_USER}:${GIT_PASS}@git.workyai.cn/237899745/zsglpt.git" git clone "$GIT_URL" "$INSTALL_DIR" cd "$INSTALL_DIR" fi # 保存配置 cat > "$INSTALL_DIR/.deploy_config" << EOF DOMAIN=$DOMAIN APP_PORT=$APP_PORT GIT_USER=$GIT_USER SSL_EMAIL=$SSL_EMAIL INSTALL_TIME=$(date '+%Y-%m-%d %H:%M:%S') EOF } # ==================== Docker 部署 ==================== deploy_docker() { log_step "部署 Docker 容器..." cd "$INSTALL_DIR" # 修改 docker-compose 端口映射 if [ -f docker-compose.yml ]; then sed -i "s/51232:51233/${APP_PORT}:51233/g" docker-compose.yml fi # 构建并启动 docker-compose down 2>/dev/null || true docker-compose up -d --build log_info "等待容器启动..." sleep 8 if docker ps | grep -q "$CONTAINER_NAME"; then log_info "容器启动成功" else log_error "容器启动失败,请检查日志: docker logs $CONTAINER_NAME" fi } # ==================== Nginx 配置 ==================== setup_nginx() { log_step "配置 Nginx..." if $BT_PANEL; then NGINX_CONF="$BT_NGINX_VHOST/${DOMAIN}.conf" NGINX_CMD="$BT_NGINX_BIN" else NGINX_CONF="/etc/nginx/sites-available/${DOMAIN}.conf" NGINX_CMD="nginx" fi # 生成配置 cat > "$NGINX_CONF" << EOF # $APP_NAME - $DOMAIN # 由 install.sh 自动生成,请勿手动修改 server { listen 80; server_name $DOMAIN; location / { proxy_pass http://127.0.0.1:$APP_PORT; proxy_http_version 1.1; proxy_set_header Upgrade \$http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host \$host; proxy_set_header X-Real-IP \$remote_addr; proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto \$scheme; proxy_read_timeout 86400; proxy_send_timeout 86400; } } EOF # 非宝塔环境需要创建软链接 if ! $BT_PANEL; then ln -sf "$NGINX_CONF" "/etc/nginx/sites-enabled/${DOMAIN}.conf" 2>/dev/null || true fi # 测试并重载 $NGINX_CMD -t && $NGINX_CMD -s reload log_info "Nginx 配置完成" } # ==================== SSL 配置 ==================== setup_ssl() { if [[ ! "$SETUP_SSL" =~ ^[Yy]$ ]]; then return fi log_step "配置 SSL 证书..." if $BT_PANEL; then # 宝塔面板使用 acme.sh if [ -f "/root/.acme.sh/acme.sh" ]; then /root/.acme.sh/acme.sh --issue -d "$DOMAIN" --webroot "$INSTALL_DIR/static" --force || true # 更新 nginx 配置 NGINX_CONF="$BT_NGINX_VHOST/${DOMAIN}.conf" cat > "$NGINX_CONF" << EOF # $APP_NAME - $DOMAIN (SSL) # 由 install.sh 自动生成 server { listen 80; server_name $DOMAIN; return 301 https://\$host\$request_uri; } server { listen 443 ssl http2; server_name $DOMAIN; ssl_certificate /root/.acme.sh/${DOMAIN}_ecc/fullchain.cer; ssl_certificate_key /root/.acme.sh/${DOMAIN}_ecc/${DOMAIN}.key; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256; ssl_prefer_server_ciphers on; location / { proxy_pass http://127.0.0.1:$APP_PORT; proxy_http_version 1.1; proxy_set_header Upgrade \$http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host \$host; proxy_set_header X-Real-IP \$remote_addr; proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto \$scheme; proxy_read_timeout 86400; } } EOF $BT_NGINX_BIN -t && $BT_NGINX_BIN -s reload else log_warn "未找到 acme.sh,请在宝塔面板手动配置 SSL" fi else # 使用 certbot certbot --nginx -d "$DOMAIN" --non-interactive --agree-tos -m "$SSL_EMAIL" || log_warn "SSL 配置失败,请手动配置" fi log_info "SSL 配置完成" } # ==================== 卸载 ==================== uninstall() { echo -e "${RED}========== 卸载 $APP_NAME ==========${NC}" # 读取配置 if [ -f "$INSTALL_DIR/.deploy_config" ]; then source "$INSTALL_DIR/.deploy_config" else read -p "请输入域名: " DOMAIN fi read -p "确认卸载 $APP_NAME? 数据将被删除! [y/N]: " CONFIRM if [[ ! "$CONFIRM" =~ ^[Yy]$ ]]; then log_info "卸载已取消" exit 0 fi log_step "停止容器..." cd "$INSTALL_DIR" 2>/dev/null && docker-compose down 2>/dev/null || true docker rm -f "$CONTAINER_NAME" 2>/dev/null || true log_step "删除 Nginx 配置..." detect_bt_panel if $BT_PANEL; then rm -f "$BT_NGINX_VHOST/${DOMAIN}.conf" $BT_NGINX_BIN -s reload 2>/dev/null || true else rm -f "/etc/nginx/sites-available/${DOMAIN}.conf" rm -f "/etc/nginx/sites-enabled/${DOMAIN}.conf" nginx -s reload 2>/dev/null || true fi # 备份数据 if [ -d "$INSTALL_DIR/data" ]; then BACKUP_DIR="/root/${APP_NAME}_backup_$(date +%Y%m%d_%H%M%S)" log_step "备份数据到 $BACKUP_DIR..." mkdir -p "$BACKUP_DIR" cp -r "$INSTALL_DIR/data" "$BACKUP_DIR/" fi log_step "删除安装目录..." rm -rf "$INSTALL_DIR" log_info "卸载完成!" [ -d "$BACKUP_DIR" ] && log_info "数据已备份到: $BACKUP_DIR" } # ==================== 状态检查 ==================== status() { echo -e "${BLUE}========== $APP_NAME 状态 ==========${NC}" if [ -f "$INSTALL_DIR/.deploy_config" ]; then source "$INSTALL_DIR/.deploy_config" echo "域名: $DOMAIN" echo "端口: $APP_PORT" echo "安装时间: $INSTALL_TIME" fi echo "" echo "容器状态:" docker ps -a | grep "$CONTAINER_NAME" || echo "容器未运行" echo "" echo "最近日志:" docker logs --tail 10 "$CONTAINER_NAME" 2>/dev/null || echo "无日志" } # ==================== 更新 ==================== update() { log_step "更新 $APP_NAME..." if [ ! -d "$INSTALL_DIR" ]; then log_error "未找到安装目录,请先安装" fi cd "$INSTALL_DIR" # 备份数据库 if [ -f "data/app_data.db" ]; then cp "data/app_data.db" "data/app_data.db.$(date +%Y%m%d_%H%M%S).bak" fi # 拉取代码 git fetch origin git reset --hard origin/master # 重建容器 docker-compose down docker-compose up -d --build log_info "更新完成!" } # ==================== 主函数 ==================== main() { check_root detect_os detect_bt_panel case "${1:-install}" in install) install_deps get_config clone_repo deploy_docker setup_nginx setup_ssl echo "" echo -e "${GREEN}========== 安装完成 ==========${NC}" echo "访问地址: http://$DOMAIN" [[ "$SETUP_SSL" =~ ^[Yy]$ ]] && echo "HTTPS: https://$DOMAIN" echo "" ;; uninstall) uninstall ;; update) update ;; status) status ;; ssl) if [ -f "$INSTALL_DIR/.deploy_config" ]; then source "$INSTALL_DIR/.deploy_config" fi SETUP_SSL=Y setup_ssl ;; *) echo "用法: $0 [install|uninstall|update|status|ssl]" echo "" echo " install - 安装部署 (默认)" echo " uninstall - 卸载并备份数据" echo " update - 更新到最新版本" echo " status - 查看运行状态" echo " ssl - 配置/更新 SSL 证书" ;; esac } main "$@"