Files
drinking-game/deploy/setup.sh
gongch 6d1dd5d56c Initial commit: 酒桌派对 / 大话骰 multiplayer drinking-game hub
- server.py: zero-dependency stdlib backend (HTTP + WebSocket /ws), 大话骰 rule engine, server-driven bots
- live.html: real MVP frontend wired to the backend over WebSocket
- index.html/app.js/style.css: older static prototype
- deploy/: systemd unit + Nginx reverse proxy + Let's Encrypt setup.sh
- test_*.py: standalone HTTP / in-process test scripts

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 10:05:10 +08:00

91 lines
4.0 KiB
Bash
Executable File
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
#
# 在服务器上一键部署「酒桌派对 / 大话骰」
# - 把项目复制到 /opt/drinking-games
# - systemd 常驻运行 server.py (127.0.0.1 视角的 8765 端口,外部由 Nginx 反代)
# - Nginx 反向代理 dn.akqp.online -> 8765含 WebSocket
# - certbot 自动签发 Let's Encrypt 证书并配置 HTTPS + 80→443 跳转
#
# 用法(在已 scp 上来的项目根目录里执行):
# sudo bash deploy/setup.sh
#
set -euo pipefail
DOMAIN="dn.akqp.online"
APP_DIR="/opt/drinking-games"
EMAIL="PumpkinPiekur@hairdresser.net" # certbot 续期通知邮箱
SRC_DIR="$(cd "$(dirname "$0")/.." && pwd)"
log() { printf '\n\033[1;36m== %s\033[0m\n' "$*"; }
die() { printf '\n\033[1;31m[ERR] %s\033[0m\n' "$*" >&2; exit 1; }
[ "$(id -u)" = "0" ] || die "请用 root 执行sudo bash deploy/setup.sh"
command -v python3 >/dev/null || die "未找到 python3"
# ---------- 0. Cloudflare 代理检测 ----------
log "检测域名解析Let's Encrypt 需直连源站)"
SERVER_IP="$(curl -fsS --max-time 10 https://api.ipify.org || echo '?')"
RESOLVED="$(getent ahostsv4 "$DOMAIN" | awk '{print $1}' | sort -u | tr '\n' ' ')"
echo " 本机公网 IP : $SERVER_IP"
echo " 域名解析到 : ${RESOLVED:-(无)}"
if [ "$SERVER_IP" != "?" ] && ! echo " $RESOLVED " | grep -q " $SERVER_IP "; then
cat <<EOF
⚠ $DOMAIN 当前未直接解析到本机(可能在 Cloudflare 橙云代理后面)。
Let's Encrypt 的 HTTP-01 验证可能失败。建议二选一:
a) 在 Cloudflare 把该记录临时切到 "DNS only"(灰云)直连本机,签完证书再开回代理;
开回代理后请把 SSL/TLS 模式设为 Full (strict)。
b) 保持代理,但确保 SSL 模式为 Full 且未强制把 80 端口跳转。
脚本将继续,签证书若失败会停在 certbot 步骤,按上面处理后重跑即可。
EOF
fi
# ---------- 1. 安装依赖 ----------
log "安装 Nginx 与 certbot"
export DEBIAN_FRONTEND=noninteractive
apt-get update -y
apt-get install -y nginx certbot python3-certbot-nginx rsync
# ---------- 2. 部署应用 ----------
log "复制项目到 $APP_DIR"
mkdir -p "$APP_DIR"
rsync -a --delete \
--exclude '.git' --exclude '__pycache__' --exclude 'deploy' \
--exclude 'test_*.py' \
"$SRC_DIR"/ "$APP_DIR"/
log "安装 systemd 服务 drinking-games"
install -m 644 "$SRC_DIR/deploy/drinking-games.service" /etc/systemd/system/drinking-games.service
systemctl daemon-reload
systemctl enable drinking-games
systemctl restart drinking-games
sleep 1
systemctl is-active --quiet drinking-games || { journalctl -u drinking-games --no-pager -n 30; die "服务启动失败"; }
curl -fsS --max-time 5 http://127.0.0.1:8765/api/rooms >/dev/null && echo " 后端本地自检 OK" || echo " ⚠ 后端本地自检失败,稍后检查日志"
# ---------- 3. Nginx 反代 ----------
log "配置 Nginx 反向代理"
install -m 644 "$SRC_DIR/deploy/nginx-dn.akqp.online.conf" /etc/nginx/sites-available/dn.akqp.online.conf
ln -sf /etc/nginx/sites-available/dn.akqp.online.conf /etc/nginx/sites-enabled/dn.akqp.online.conf
[ -e /etc/nginx/sites-enabled/default ] && rm -f /etc/nginx/sites-enabled/default || true
nginx -t
systemctl reload nginx
# ---------- 4. 防火墙(若启用了 ufw ----------
if command -v ufw >/dev/null && ufw status | grep -q "Status: active"; then
log "放行 80/443关闭 8765 外部访问"
ufw allow 'Nginx Full' || true
ufw deny 8765/tcp || true
fi
# ---------- 5. HTTPS 证书 ----------
log "签发 Let's Encrypt 证书并启用 HTTPS"
certbot --nginx -d "$DOMAIN" \
--non-interactive --agree-tos -m "$EMAIL" \
--redirect || die "证书签发失败(多为 Cloudflare 代理导致 HTTP-01 验证不通),按开头提示处理后重跑本脚本"
systemctl reload nginx
log "完成"
echo " 访问: https://$DOMAIN/ (自动跳到 /live.html"
echo " 服务: systemctl status drinking-games | journalctl -u drinking-games -f"
echo " 证书自动续期由 certbot.timer 负责,可用 'certbot renew --dry-run' 验证。"