#!/usr/bin/env bash # ════════════════════════════════════════════════════════════════ # 根据探测档位动态生成资源调优 · tune-from-env.sh # Sovereign: TCS-0002∞ · 国作登字-2026-A-00037559 # 守护: 铸渊 · ICE-GL-ZY001 # ════════════════════════════════════════════════════════════════ # # 读 detect-env.sh 写出的 server-env.json, 依据 size_tier 生成: # 1. $DATA_ROOT/lighthouse/.env.tune — 决策快照 # 含 SIZE_TIER / PG_SHARED_BUFFERS / PG_WORK_MEM / PG_MAX_CONN # / GITEA_CACHE_POOL / GITEA_QUEUE_LENGTH / RUNNER_DEFAULT_ENABLED # 2. 决策回执 -> $DEPLOY_ROOT/_logs/tune-decision-*.json # # ⚠️ 当前 .env.tune 的真实作用域 (2026-05-08 修正, 别再被注释误导): # .env.tune 不是 docker-compose 的 env_file. compose 启动时不会 # 自动读它 (docker-compose.yml 没有 env_file: .env.tune 声明). # # bootstrap.sh 会在调 docker compose up 之前 `source .env.tune`, # **当前真正影响行为的只有 RUNNER_DEFAULT_ENABLED** — 它决定 update # 阶段是否带 `--profile runner` 起 runner 容器. # # PG_SHARED_BUFFERS / PG_WORK_MEM / PG_MAX_CONN / GITEA_CACHE_POOL / # GITEA_QUEUE_LENGTH 这些字段目前**只是档位决策的存档**, 写到 .env.tune # 是为了: # a) tune-decision-*.json 回执留痕 (霜砚 / 冰朔可追溯) # b) 后续如果在 docker-compose.yml 加上 `env_file: ./.env.tune` + # 在 postgres / gitea 服务里用 `${PG_SHARED_BUFFERS}` 引用, # 这一份就立刻生效, 不用改 tune-from-env.sh # # 也就是说: 这个脚本现在做的事 = "决策 + 留档", 不是"实时调 PG". # 要让 PG 调优真的生效, 需要在 docker-compose.yml 里手动加引用 # (TODO 见 §下方). # # 档位策略 (因果链): # tiny <4G : runner 关掉, postgres shared_buffers=64M, gitea cache 减半 # small 4-6G : runner 关掉, postgres shared_buffers=128M # medium 6-12G: runner=optional (默认关), postgres shared_buffers=256M # large 12-24G: runner=on, postgres shared_buffers=512M # xlarge >=24G: runner=on, postgres shared_buffers=1G # # 设计理念: # 不再硬假设 4C16G. 2C8G 来了也能跑(只是 runner 默认关, 不会同时塞下); # 8C32G 来了也能跑(自动放大 PG buffer). 这一层是"动态适配"的根基. # ════════════════════════════════════════════════════════════════ set -euo pipefail ENV_FILE="${ENV_FILE:-/opt/guanghu/_logs/server-env.json}" DATA_ROOT="${DATA_ROOT:-/data}" DEPLOY_ROOT="${DEPLOY_ROOT:-/opt/guanghu}" 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")" CPU="$(jq -r '.compute.cpu_count' "$ENV_FILE")" # ─── 档位 → 参数表 ──────────────────────────────────────────── case "$SIZE_TIER" in tiny) PG_SHARED_BUFFERS="64MB" PG_WORK_MEM="2MB" PG_MAX_CONN="40" GITEA_CACHE_POOL="50" RUNNER_DEFAULT_ENABLED="false" GITEA_QUEUE_LENGTH="100" NOTE="资源极少, runner 必关, 不要同时跑大型 git push" ;; small) PG_SHARED_BUFFERS="128MB" PG_WORK_MEM="4MB" PG_MAX_CONN="60" GITEA_CACHE_POOL="100" RUNNER_DEFAULT_ENABLED="false" GITEA_QUEUE_LENGTH="200" NOTE="2C8G 档. Gitea+PG+Redis 能跑, runner 默认关 (按需手动 docker compose --profile runner up)" ;; medium) PG_SHARED_BUFFERS="256MB" PG_WORK_MEM="8MB" PG_MAX_CONN="100" GITEA_CACHE_POOL="100" RUNNER_DEFAULT_ENABLED="false" GITEA_QUEUE_LENGTH="500" NOTE="主流档. runner 默认关, 大型构建任务时再开" ;; large) PG_SHARED_BUFFERS="512MB" PG_WORK_MEM="16MB" PG_MAX_CONN="200" GITEA_CACHE_POOL="200" RUNNER_DEFAULT_ENABLED="true" GITEA_QUEUE_LENGTH="1000" NOTE="原计划 4C16G 主灯塔. runner 默认开" ;; xlarge) PG_SHARED_BUFFERS="1GB" PG_WORK_MEM="32MB" PG_MAX_CONN="300" GITEA_CACHE_POOL="300" RUNNER_DEFAULT_ENABLED="true" GITEA_QUEUE_LENGTH="2000" NOTE="超规格, 全部组件并行无忧" ;; *) echo "❌ [tune] 未知 size_tier=$SIZE_TIER" >&2 exit 1 ;; esac # ─── 写 .env.tune (compose 第二份 .env) ─────────────────────── TUNE_FILE="$DATA_ROOT/lighthouse/.env.tune" mkdir -p "$(dirname "$TUNE_FILE")" cat > "$TUNE_FILE" < "$RECEIPT" <