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>
This commit is contained in:
15
deploy/drinking-games.service
Normal file
15
deploy/drinking-games.service
Normal file
@@ -0,0 +1,15 @@
|
||||
[Unit]
|
||||
Description=Drinking Games Hub (大话骰)
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
WorkingDirectory=/opt/drinking-games
|
||||
ExecStart=/usr/bin/python3 /opt/drinking-games/server.py
|
||||
Restart=always
|
||||
RestartSec=2
|
||||
User=root
|
||||
# server.py 监听 0.0.0.0:8765,由 Nginx 反代;防火墙应只放行 80/443
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
35
deploy/nginx-dn.akqp.online.conf
Normal file
35
deploy/nginx-dn.akqp.online.conf
Normal file
@@ -0,0 +1,35 @@
|
||||
# Nginx 反向代理 — dn.akqp.online → 127.0.0.1:8765 (server.py)
|
||||
# 支持 WebSocket(/ws)。HTTPS 由 certbot --nginx 自动追加 443 段与跳转。
|
||||
|
||||
map $http_upgrade $connection_upgrade {
|
||||
default upgrade;
|
||||
'' close;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
server_name dn.akqp.online;
|
||||
|
||||
# 入口直接打开真实 MVP 页面
|
||||
location = / {
|
||||
return 302 /live.html;
|
||||
}
|
||||
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:8765;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
|
||||
# WebSocket 升级(/ws 走这里)
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection $connection_upgrade;
|
||||
|
||||
# 长连接保活,避免 WS 被默认 60s 读超时切断
|
||||
proxy_read_timeout 3600s;
|
||||
proxy_send_timeout 3600s;
|
||||
}
|
||||
}
|
||||
90
deploy/setup.sh
Executable file
90
deploy/setup.sh
Executable file
@@ -0,0 +1,90 @@
|
||||
#!/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' 验证。"
|
||||
Reference in New Issue
Block a user