ci: 新增 Gitea Actions 部署流水线 + Runner/Deploy 一键脚本
构建 & 部署 BYW VoiceHub / Preflight 语法 & 构建检查 (push) Canceled after 0s
构建 & 部署 BYW VoiceHub / 构建并推送镜像 (push) Canceled after 0s
构建 & 部署 BYW VoiceHub / 部署到生产服务器 (push) Canceled after 0s

This commit is contained in:
2026-09-06 08:44:11 +08:00
parent 1718542228
commit 5d015a3529
3 changed files with 617 additions and 90 deletions
+159
View File
@@ -0,0 +1,159 @@
#!/usr/bin/env bash
# ============================================================================
# setup-deploy-user.sh
# 在「生产服务器」上一键做好 CI 自动部署所需的系统配置:
# 1) 新建 deploy 用户(低权限,禁止密码登录,只能 key 登录)
# 2) 生成 ed25519 SSH 密钥对(私钥你粘去 Gitea Secrets DEPLOY_SSH_KEY)
# 3) 加入 docker 组,允许 docker compose 操作
# 4) 给 /opt/byw-voicehub 目录读写权限(setfacl)
# 5) 打印私钥内容 & 公钥指纹,便于你检查和复制
#
# 用法(在生产服务器上,sudo 运行):
# sudo bash scripts/setup-deploy-user.sh [--deploy-dir /opt/byw-voicehub]
# ============================================================================
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} $*"; }
DEPLOY_DIR="/opt/byw-voicehub"
DEPLOY_USER="deploy"
while [[ $# -gt 0 ]]; do
case "$1" in
--deploy-dir) DEPLOY_DIR="$2"; shift 2 ;;
--user) DEPLOY_USER="$2"; shift 2 ;;
-h|--help)
sed -n '2,15p' "$0" | sed 's/^# \{0,1\}//'
exit 0
;;
*) err "未知参数 $1(--help 查看帮助)" ;;
esac
done
[[ $EUID -eq 0 ]] || err "请用 sudo 运行本脚本"
command -v docker >/dev/null 2>&1 || err "先装完 Docker 再跑本脚本(路径一的教程里有)"
command -v setfacl >/dev/null 2>&1 || {
warn "没装 acl 工具,现在 apt install"
apt-get update && apt-get install -y acl
}
# -------- 1. 建用户 --------
if ! id -u "${DEPLOY_USER}" >/dev/null 2>&1; then
useradd --create-home --shell /usr/bin/bash --disabled-password "${DEPLOY_USER}"
ok "新建用户:${DEPLOY_USER}(无密码,仅 SSH key 登录)"
else
info "用户 ${DEPLOY_USER} 已存在,跳过创建"
fi
# -------- 2. 加入 docker 组 --------
usermod -aG docker "${DEPLOY_USER}"
ok "${DEPLOY_USER} 加入 docker 组(有权限执行 docker compose)"
# -------- 3. 生成 SSH 密钥(无密码) --------
SSH_DIR="/home/${DEPLOY_USER}/.ssh"
mkdir -p "${SSH_DIR}"
chmod 700 "${SSH_DIR}"
chown "${DEPLOY_USER}:${DEPLOY_USER}" "${SSH_DIR}"
KEY_PATH="${SSH_DIR}/id_ed25519"
if [[ ! -f "${KEY_PATH}" ]]; then
sudo -u "${DEPLOY_USER}" ssh-keygen -t ed25519 \
-C "gitea-actions-deploy-$(hostname)" \
-f "${KEY_PATH}" \
-N "" >/dev/null
ok "SSH ed25519 密钥对生成:${KEY_PATH}"
else
info "密钥对已存在,跳过生成:${KEY_PATH}"
fi
# 公钥加入 authorized_keys(允许持对应私钥的人以 deploy 用户 ssh 登录)
AUTH_KEYS="${SSH_DIR}/authorized_keys"
touch "${AUTH_KEYS}"
PUBKEY_CONTENT="$(cat "${KEY_PATH}.pub")"
if ! grep -qF "${PUBKEY_CONTENT}" "${AUTH_KEYS}" 2>/dev/null; then
echo "${PUBKEY_CONTENT}" >> "${AUTH_KEYS}"
ok "公钥已写入 authorized_keys"
fi
chmod 600 "${AUTH_KEYS}"
chmod 644 "${KEY_PATH}.pub"
chmod 600 "${KEY_PATH}"
chown -R "${DEPLOY_USER}:${DEPLOY_USER}" "${SSH_DIR}"
# -------- 4. sshd 加固(只允许公钥登录;别让 root 密码登录;deploy 禁止转发)--------
SSHD_SNIPPET="/etc/ssh/sshd_config.d/99-deploy-user.conf"
if [[ ! -f "${SSHD_SNIPPET}" ]]; then
mkdir -p /etc/ssh/sshd_config.d
cat > "${SSHD_SNIPPET}" <<SSHD
# 针对 deploy 用户:仅允许公钥登录,禁用 TCP 转发等
Match User ${DEPLOY_USER}
PasswordAuthentication no
PubkeyAuthentication yes
PermitTTY yes
AllowTcpForwarding no
X11Forwarding no
SSHD
systemctl reload sshd 2>/dev/null || service ssh reload || true
ok "sshd 配置已加固(deploy 只允许公钥登录,并禁用端口转发)"
fi
# -------- 5. 创建部署目录并给 deploy 权限 --------
mkdir -p "${DEPLOY_DIR}"
# 既设组权限,又加 ACL,确保后续新建文件也有
setfacl -R -m "u:${DEPLOY_USER}:rwX" "${DEPLOY_DIR}"
setfacl -R -d -m "u:${DEPLOY_USER}:rwX" "${DEPLOY_DIR}"
ok "部署目录 ${DEPLOY_DIR} 已给 ${DEPLOY_USER} 完整读写权限(+ 新建文件继承权限)"
# 如果目录里有 compose/环境文件,顺便改一下属组,避免「root 建的文件 deploy 改不了」
chgrp -R docker "${DEPLOY_DIR}" 2>/dev/null || true
chmod -R g+rwX "${DEPLOY_DIR}" 2>/dev/null || true
# -------- 6. 验证 docker 是否真能用(不报错)--------
DOCKER_RC=0
sudo -u "${DEPLOY_USER}" docker ps >/dev/null 2>&1 || DOCKER_RC=$?
if [[ ${DOCKER_RC} -eq 0 ]]; then
ok "✅ ${DEPLOY_USER} 可以执行 docker 命令"
else
warn "⚠️ ${DEPLOY_USER} 暂时跑不了 docker(可能需要重新登录一次刷新组),部署时不会有影响(但验证时会再触发一次)"
fi
# -------- 7. 打印信息 --------
FINGERPRINT="$(ssh-keygen -l -f "${KEY_PATH}.pub" 2>/dev/null || true)"
PUBKEY_CONTENT="$(cat "${KEY_PATH}.pub")"
PRIVATE_CONTENT="$(cat "${KEY_PATH}")"
clear
echo -e "${GREEN}================================================================================${NC}"
echo -e "${GREEN} 🎉 部署用户 & SSH 密钥 配置完成!${NC}"
echo -e "${GREEN}================================================================================${NC}"
echo -e " 👤 部署用户名 :${CYAN}${DEPLOY_USER}${NC}"
echo -e " 📂 部署目录 :${CYAN}${DEPLOY_DIR}${NC}"
echo -e " 🔑 私钥文件路径 :${CYAN}${KEY_PATH}${NC}"
echo -e " 🧾 公钥指纹 :${FINGERPRINT}"
echo -e " 🧾 公钥内容(方便核对):"
echo -e " ${PUBKEY_CONTENT}"
echo ""
echo -e "${YELLOW}================================================================================${NC}"
echo -e "${YELLOW} ⚠️ 下面这一整段是【私钥】,完整复制(从 BEGIN 到 END 包括两行)到:${NC}"
echo -e "${YELLOW} Gitea 仓库 → Settings → Secrets and variables → Actions → New Secret${NC}"
echo -e "${YELLOW} Name = DEPLOY_SSH_KEY${NC}"
echo -e "${YELLOW} Value = 粘贴下面一整段(包括 -----BEGIN/END-----)${NC}"
echo -e "${YELLOW}================================================================================${NC}"
echo ""
echo "${PRIVATE_CONTENT}"
echo ""
echo -e "${YELLOW}================================================================================${NC}"
echo -e "${YELLOW} ⚠️ 上面就是 DEPLOY_SSH_KEY,不要在任何地方贴到别的文档或聊天。看完 Ctrl+L 清屏。${NC}"
echo -e "${YELLOW}================================================================================${NC}"
echo ""
echo -e "${CYAN}👉 同时你还需要补以下几个 Repository Secrets(都在同一页添加):${NC}"
echo -e " • DEPLOY_HOST = 你的服务器公网 IP 或域名"
echo -e " • DEPLOY_PORT = SSH 端口(一般 22)"
echo -e " • DEPLOY_USER = ${DEPLOY_USER}(就是这个用户名)"
echo -e " • REGISTRY_TOKEN = 你的 Gitea 个人访问令牌(Package 读写权限)"
echo -e " • REGISTRY_PULL_USER = 同 REGISTRY_USER(服务器上拉镜像用,一般和 REGISTRY_USER 一样)"
echo -e " • REGISTRY_PULL_TOKEN= 上面令牌同一个或新建一个仅 pull 权限的更安全"
echo -e " • NUXT_PUBLIC_SITE_URL = https://你的域名.com(用来显示部署成功后的跳转按钮)"
echo ""