236 lines
9.0 KiB
Bash
Executable File
236 lines
9.0 KiB
Bash
Executable File
#!/usr/bin/env bash
|
||
# ════════════════════════════════════════════════════════════════
|
||
# 光湖 · 新CVM一键初始化脚本
|
||
# 服务器:guanghu-zhuyuan (4C16G, 42.193.161.251)
|
||
# 执行方式:在新服务器的腾讯云在线终端里运行
|
||
# ════════════════════════════════════════════════════════════════
|
||
#
|
||
# 用法(复制这一整行到新服务器终端执行):
|
||
# bash <(curl -fsSL https://raw.githubusercontent.com/qinfendebingshuo/guanghulab/main/scripts/cvm-init/init-cvm.sh)
|
||
#
|
||
# 如果GitHub不通,先在旧服务器上把脚本传过来:
|
||
# scp /opt/zhuyuan-cn/repo-mirror/20260509-1849/guanghulab/scripts/cvm-init/init-cvm.sh root@42.193.161.251:/tmp/
|
||
# 然后在新服务器上:bash /tmp/init-cvm.sh
|
||
#
|
||
# ════════════════════════════════════════════════════════════════
|
||
|
||
set -euo pipefail
|
||
set +e # 不自动退出,让脚本继续
|
||
|
||
GREEN='\033[0;32m'
|
||
YELLOW='\033[1;33m'
|
||
CYAN='\033[0;36m'
|
||
RED='\033[0;31m'
|
||
NC='\033[0m'
|
||
|
||
echo -e "${CYAN}═══════════════════════════════════════════${NC}"
|
||
echo -e "${CYAN} 光湖 · 新CVM初始化${NC}"
|
||
echo -e "${CYAN} guanghu-zhuyuan · 4C16G${NC}"
|
||
echo -e "${CYAN}═══════════════════════════════════════════${NC}"
|
||
echo ""
|
||
|
||
# ─── 第1步:确认在新服务器上 ──────────────────────────────────
|
||
echo -e "${YELLOW}[第1步/8] 确认环境...${NC}"
|
||
CURRENT_IP=$(curl -sf ifconfig.me 2>/dev/null || echo "unknown")
|
||
echo " 当前IP: $CURRENT_IP"
|
||
if [[ "$CURRENT_IP" != "42.193.161.251" ]]; then
|
||
echo -e "${YELLOW} ⚠️ IP不是42.193.161.251,你确定要在这台机器上初始化?${NC}"
|
||
read -p " 继续吗?[y/N] " -n 1 -r
|
||
echo
|
||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then exit 0; fi
|
||
fi
|
||
echo -e "${GREEN} 环境确认 ✅${NC}"
|
||
|
||
# ─── 第2步:系统基础 ──────────────────────────────────────────
|
||
echo ""
|
||
echo -e "${YELLOW}[第2步/8] 安装系统基础软件...${NC}"
|
||
apt update -qq
|
||
apt install -y -qq curl git nginx ufw xz-utils unzip software-properties-common build-essential > /dev/null 2>&1
|
||
echo -e "${GREEN} 系统软件 ✅${NC}"
|
||
|
||
# ─── 第3步:Node.js 20 ────────────────────────────────────────
|
||
echo ""
|
||
echo -e "${YELLOW}[第3步/8] 安装Node.js 20...${NC}"
|
||
if ! command -v node &>/dev/null || [[ "$(node -v)" != v20* ]]; then
|
||
curl -fsSL https://deb.nodesource.com/setup_20.x | bash - > /dev/null 2>&1
|
||
apt install -y -qq nodejs > /dev/null 2>&1
|
||
fi
|
||
echo " Node.js: $(node -v)"
|
||
npm install -g pm2 > /dev/null 2>&1
|
||
echo " PM2: $(pm2 -v)"
|
||
echo -e "${GREEN} Node.js + PM2 ✅${NC}"
|
||
|
||
# ─── 第4步:目录结构 ──────────────────────────────────────────
|
||
echo ""
|
||
echo -e "${YELLOW}[第4步/8] 创建目录结构...${NC}"
|
||
mkdir -p /data/guanghulab/{forgejo/{data,repositories,log},secrets-vault,scripts,.runtime}
|
||
echo -e "${GREEN} /data/guanghulab/ ✅${NC}"
|
||
|
||
# ─── 第5步:Forgejo ───────────────────────────────────────────
|
||
echo ""
|
||
echo -e "${YELLOW}[第5步/8] 安装Forgejo...${NC}"
|
||
|
||
# 创建git用户
|
||
if ! id -u git &>/dev/null; then
|
||
useradd -r -m -d /data/guanghulab/forgejo -s /bin/bash git
|
||
echo -e "${GREEN} git用户已创建${NC}"
|
||
fi
|
||
|
||
# 下载Forgejo二进制
|
||
FORGEJO_VERSION="11.0.1"
|
||
FORGEJO_BINARY="/usr/local/bin/forgejo"
|
||
if [[ ! -x "$FORGEJO_BINARY" ]]; then
|
||
echo " 下载Forgejo v${FORGEJO_VERSION}..."
|
||
curl -fSL --progress-bar -o "$FORGEJO_BINARY" \
|
||
"https://codeberg.org/forgejo/forgejo/releases/download/v${FORGEJO_VERSION}/forgejo-${FORGEJO_VERSION}-linux-amd64" \
|
||
2>/dev/null || {
|
||
# 如果codeberg下载不了,试gitea镜像
|
||
echo " codeberg不通,尝试备用下载..."
|
||
curl -fSL --progress-bar -o "$FORGEJO_BINARY" \
|
||
"https://dl.gitea.io/forgejo/${FORGEJO_VERSION}/forgejo-${FORGEJO_VERSION}-linux-amd64" 2>/dev/null || {
|
||
echo -e "${RED} ❌ Forgejo下载失败${NC}"
|
||
echo " 请手动下载后放到 /usr/local/bin/forgejo"
|
||
echo " 下载地址: https://codeberg.org/forgejo/forgejo/releases"
|
||
}
|
||
}
|
||
chmod +x "$FORGEJO_BINARY"
|
||
fi
|
||
|
||
if [[ -x "$FORGEJO_BINARY" ]]; then
|
||
echo " Forgejo: $("$FORGEJO_BINARY" --version 2>&1 | head -1)"
|
||
fi
|
||
|
||
# Forgejo配置文件
|
||
mkdir -p /etc/forgejo
|
||
cat > /etc/forgejo/app.ini << 'INIEOF'
|
||
WORK_PATH = /data/guanghulab/forgejo/data
|
||
|
||
[server]
|
||
DOMAIN = guanghulab.com
|
||
ROOT_URL = https://guanghulab.com/git/
|
||
HTTP_PORT = 3001
|
||
HTTP_ADDR = 127.0.0.1
|
||
LFS_START_SERVER = false
|
||
OFFLINE_MODE = false
|
||
|
||
[database]
|
||
DB_TYPE = sqlite3
|
||
PATH = /data/guanghulab/forgejo/data/forgejo.db
|
||
|
||
[repository]
|
||
ROOT = /data/guanghulab/forgejo/repositories
|
||
|
||
[log]
|
||
ROOT_PATH = /data/guanghulab/forgejo/log
|
||
|
||
[service]
|
||
DISABLE_REGISTRATION = true
|
||
|
||
[security]
|
||
INSTALL_LOCK = true
|
||
|
||
[actions]
|
||
ENABLED = true
|
||
|
||
[packages]
|
||
CHUNKED_UPLOAD_PATH = /data/guanghulab/forgejo/data/tmp/package-upload
|
||
INIEOF
|
||
|
||
chown -R git:git /data/guanghulab/forgejo /etc/forgejo
|
||
echo -e "${GREEN} Forgejo配置 ✅${NC}"
|
||
|
||
# systemd服务
|
||
cat > /etc/systemd/system/forgejo.service << 'SVCEOF'
|
||
[Unit]
|
||
Description=Forgejo (self-hosted git)
|
||
After=network.target
|
||
|
||
[Service]
|
||
User=git
|
||
Group=git
|
||
WorkingDirectory=/data/guanghulab/forgejo
|
||
ExecStart=/usr/local/bin/forgejo web --config /etc/forgejo/app.ini
|
||
Restart=always
|
||
RestartSec=10
|
||
Environment=USER=git HOME=/data/guanghulab/forgejo
|
||
|
||
[Install]
|
||
WantedBy=multi-user.target
|
||
SVCEOF
|
||
|
||
systemctl daemon-reload
|
||
systemctl enable forgejo
|
||
systemctl start forgejo
|
||
sleep 3
|
||
|
||
if systemctl is-active --quiet forgejo; then
|
||
echo -e "${GREEN} Forgejo运行中 ✅${NC}"
|
||
else
|
||
echo -e "${RED} ❌ Forgejo启动失败${NC}"
|
||
journalctl -u forgejo -n 10 --no-pager
|
||
fi
|
||
|
||
# ─── 第6步:Nginx ─────────────────────────────────────────────
|
||
echo ""
|
||
echo -e "${YELLOW}[第6步/8] 配置Nginx反向代理...${NC}"
|
||
cat > /etc/nginx/sites-available/guanghulab << 'NGXEOF'
|
||
server {
|
||
listen 80;
|
||
server_name guanghulab.com;
|
||
|
||
# gRPC(Runner注册和通信需要)
|
||
location /git/api/actions/ {
|
||
grpc_pass grpc://127.0.0.1:3001;
|
||
grpc_set_header X-Real-IP $remote_addr;
|
||
}
|
||
|
||
# 普通HTTP请求
|
||
location /git/ {
|
||
proxy_pass http://127.0.0.1:3001/;
|
||
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;
|
||
client_max_body_size 100M;
|
||
}
|
||
}
|
||
NGXEOF
|
||
|
||
ln -sf /etc/nginx/sites-available/guanghulab /etc/nginx/sites-enabled/
|
||
rm -f /etc/nginx/sites-enabled/default
|
||
nginx -t 2>/dev/null && systemctl restart nginx
|
||
echo -e "${GREEN} Nginx ✅${NC}"
|
||
|
||
# ─── 第7步:防火墙 ────────────────────────────────────────────
|
||
echo ""
|
||
echo -e "${YELLOW}[第7步/8] 配置防火墙...${NC}"
|
||
ufw allow 22/tcp
|
||
ufw allow 80/tcp
|
||
ufw allow 443/tcp
|
||
ufw --force enable
|
||
echo -e "${GREEN} 防火墙 ✅${NC}"
|
||
|
||
# ─── 第8步:验证 ──────────────────────────────────────────────
|
||
echo ""
|
||
echo -e "${YELLOW}[第8步/8] 验证所有服务...${NC}"
|
||
echo ""
|
||
echo " Forgejo: $(systemctl is-active forgejo 2>/dev/null || echo unknown)"
|
||
echo " Nginx: $(systemctl is-active nginx 2>/dev/null || echo unknown)"
|
||
echo " Docker: $(systemctl is-active docker 2>/dev/null || echo unknown)"
|
||
echo " Node.js: $(node -v)"
|
||
echo " PM2: $(pm2 -v)"
|
||
echo ""
|
||
echo " 内存: $(free -h | awk '/Mem:/ {print $2 " 总计, " $7 " 可用"}')"
|
||
echo " 磁盘: $(df -h /data | awk 'NR==2 {print $4 " 可用"}')"
|
||
echo ""
|
||
echo -e "${GREEN}═══════════════════════════════════════════${NC}"
|
||
echo -e "${GREEN} ✅ 新CVM基础环境初始化完成!${NC}"
|
||
echo -e "${GREEN}═══════════════════════════════════════════${NC}"
|
||
echo ""
|
||
echo " 下一步:"
|
||
echo " 1. 浏览器打开 http://42.193.161.251/git/ 完成Forgejo初始设置"
|
||
echo " 2. 创建管理员账号 bingshuo"
|
||
echo " 3. 告诉铸渊Forgejo已就绪,铸渊会通过API完成剩余配置"
|
||
echo ""
|
||
echo " 铸渊 · ICE-GL-ZY001 · TCS-0002∞"
|