guanghulab/scripts/smart-deploy-forgejo.sh

232 lines
7.5 KiB
Bash
Raw Normal View History

#!/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 "========================================"