100 lines
4.0 KiB
Bash
100 lines
4.0 KiB
Bash
#!/bin/bash
|
|||
|
|
# ============================================================
|
||
|
|
# 高考质量分析系统 · 一条命令部署(群晖/Linux Docker)
|
||
|
|
# 用法(环境变量前缀传参, 注意 APP_DIR/DATA_DIR 必须在 bash -c 之前):
|
||
|
|
# APP_DIR=/volume2/docker/gaokao-sys DATA_DIR=/volume2/docker/gaokao-sys-data \
|
||
|
|
# bash -c "$(curl -fsSL http://192.168.1.6:3000/bennyao/gaokao-deploy/raw/branch/master/init.sh)"
|
||
|
|
# 若目标目录无写权限, 先执行: sudo mkdir -p <APP_DIR> <DATA_DIR>/data && sudo chown -R $(whoami) <APP_DIR> <DATA_DIR>
|
||
|
|
# ============================================================
|
||
|
|
set -e
|
||
|
|
|
||
|
|
GITEA_HOST="${GITEA_HOST:-192.168.1.6}"
|
||
|
|
GITEA_PORT="${GITEA_PORT:-3000}"
|
||
|
|
GITEA_OWNER="${GITEA_OWNER:-bennyao}"
|
||
|
|
GITEA_REPO="${GITEA_REPO:-gaokao-sys}"
|
||
|
|
TOKEN_NAME="${TOKEN_NAME:-gaokao-deploy}"
|
||
|
|
APP_DIR="${APP_DIR:-/opt/gaokao-sys}"
|
||
|
|
DATA_DIR="${DATA_DIR:-/opt/gaokao-sys-data}"
|
||
|
|
PORT="${PORT:-8501}"
|
||
|
|
KEY_PATH="$DATA_DIR/.ssh_key"
|
||
|
|
BASE="http://$GITEA_HOST:$GITEA_PORT"
|
||
|
|
API="$BASE/api/v1/repos/$GITEA_OWNER/$GITEA_REPO"
|
||
|
|
|
||
|
|
# ---- 令牌: 环境变量优先, 否则交互静默输入(绕过管道 stdin) ----
|
||
|
|
if [ -z "$GITEA_TOKEN" ]; then
|
||
|
|
read -s -p "请输入 Gitea 访问令牌(静默, 不回显): " GITEA_TOKEN < /dev/tty
|
||
|
|
echo ""
|
||
|
|
fi
|
||
|
|
: "${GITEA_TOKEN:?未输入令牌, 中止}"
|
||
|
|
TOKEN_CLEANED=0
|
||
|
|
|
||
|
|
# ---- 退出时自动删除一次性令牌 ----
|
||
|
|
cleanup() {
|
||
|
|
if [ -n "$GITEA_TOKEN" ] && [ "$TOKEN_CLEANED" != "1" ]; then
|
||
|
|
if curl -fsS -X DELETE -H "Authorization: token $GITEA_TOKEN" \
|
||
|
|
"$BASE/api/v1/user/tokens/$GITEA_OWNER/$TOKEN_NAME" >/dev/null 2>&1; then
|
||
|
|
echo "[OK] 一次性令牌已自动删除"
|
||
|
|
else
|
||
|
|
echo "[提示] 令牌自动删除失败, 请管理员到 Gitea → 设置 → 应用 手动删除"
|
||
|
|
fi
|
||
|
|
fi
|
||
|
|
}
|
||
|
|
trap cleanup EXIT
|
||
|
|
|
||
|
|
echo "==> [1/7] 检查 Docker"
|
||
|
|
command -v docker >/dev/null 2>&1 || { echo "[错误] 未安装 Docker"; exit 1; }
|
||
|
|
|
||
|
|
echo "==> [2/7] 准备目录并克隆代码(令牌认证)"
|
||
|
|
mkdir -p "$APP_DIR" 2>/dev/null || {
|
||
|
|
echo "[错误] 无法创建 $APP_DIR(权限不足)"
|
||
|
|
echo "请先执行: sudo mkdir -p $APP_DIR $DATA_DIR/data && sudo chown -R \$(whoami) $APP_DIR $DATA_DIR"
|
||
|
|
exit 1
|
||
|
|
}
|
||
|
|
mkdir -p "$DATA_DIR/data" 2>/dev/null || {
|
||
|
|
echo "[错误] 无法创建 $DATA_DIR/data(权限不足)"
|
||
|
|
echo "请先执行: sudo mkdir -p $DATA_DIR/data && sudo chown -R \$(whoami) $DATA_DIR"
|
||
|
|
exit 1
|
||
|
|
}
|
||
|
|
if [ ! -d "$APP_DIR/.git" ]; then
|
||
|
|
git clone "http://oauth2:$GITEA_TOKEN@$GITEA_HOST:$GITEA_PORT/$GITEA_OWNER/$GITEA_REPO.git" "$APP_DIR"
|
||
|
|
else
|
||
|
|
cd "$APP_DIR" && git pull
|
||
|
|
fi
|
||
|
|
|
||
|
|
echo "==> [3/7] 生成部署密钥并自动加入 Gitea(API, 升级免密)"
|
||
|
|
if [ ! -f "$KEY_PATH" ]; then
|
||
|
|
ssh-keygen -t rsa -b 4096 -f "$KEY_PATH" -N "" -q
|
||
|
|
PUB="$(cat "$KEY_PATH.pub")"
|
||
|
|
if curl -fsS -X POST -H "Authorization: token $GITEA_TOKEN" \
|
||
|
|
-H "Content-Type: application/json" \
|
||
|
|
-d "{\"title\":\"$(hostname)-deploy\",\"key\":\"$PUB\",\"read_only\":true}" \
|
||
|
|
"$API/keys" >/dev/null 2>&1; then
|
||
|
|
echo "[OK] 部署密钥已自动添加(只读)"
|
||
|
|
else
|
||
|
|
echo "[提示] 部署密钥添加失败: 到 Gitea → gaokao-sys → 设置 → 部署密钥 手动添加(只读):"
|
||
|
|
cat "$KEY_PATH.pub"
|
||
|
|
fi
|
||
|
|
fi
|
||
|
|
chmod 600 "$KEY_PATH"
|
||
|
|
|
||
|
|
echo "==> [4/7] 构建镜像(首次较慢)"
|
||
|
|
cd "$APP_DIR"
|
||
|
|
docker build -t gaokao-sys:latest .
|
||
|
|
|
||
|
|
echo "==> [5/7] 启动容器"
|
||
|
|
docker rm -f gaokao-sys >/dev/null 2>&1 || true
|
||
|
|
docker run -d --name gaokao-sys --restart=unless-stopped -p "$PORT:8501" \
|
||
|
|
-v "$APP_DIR":/app \
|
||
|
|
-v "$DATA_DIR/data":/app/data \
|
||
|
|
-v "$KEY_PATH":/app/.ssh_key:ro \
|
||
|
|
gaokao-sys:latest
|
||
|
|
|
||
|
|
echo "==> [6/7] 验证"
|
||
|
|
sleep 10
|
||
|
|
curl -sf "http://127.0.0.1:$PORT/_stcore/health" >/dev/null 2>&1 && echo "[OK] 服务健康" || echo "[警告] 服务未响应: docker logs gaokao-sys"
|
||
|
|
|
||
|
|
echo "==> [7/7] 完成"
|
||
|
|
IP=$(hostname -I 2>/dev/null | awk '{print $1}')
|
||
|
|
echo " 访问: http://${IP:-<本机IP>}:$PORT"
|
||
|
|
echo " 升级: 系统内「数据管理 → 🔄 更新」(手动/全自动, 走只读部署密钥)"
|