#!/bin/bash # ============================================================ # 光湖 · Forgejo 智能一键部署脚本 # 功能:自动探测服务器环境 → 拉取最新配置 → 部署代码仓库 # 适用:换服务器时一条命令跑完 # ============================================================ 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}[OK]${NC} $1"; } warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } err() { echo -e "${RED}[ERR]${NC} $1"; } # ====== 配置区(可自定义)===== DOMAIN="${DOMAIN:-guanghulab.com}" FORGEJO_PORT="${FORGEJO_PORT:-3001}" FORGEJO_DIR="${FORGEJO_DIR:-/opt/forgejo}" FORGEJO_VERSION="${FORGEJO_VERSION:-1.23}" ADMIN_EMAIL="${ADMIN_EMAIL:-admin@guanghulab.com}" COS_BUCKET="${COS_BUCKET:-zy-team-hub-1317346199}" COS_REGION="${COS_REGION:-ap-guangzhou}" # ====== 第一步:环境探测 ====== info "========== 第一步:环境探测 ==========" # 探测 OS OS=$(grep -oP '^ID=\K.*' /etc/os-release 2>/dev/null || echo "ubuntu") ARCH=$(uname -m) RAM_MB=$(free -m | awk '/^Mem:/{print $2}') DISK_GB=$(df -BG "${FORGEJO_DIR%/*}" 2>/dev/null | awk 'NR==2{print $4}' | sed 's/G//' || echo "10") IP=$(curl -s ifconfig.me 2>/dev/null || hostname -I | awk '{print $1}') info "系统: $OS | 架构: $ARCH | 内存: ${RAM_MB}MB | 磁盘: ${DISK_GB}G" info "域名: $DOMAIN | 服务器IP: $IP" ok "环境探测完成" # ====== 第二步:安装依赖 ====== info "========== 第二步:安装依赖 ==========" # 安装必要软件 install_pkg() { if ! command -v "$1" &>/dev/null; then info "正在安装 $1..." apt-get install -y "$1" &>/dev/null && ok "$1 安装完成" || warn "$1 安装失败" else ok "$1 已存在" fi } install_pkg nginx install_pkg wget install_pkg curl # ====== 第三步:配置 Nginx ====== info "========== 第三步:配置 Nginx ==========" cat > /etc/nginx/sites-available/guanghulab << 'NGINXEOF' server { listen 80; server_name DOMAIN_PLACEHOLDER; return 301 https://$server_name$request_uri; } server { listen 443 ssl http2; server_name DOMAIN_PLACEHOLDER; ssl_certificate /etc/letsencrypt/live/DOMAIN_PLACEHOLDER-0001/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/DOMAIN_PLACEHOLDER-0001/privkey.pem; ssl_protocols TLSv1.2 TLSv1.3; location / { client_max_body_size 100M; proxy_pass http://127.0.0.1:PORT_PLACEHOLDER; 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; } } NGINXEOF sed -i "s/DOMAIN_PLACEHOLDER/$DOMAIN/g" /etc/nginx/sites-available/guanghulab sed -i "s/PORT_PLACEHOLDER/$FORGEJO_PORT/g" /etc/nginx/sites-available/guanghulab ln -sf /etc/nginx/sites-available/guanghulab /etc/nginx/sites-enabled/ rm -f /etc/nginx/sites-enabled/default # ====== 第四步:安装 Forgejo ====== info "========== 第四步:安装 Forgejo ==========" if [ -f "$FORGEJO_DIR/repositories/bingshuo/guanghulab.git/HEAD" ]; then ok "Forgejo 数据已存在,跳过安装" else # 下载 Forgejo 二进制 FORGEJO_BIN="/usr/local/bin/gitea" if [ ! -f "$FORGEJO_BIN" ]; then DL_URL="https://dl.gitea.com/gitea/${FORGEJO_VERSION}/gitea-${FORGEJO_VERSION}-linux-amd64" info "正在下载 Forgejo ($DL_URL)..." wget -q --timeout=30 -O "$FORGEJO_BIN" "$DL_URL" 2>/dev/null || { warn "主源下载失败,尝试备用源..." wget -q --timeout=30 -O "$FORGEJO_BIN" \ "https://github.com/go-gitea/gitea/releases/download/v${FORGEJO_VERSION}.0/gitea-${FORGEJO_VERSION}.0-linux-amd64" 2>/dev/null || { err "所有下载源都失败,请手动下载二进制" exit 1 } } chmod +x "$FORGEJO_BIN" ok "Forgejo 二进制下载完成 ($(ls -lh $FORGEJO_BIN | awk '{print $5}'))" fi # 尝试从 COS 恢复备份 if command -v coscmd &>/dev/null; then info "正在从 COS 查找备份..." BACKUP_FILE=$(coscmd list backups/ 2>/dev/null | grep -i "forgejo\|gitea\|guanghu" | head -1 | awk '{print $NF}') if [ -n "$BACKUP_FILE" ]; then info "找到备份: $BACKUP_FILE,正在下载..." mkdir -p /tmp/forgejo-restore coscmd download "$BACKUP_FILE" /tmp/forgejo-restore/backup.tar.gz &>/dev/null tar -xzf /tmp/forgejo-restore/backup.tar.gz -C /opt --strip-components=2 data/guanghulab/forgejo 2>/dev/null && { ok "从 COS 备份恢复 Forgejo 数据成功" } || warn "备份恢复失败,将创建新的 Forgejo 实例" rm -rf /tmp/forgejo-restore else warn "COS 中未找到 Forgejo 备份,将创建新实例" fi fi fi # ====== 第五步:创建配置 ====== info "========== 第五步:创建配置 ==========" mkdir -p $FORGEJO_DIR/data $FORGEJO_DIR/log $FORGEJO_DIR/repositories $FORGEJO_DIR/custom/conf cat > $FORGEJO_DIR/custom/conf/app.ini << INIEOF APP_NAME = 光湖 · Forgejo RUN_MODE = prod [server] PROTOCOL = http DOMAIN = $DOMAIN ROOT_URL = https://$DOMAIN/ HTTP_PORT = $FORGEJO_PORT [database] DB_TYPE = sqlite3 PATH = $FORGEJO_DIR/data/forgejo.db [repository] ROOT = $FORGEJO_DIR/repositories [service] DISABLE_REGISTRATION = false REQUIRE_SIGNIN_VIEW = false [server] SSH_DOMAIN = $DOMAIN INIEOF # ====== 第六步:创建用户并启动服务 ====== info "========== 第六步:启动服务 ==========" # 创建 git 用户 id -u git &>/dev/null || useradd -m -s /bin/bash git chown -R git:git $FORGEJO_DIR # 注册 systemd 服务 cat > /etc/systemd/system/forgejo.service << 'UNITEOF' [Unit] Description=Forgejo After=network.target [Service] Type=simple User=git ExecStart=/usr/local/bin/gitea web --config OPT_DIR_PLACEHOLDER/custom/conf/app.ini --work-path OPT_DIR_PLACEHOLDER Restart=always RestartSec=5 [Install] WantedBy=multi-user.target UNITEOF sed -i "s|OPT_DIR_PLACEHOLDER|$FORGEJO_DIR|g" /etc/systemd/system/forgejo.service systemctl daemon-reload systemctl enable forgejo --quiet 2>/dev/null systemctl start forgejo sleep 2 # 检查服务 if systemctl is-active --quiet forgejo; then ok "Forgejo 服务运行中 (端口 $FORGEJO_PORT)" else err "Forgejo 启动失败,查看日志: journalctl -u forgejo -n 50 --no-pager" exit 1 fi # ====== 第七步:配置 SSL ====== info "========== 第七步:配置 SSL ==========" if [ ! -f "/etc/letsencrypt/live/$DOMAIN-0001/fullchain.pem" ]; then if command -v certbot &>/dev/null; then info "正在申请 SSL 证书..." certbot --nginx -d "$DOMAIN" --non-interactive --agree-tos -m "$ADMIN_EMAIL" --quiet 2>/dev/null && { ok "SSL 证书配置成功 ($DOMAIN)" } || warn "SSL 证书申请失败,将使用 HTTP" else warn "certbot 未安装,跳过 SSL 配置" fi else ok "SSL 证书已存在,跳过申请" fi # 重启 Nginx 加载最终配置 nginx -t && systemctl restart nginx # ====== 完成 ====== echo "" info "========================================" ok "光湖 · Forgejo 部署完成!" echo "" info "访问地址: https://$DOMAIN/" info "管理后台: https://$DOMAIN/user/login" echo "" info "常用命令:" info " 查看状态: sudo systemctl status forgejo" info " 查看日志: sudo journalctl -u forgejo -n 50 -f" info " 重启服务: sudo systemctl restart forgejo" info "========================================"