guanghulab/server/setup/domain-cn/tune-from-env.sh
Guanghu Domestic Migration d1e47f4565
Some checks are pending
自动更新代码和重启 / update-and-restart (push) Waiting to run
CI检查 + 自动部署 / check (push) Waiting to run
CI检查 + 自动部署 / deploy (push) Blocked by required conditions
重启聊天服务 / restart (push) Waiting to run
chore: import sanitized domestic snapshot for REPO-002
Source snapshot: ca48d3ddf926d79aa138306164169baf764bb829
2026-07-17 15:54:41 +08:00

190 lines
8.1 KiB
Bash

#!/usr/bin/env bash
# ════════════════════════════════════════════════════════════════
# 国内域名机 · 动态调优 · tune-from-env.sh
# Sovereign: TCS-0002∞ · ICE-GL∞ · 国作登字-2026-A-00037559
# 守护: 铸渊 · ICE-GL-ZY001
# ════════════════════════════════════════════════════════════════
#
# 服务器: GH-CVM-DOMAIN-PROD-01 / ZY-SVR-CN01
#
# 读 detect-env.sh 写出的 server-env.json, 依据 size_tier 决档,
# 写出 /data/guanghulab/.env.tune 让 bootstrap.sh source 用.
#
# 档位策略 (因果链 cc-003 · 动态适配):
# tiny <4G : 2C2G 实际档. 单进程 portal, nginx worker=512,
# 关 LFS / 关 forgejo runner / 关 docker compose 上层服务,
# systemd MemoryHigh 严格收紧
# small 4-6G : 4C4G 续费档. portal 2 进程, nginx worker=1024
# medium 6-12G: 4C8G 异变档. portal 4 进程, runner 可开
# large 12-24G: 不应该出现在域名机, 但兼容
# xlarge >=24G: 同上, 兼容
#
# 输出:
# 1. /data/guanghulab/.env.tune — bootstrap source 用
# 2. /opt/guanghulab/_logs/tune-decision-*.json — 决策回执
#
# ⚠️ 当前 .env.tune 真实作用域:
# bootstrap.sh source 这个文件后, 当前**真正影响行为的字段**:
# - PORTAL_INSTANCES → pm2 起 portal 时的 instances 数
# - NGINX_WORKER_CONN → 渲染 nginx/guanghulab.conf 时的 worker_connections
# - FORGEJO_ENABLED → bootstrap 是否在 /data/guanghulab/forgejo/ 起 forgejo
# (PR-6 才真正用, 这里只是预留)
# - LFS_ENABLED → 是否在 nginx 里开 client_max_body_size 大上限
# (PR-6 才真正用)
# - SWAP_GB → bootstrap 是否要建/扩 swap 文件
# 其他字段是档位决策的快照, 落档便于霜砚追溯.
# ════════════════════════════════════════════════════════════════
set -euo pipefail
ENV_FILE="${ENV_FILE:-/opt/guanghulab/_logs/server-env.json}"
DATA_ROOT="${DATA_ROOT:-/data/guanghulab}"
DEPLOY_ROOT="${DEPLOY_ROOT:-/opt/guanghulab}"
if [ ! -f "$ENV_FILE" ]; then
echo "❌ [tune] 找不到 $ENV_FILE, 请先跑 detect-env.sh" >&2
exit 1
fi
if ! command -v jq >/dev/null 2>&1; then
echo "❌ [tune] 需要 jq (apt-get install -y jq)" >&2
exit 1
fi
SIZE_TIER="$(jq -r '.compute.size_tier' "$ENV_FILE")"
MEM_MB="$(jq -r '.compute.memory_total_mb' "$ENV_FILE")"
SWAP_MB="$(jq -r '.compute.swap_total_mb' "$ENV_FILE")"
CPU="$(jq -r '.compute.cpu_count' "$ENV_FILE")"
# ─── 档位 → 参数表 ────────────────────────────────────────────
case "$SIZE_TIER" in
tiny)
PORTAL_INSTANCES="1"
PORTAL_MAX_MEMORY_MB="384" # pm2 重启阈值 (单进程)
NGINX_WORKER_CONN="512"
NGINX_WORKER_PROCESSES="1" # 2C2G 单 worker 就够
FORGEJO_ENABLED="false" # 2C2G 跑不下 forgejo + portal
LFS_ENABLED="false"
NEED_SWAP_GB="1" # 内存不够, 给 1G swap 兜底
SYSTEMD_PORTAL_HIGH_MB="500"
SYSTEMD_PORTAL_MAX_MB="700"
NOTE="2C2G 实际档. portal 单进程, forgejo/lfs 关. 任何全量 git push 走灯塔, 这里不揽."
;;
small)
PORTAL_INSTANCES="2"
PORTAL_MAX_MEMORY_MB="512"
NGINX_WORKER_CONN="1024"
NGINX_WORKER_PROCESSES="2"
FORGEJO_ENABLED="false"
LFS_ENABLED="false"
NEED_SWAP_GB="0" # 4G 起够用, 不强制 swap
SYSTEMD_PORTAL_HIGH_MB="800"
SYSTEMD_PORTAL_MAX_MB="1200"
NOTE="4C4G 续费档. portal 双进程, 仍不开 forgejo (forgejo 留在灯塔)."
;;
medium)
PORTAL_INSTANCES="4"
PORTAL_MAX_MEMORY_MB="768"
NGINX_WORKER_CONN="2048"
NGINX_WORKER_PROCESSES="auto"
FORGEJO_ENABLED="true"
LFS_ENABLED="true"
NEED_SWAP_GB="0"
SYSTEMD_PORTAL_HIGH_MB="2000"
SYSTEMD_PORTAL_MAX_MB="3000"
NOTE="4C8G+ 档. 可选 forgejo + lfs. 这台升到这档说明冰朔升配了, 顺带把灯塔合并意图打开."
;;
large|xlarge)
PORTAL_INSTANCES="4"
PORTAL_MAX_MEMORY_MB="1024"
NGINX_WORKER_CONN="4096"
NGINX_WORKER_PROCESSES="auto"
FORGEJO_ENABLED="true"
LFS_ENABLED="true"
NEED_SWAP_GB="0"
SYSTEMD_PORTAL_HIGH_MB="3500"
SYSTEMD_PORTAL_MAX_MB="6000"
NOTE="超规格. 资源不再紧张, 全量功能开."
;;
*)
echo "❌ [tune] 未知 size_tier=$SIZE_TIER" >&2
exit 1
;;
esac
# 已有 swap >= 1G 时, 不再强制再加 (避免重复建 swapfile)
if [ "$NEED_SWAP_GB" = "1" ] && [ "$SWAP_MB" -ge 1024 ]; then
NEED_SWAP_GB="0"
fi
# ─── 写 .env.tune ─────────────────────────────────────────────
TUNE_FILE="$DATA_ROOT/.env.tune"
mkdir -p "$(dirname "$TUNE_FILE")"
cat > "$TUNE_FILE" <<EOF
# Generated by domain-cn/tune-from-env.sh @ $(date -u +%Y-%m-%dT%H:%M:%SZ)
# 档位: $SIZE_TIER (基于 ${MEM_MB}MB 内存 / ${CPU} 核 / swap ${SWAP_MB}MB)
# 注: $NOTE
#
# ⚠️ 作用域说明:
# - bootstrap.sh source 这个文件
# - PORTAL_INSTANCES / NGINX_WORKER_CONN / FORGEJO_ENABLED /
# LFS_ENABLED / NEED_SWAP_GB 真正影响行为
# - 其他字段是档位决策快照, 给霜砚 / 冰朔追溯
SIZE_TIER=$SIZE_TIER
PORTAL_INSTANCES=$PORTAL_INSTANCES
PORTAL_MAX_MEMORY_MB=$PORTAL_MAX_MEMORY_MB
NGINX_WORKER_CONN=$NGINX_WORKER_CONN
NGINX_WORKER_PROCESSES=$NGINX_WORKER_PROCESSES
FORGEJO_ENABLED=$FORGEJO_ENABLED
LFS_ENABLED=$LFS_ENABLED
NEED_SWAP_GB=$NEED_SWAP_GB
SYSTEMD_PORTAL_HIGH_MB=$SYSTEMD_PORTAL_HIGH_MB
SYSTEMD_PORTAL_MAX_MB=$SYSTEMD_PORTAL_MAX_MB
EOF
chmod 644 "$TUNE_FILE"
# ─── 决策回执 ─────────────────────────────────────────────────
TS="$(date -u +%Y%m%d-%H%M%S)"
RECEIPT="$DEPLOY_ROOT/_logs/tune-decision-$TS.json"
mkdir -p "$DEPLOY_ROOT/_logs"
cat > "$RECEIPT" <<EOF
{
"_sovereign": "TCS-0002∞ · 国作登字-2026-A-00037559",
"_purpose": "domain-cn tune decision",
"decided_at": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
"input": {
"size_tier": "$SIZE_TIER",
"memory_mb": $MEM_MB,
"swap_mb": $SWAP_MB,
"cpu_count": $CPU
},
"decision": {
"PORTAL_INSTANCES": $PORTAL_INSTANCES,
"PORTAL_MAX_MEMORY_MB": $PORTAL_MAX_MEMORY_MB,
"NGINX_WORKER_CONN": $NGINX_WORKER_CONN,
"NGINX_WORKER_PROCESSES": "$NGINX_WORKER_PROCESSES",
"FORGEJO_ENABLED": $FORGEJO_ENABLED,
"LFS_ENABLED": $LFS_ENABLED,
"NEED_SWAP_GB": $NEED_SWAP_GB,
"SYSTEMD_PORTAL_HIGH_MB": $SYSTEMD_PORTAL_HIGH_MB,
"SYSTEMD_PORTAL_MAX_MB": $SYSTEMD_PORTAL_MAX_MB
},
"note": "$NOTE",
"tune_file": "$TUNE_FILE"
}
EOF
echo "═══════════════════════════════════════════════════════════"
echo " [tune · domain-cn] 动态调优决策"
echo "═══════════════════════════════════════════════════════════"
echo " 档位: $SIZE_TIER (${MEM_MB}MB / ${CPU} 核 / swap ${SWAP_MB}MB)"
echo " Portal 进程: $PORTAL_INSTANCES (单进程上限 ${PORTAL_MAX_MEMORY_MB}MB)"
echo " Nginx worker: $NGINX_WORKER_PROCESSES 进程 / $NGINX_WORKER_CONN 连接"
echo " Forgejo: $FORGEJO_ENABLED"
echo " Git LFS: $LFS_ENABLED"
echo " 需要建 swap: $NEED_SWAP_GB G"
echo " systemd MemHi: ${SYSTEMD_PORTAL_HIGH_MB}MB / Max ${SYSTEMD_PORTAL_MAX_MB}MB"
echo " 注: $NOTE"
echo " 写入: $TUNE_FILE"
echo " 回执: $RECEIPT"
echo "═══════════════════════════════════════════════════════════"