Files
BYW-VoiceHub/scripts/setup-runner.sh
T
Henry_Du ed66d2d79f
构建 & 部署 BYW VoiceHub / Preflight 语法 & 构建检查 (push) Canceled after 0s
构建 & 部署 BYW VoiceHub / 构建并推送镜像 (push) Canceled after 0s
构建 & 部署 BYW VoiceHub / 部署到生产服务器 (push) Canceled after 0s
fix: 兼容中文 Gitea 1.27 的纯字母数字 Registration Token
2026-09-06 09:01:23 +08:00

281 lines
12 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bash
# ============================================================================
# setup-runner.sh —— 一键安装并注册 Gitea Actions Runner(act_runner)
#
# ✅ 兼容 Gitea 1.21 ~ 最新(含 1.27.x),新版没有 Platform 下拉菜单。
#
# 使用方法(两种模式任选其一,推荐 模式 A 最省事):
#
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# 模式 A:仓库级 Runner(只给这个 VoiceHub 仓库用,最常用、权限最小)
# 路径:你的仓库 → Settings → Actions → Runners → 右上角
# → 新版(1.21+)这里没有 Platform 选择,直接有一个输入框
# 写着「Registration token」或「注册令牌」
# → 点右边的 📋 复制按钮,得到一串以 R 开头的 token
# 例: RGT8FZxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxV
#
# 机器上执行:
# sudo bash scripts/setup-runner.sh \
# --scope repo --gitea https://你的-gitea --token RGTxxxx...
#
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# 模式 B:组织级 Runner(同一个 Gitea 组织下所有仓库都能用)
# 路径:组织主页 → Settings → Actions → Runners → 复制 Registration token
# (Token 开头一般是 RGOxxxx)
#
# 执行:
# sudo bash scripts/setup-runner.sh \
# --scope org --gitea https://你的-gitea --token RGOxxxx...
#
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# 模式 C:全局/站点级 Runner(Gitea 全站所有仓库都能用,需站点管理员)
# 路径:站点管理后台(Site Administration)→ Actions → Runners
# → 复制 Registration token(开头一般是 RGxxxx)
#
# 执行:
# sudo bash scripts/setup-runner.sh \
# --scope global --gitea https://你的-gitea --token RGxxxx...
#
# 其他可选参数:
# --name "my-runner-01" 自定义 Runner 名字(默认是 runner-主机名)
# --user gitrunner 运行用户(默认 gitrunner)
# --dir /opt/act_runner 安装目录(默认 /opt/act_runner)
# ============================================================================
set -euo pipefail
# ---------- 颜色 ----------
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; CYAN='\033[1;36m'; NC='\033[0m'
info() { echo -e "${GREEN}[INFO]${NC} $*"; }
warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
err() { echo -e "${RED}[ERROR]${NC} $*" >&2; exit 1; }
ok() { echo -e "${CYAN}[ OK ]${NC} $*"; }
# ---------- 解析参数 ----------
GITEA_URL=""
REG_TOKEN=""
SCOPE="repo" # repo | org | global(默认 repo,绝大多数人的场景)
RUNNER_NAME="runner-$(hostname | tr '[:upper:]' '[:lower:]')"
RUNNER_USER="gitrunner"
INSTALL_DIR="/opt/act_runner"
while [[ $# -gt 0 ]]; do
case "$1" in
--gitea) GITEA_URL="${2}"; shift 2 ;;
--token) REG_TOKEN="${2}"; shift 2 ;;
--scope) SCOPE="${2}"; shift 2 ;;
--name) RUNNER_NAME="${2}"; shift 2 ;;
--user) RUNNER_USER="${2}"; shift 2 ;;
--dir) INSTALL_DIR="${2}"; shift 2 ;;
-h|--help)
sed -n '2,60p' "$0" | sed 's/^# \{0,1\}//'
exit 0
;;
*) err "未知参数:$1(--help 查看帮助)" ;;
esac
done
[[ -n "${GITEA_URL}" ]] || err "必须传 --gitea https://你的-gitea-地址"
[[ -n "${REG_TOKEN}" ]] || err "必须传 --token(从 Gitea 页面的 Registration token 复制,Rxx 开头的一串)"
case "${SCOPE}" in
repo|org|global) ;;
*) err "--scope 必须是 repo | org | global 其中之一" ;;
esac
[[ $EUID -eq 0 ]] || err "请用 sudo 运行本脚本(需要写 /opt / /etc/systemd/system)"
# 去掉末尾 /
GITEA_URL="${GITEA_URL%/}"
echo ""
echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo -e "${CYAN} 🚀 开始部署 Gitea Actions Runner (兼容 1.21 ~ 1.27+)${NC}"
echo -e "${CYAN} • 绑定 Gitea : ${GITEA_URL}${NC}"
echo -e "${CYAN} • 作用域 : ${SCOPE}${NC}"
echo -e "${CYAN} • Runner 名称 : ${RUNNER_NAME}${NC}"
echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo ""
# ---------- 0. 架构检测 ----------
ARCH="$(uname -m)"
case "${ARCH}" in
x86_64|amd64) PLATFORM="linux-amd64" ;;
aarch64|arm64) PLATFORM="linux-arm64" ;;
armv7l) PLATFORM="linux-arm" ;;
*) err "暂不支持的架构:${ARCH}(需要 x86_64 / aarch64 / armv7)" ;;
esac
ok "检测到架构:${ARCH} → 下载版本:${PLATFORM}"
# ---------- 0.5 给新版 Gitea 用户的 Token 格式提示 ----------
# 不同版本 / 语言包的 Token 前缀不一样,兼容 4 种真实存在的格式:
# • 英文 1.21+ 仓库级 RGTxxxx / 组织级 RGOxxxx / 全局 RGxxxx
# • 中文语言包 / 某些二次分发版本:纯字母数字 20~64 位(如 LHLDAwsho7vVSukoEeKhft)
TOKEN_LEN="${#REG_TOKEN}"
ok "Token 长度 = ${TOKEN_LEN} 位"
case "${REG_TOKEN}" in
# 英文原版前缀
RG*) info "• Token 前缀 RG:全局/站点级(英文原版)✅" ;;
RGO*) info "• Token 前缀 RGO:组织级(英文原版)✅" ;;
RGT*) info "• Token 前缀 RGT:仓库级(英文原版)✅" ;;
# 纯字母数字(中文 UI / 二开版本常见)
[A-Za-z0-9]\{16,128\})
ok "• 纯字母数字 Token(中文 UI / 某些二开版本常见)✅,和截图里的「注册令牌」一致"
;;
# 其他
*)
warn "• Token 看起来不是 Gitea 常见格式。不过也可能是新版改动,继续尝试注册..."
warn " 如果注册报 401/403,建议回到页面点一次「重置注册令牌」重新复制。"
;;
esac
# 基本字符集校验(防止复制时粘了空格或换行)
if [[ ! "${REG_TOKEN}" =~ ^[A-Za-z0-9]+$ ]]; then
warn "⚠️ Token 里含有非字母数字的字符,很可能是复制时多带了空格/换行/标点!"
warn " 建议回到仓库页面点 📋 复制按钮(不要手选文字)。"
fi
# ---------- 1. 安装依赖:docker(Runner 要用 Docker-in-Docker 执行 buildx 等)----------
if ! command -v docker >/dev/null 2>&1; then
info "检测到没装 Docker,现在用官方一键脚本安装(国内自动换清华源)..."
curl -fsSL https://get.docker.com -o /tmp/get-docker.sh || err "下载 docker-install 脚本失败"
if curl -sI https://mirrors.tuna.tsinghua.edu.cn >/dev/null; then
bash /tmp/get-docker.sh --mirror Aliyun || bash /tmp/get-docker.sh
else
bash /tmp/get-docker.sh
fi
systemctl enable --now docker
info "✅ Docker 安装完成:$(docker --version)"
else
info "✅ Docker 已存在:$(docker --version)"
fi
# ---------- 2. 建运行用户 gitrunner,加入 docker 组 ----------
if ! id -u "${RUNNER_USER}" >/dev/null 2>&1; then
useradd -r -s /usr/sbin/nologin -d "${INSTALL_DIR}" "${RUNNER_USER}"
info "✅ 新建系统用户 ${RUNNER_USER}"
else
info "ℹ️ 用户 ${RUNNER_USER} 已存在,跳过创建"
fi
usermod -aG docker "${RUNNER_USER}"
info "✅ 把 ${RUNNER_USER} 加入 docker 组(允许操作 Docker daemon)"
mkdir -p "${INSTALL_DIR}"
chown -R "${RUNNER_USER}:${RUNNER_USER}" "${INSTALL_DIR}"
# ---------- 3. 下载最新 act_runner ----------
info "⬇️ 正在拉取 act_runner 最新 release 元数据..."
LATEST_JSON="$(curl -fsSL https://gitea.com/api/v1/repos/gitea/act_runner/releases/latest || true)"
if [[ -z "${LATEST_JSON}" ]]; then
warn "gitea.com 不通,改用硬编码版本 0.2.10(你之后可手动升级)"
VERSION="0.2.10"
else
VERSION="$(echo "${LATEST_JSON}" | grep -oE '"tag_name":\s*"[^"]+"' | head -1 | cut -d'"' -f4 | sed 's/^v//')"
[[ -n "${VERSION}" ]] || VERSION="0.2.10"
fi
BIN_URL="https://dl.gitea.com/act_runner/${VERSION}/act_runner-${VERSION}-${PLATFORM}"
info "⬇️ 下载 act_runner v${VERSION}:${BIN_URL}"
curl -fsSL "${BIN_URL}" -o /usr/local/bin/act_runner \
|| err "下载失败。请手动打开 ${BIN_URL} 看是否 404,然后换个版本"
chmod +x /usr/local/bin/act_runner
info "✅ act_runner 已安装到 /usr/local/bin,版本:$(act_runner --version 2>&1 || true)"
# ---------- 4. 注册 Runner ----------
cd "${INSTALL_DIR}"
info "🔗 开始注册 Runner 到 ${GITEA_URL}(名称:${RUNNER_NAME})"
# 切到 gitrunner 用户注册,避免 root 跑(安全)
rm -f .runner 2>/dev/null || true
sudo -u "${RUNNER_USER}" env HOME="${INSTALL_DIR}" \
act_runner register \
--instance "${GITEA_URL}" \
--token "${REG_TOKEN}" \
--name "${RUNNER_NAME}" \
--labels "ubuntu-latest:docker://catthehacker/ubuntu:act-22.04" \
--no-interactive \
|| err "注册失败!常见原因:\n 1) token 不对(复制时别带空格)\n 2) Runner 机器出不了网到 ${GITEA_URL}\n 3) Gitea 站点时间和这台机器差太远(证书验证失败)"
chown "${RUNNER_USER}:${RUNNER_USER}" .runner 2>/dev/null || true
# ---------- 5. 生成配置文件(建议开启 docker.host 特权)----------
CONFIG_FILE="${INSTALL_DIR}/config.yaml"
if [[ ! -f "${CONFIG_FILE}" ]]; then
cat > "${CONFIG_FILE}" <<'YAML'
log:
level: info
runner:
file: .runner
capacity: 2 # 同一台 Runner 最多同时跑 2 个 Job
envs:
GOPROXY: https://goproxy.cn,direct
NPM_CONFIG_REGISTRY: https://registry.npmmirror.com
timeout: 3h
cache:
enabled: true
dir: /opt/act_runner/cache
container:
network: "bridge"
privileged: true # build-push-action 用到 Docker daemon
options: |
--add-host "host.docker.internal:host-gateway"
YAML
chown "${RUNNER_USER}:${RUNNER_USER}" "${CONFIG_FILE}"
mkdir -p "${INSTALL_DIR}/cache"
chown -R "${RUNNER_USER}:${RUNNER_USER}" "${INSTALL_DIR}/cache"
info "✅ 默认 config 写入 ${CONFIG_FILE}"
fi
# ---------- 6. 写 systemd 服务,开机自启 ----------
UNIT_FILE="/etc/systemd/system/gitea-act-runner.service"
cat > "${UNIT_FILE}" <<SYSTEMD
[Unit]
Description=Gitea Actions Runner (${RUNNER_NAME})
After=network.target docker.service
Requires=docker.service
[Service]
Type=simple
User=${RUNNER_USER}
Group=${RUNNER_USER}
WorkingDirectory=${INSTALL_DIR}
Environment=HOME=${INSTALL_DIR}
ExecStart=/usr/local/bin/act_runner daemon --config ${CONFIG_FILE}
Restart=always
RestartSec=5
KillMode=mixed
TimeoutStopSec=30
# 安全加固
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ReadWritePaths=${INSTALL_DIR} /var/run/docker.sock /tmp /var/tmp
[Install]
WantedBy=multi-user.target
SYSTEMD
systemctl daemon-reload
systemctl enable --now gitea-act-runner
info "✅ systemd 服务已写入并启动:${UNIT_FILE}"
sleep 3 # 给 daemon 点时间注册
info "📌 当前 Runner 状态:"
systemctl --no-pager status gitea-act-runner | head -15 || true
info "📌 最近 30 行日志(验证 OK):"
journalctl --no-pager -u gitea-act-runner --since "2 minutes ago" -n 30 || true
echo ""
echo -e "${GREEN}===========================================================================${NC}"
echo -e "${GREEN} 🎉 Gitea Actions Runner 安装 & 注册 & 开机自启 全部完成!${NC}"
echo -e "${GREEN}===========================================================================${NC}"
echo " ✅ Runner 名称 : ${RUNNER_NAME}"
echo " ✅ 运行用户 : ${RUNNER_USER}"
echo " ✅ 安装目录 : ${INSTALL_DIR}"
echo " ✅ 绑定 Gitea : ${GITEA_URL}"
echo ""
echo " 👉 下一步验证(建议立刻做):"
echo " 1. 浏览器打开:${GITEA_URL} → 仓库 → Settings → Actions → Runners"
echo " 应该能看到一个 Runner,状态 = Idle"
echo " 2. 回到终端,模拟跑一个 workflow 没问题就彻底大功告成!"
echo " 👉 常用命令:"
echo " systemctl {start|stop|restart|status} gitea-act-runner"
echo " journalctl -u gitea-act-runner -f # 实时看日志"
echo ""