Files
BYW-VoiceHub/scripts/setup-deploy-user.sh
T
Henry_Du 5d015a3529
构建 & 部署 BYW VoiceHub / Preflight 语法 & 构建检查 (push) Canceled after 0s
构建 & 部署 BYW VoiceHub / 构建并推送镜像 (push) Canceled after 0s
构建 & 部署 BYW VoiceHub / 部署到生产服务器 (push) Canceled after 0s
ci: 新增 Gitea Actions 部署流水线 + Runner/Deploy 一键脚本
2026-09-06 08:44:11 +08:00

160 lines
7.2 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-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 ""