面向非网络专业读者的环境说明书:几个网址分别是什么、给谁用、改代码先上哪、为什么有时”看不到新版本”。 按隐私铁律,本文所有真实地址一律用占位符:{DOMAIN} 生产域名、{BETA_HOST} 内测域名、{HK_IP} 服务器 IP(香港)、{HOST_ROOT} 服务器部署父目录、{PROD_ROOT}/{BETA_ROOT} 两套部署根、{SSH_USER} 服务器用户。 真实值对照表只保存在本机 gitignored 的
local/ENV.md(机制原理见 ARCHITECTURE.md,部署/发布纪律见 DEVELOPMENT_FLOW.md,服务器细节见 DEPLOY.md,游戏 QA 见 GAMES.md)。
Qbao 有三层”环境”,改动一律从左到右流动:
本机写代码(L0) → 内测环境验收(L1) → 生产上线(L2) → 推送 GitHub
| 名词 | 是什么 | 类比 | 在本项目的角色 |
|---|---|---|---|
| 域名 | 人类可读的网址 | 门牌号 | {DOMAIN}(生产)、{BETA_HOST}(内测) |
| DNS | 把域名翻译成服务器 IP | 电话簿 | 由 Cloudflare 托管,指向香港服务器 |
| Cloudflare | 全球 CDN + DNS | 快递总站 | DNS 管理;{DOMAIN} 走代理(加速 + 边缘 HTTPS);{BETA_HOST} 仅 DNS 直连 |
| Caddy | 收下 HTTPS 请求,就地直出网页或转给业务程序 | 前台柜员 + 仓库管理员一肩挑 | 香港服务器 {HK_IP} 上的 Caddy:TLS 加密 + 静态直出 + API 反代,两个域名各一个 site 块 |
| Node API | 处理业务逻辑的程序 | 业务员 | 同一台机器上的 Express 服务(生产 :3000 / 内测 :3100) |
| PostgreSQL | 数据库 | 账本 | 生产库 qbao / 内测库 qbao_beta(同一个数据库软件里的两本账) |
| 缓存 | 浏览器/CDN 暂存文件以加速 | 复印留底 | 生产静态资源保留 7 天(改版靠 ?v= 刷新);内测不缓存 |
| WebSocket | 双向长连接 | 对讲机 | 狼人杀房间实时通信(:3011) |
| HTTPS | 加密的网页传输 | 密封信封 | 生产与内测都走 HTTPS,证书由 Caddy 自动申请续期 |
【生产 · 真实用户】
用户 ──https://{DOMAIN}──> Cloudflare(CDN/代理)──> 香港 {HK_IP}
Caddy(TLS 终结 + 静态直出 + 反代)
├── 静态 {PROD_ROOT}/app(7 天缓存)
├── /api ··· → Node :3000 → PostgreSQL 库 qbao
└── 狼人杀 ··· → Node :3011(房间在内存,不落库)
【内测 · 测试/内测人员】
内测者 ──https://{BETA_HOST}──>(DNS 直连,不过 CDN)香港 {HK_IP}
Caddy(另一个 site 块)
├── 静态 {BETA_ROOT}/app(不缓存)
└── /api ··· → Node :3100 → PostgreSQL 库 qbao_beta
关键点:生产与内测在同一台香港服务器上,靠 Caddy 的两个域名配置块分成两套「静态目录 + API + 账本」,两边互不碰面。
2026-09-10 起服务全部由香港单机提供:此前是「香港中转 + 大陆源站」两层(大陆机房会拦截未备案域名,才需要那套绕行方案), 源站已于同日退役清理。现在香港主机直接就是源站,链路更短,也不再需要任何「回源改写 / 路由暗号」机制。
| L0 本机开发 | L1 内测环境 | L2 生产 | |
|---|---|---|---|
| 入口 | http://127.0.0.1:8124/games/ 等本地地址 |
https://{BETA_HOST} | https://{DOMAIN} |
| 谁在用 | 开发时自己 | 你 + 受邀内测同学 | 全部真实用户 |
| 数据库 | 无(单测用假库) | qbao_beta(可随时删了重建) | qbao(不可测试) |
| API | 无(单测内嵌) | 香港 :3100 | 香港 :3000 |
| 静态目录 | 仓库 app/public/games / 构建产物 |
{BETA_ROOT}/app | {PROD_ROOT}/app |
| 缓存 | 无 | 不缓存(改完刷新即见) | 静态 7 天(改版需 ?v= 版本号) |
| 测试动作 | 只跑单测与页面 | 注册小号/对局/兑换/清库 全都可以 | 只读巡检(金丝雀账号) |
| 上线顺序 | ① | ②(默认验收点) | ③(验收通过后) |
?qa=1 调试钩子只在 {BETA_HOST} 与 localhost 生效,生产域名一律忽略(代码层强制,见 docs/GAMES.md 第六节)。以”调整弹珠兑换规则”为例:
1) 本机改代码 + 补/改单测 → DoD 全绿(L0)
2) 运行同步脚本:server 代码 → 内测目录;执行内测库迁移;重启内测 API(L1)
3) 内测自动冒烟:注册→登录→兑换→对局,断言写进 qbao_beta 且 qbao 零变化
4) 你在 https://{BETA_HOST} 上点一遍验收(或发给内测同学)
5) 验收通过 → 同样步骤执行到生产(同步、迁移、重启)→ 生产只读巡检
6) 你明确说"测试通过" → git push + tag + Release
任何一步失败就回到上一步修,生产上永远只有验收过的版本。
| 场景 | 路径 |
|---|---|
| 网页/手机浏览器 | 打开 https://{BETA_HOST},开放注册(内测网址只发给受邀者;页面带”内测环境”角标防混淆) |
| 微信里打开 | 直接分享内测网址(浏览器内核打开即可玩) |
| 当 App 用 | 手机浏览器「添加到主屏幕」,全屏体验 |
| 游戏自动化冒烟 | {BETA_HOST} 或 localhost 下游戏页加 ?qa=1&token=…(生产域名自动失效) |
| 桌面客户端 | 安装包走既有 beta 渠道 + 应用内「服务器地址」填 https://{BETA_HOST} |
| 手机壳 App 内测 | 下载页/下载中心「内测版(可选)」自选下载(com.qbao.beta 与正式版共存安装),构建与发布见 §7.1 |
| 内测出问题 | qbao_beta 一键重建(命令见 docs/DEPLOY.md 4B),不影响任何真实用户 |
| 数据迁移(双向) | 正式服与内测服之间用「本地备份」JSON 互导(目标环境注册登录同账号→上传恢复);管理员/封禁等账号属性不随备份迁移(见 §5.8-9) |
scripts/build-beta-apk.ps1(产物 .tmp/beta-apk/Qbao-Android-1.0.1-beta.N.apk)。壳工程支持环境变量覆盖与 gradle -PqbaoBeta 切换:应用标识 com.qbao.beta、应用名”Qbao 内测”、指向内测域名,与正式版同签名共存安装、数据互不干扰。publish-mobile.js add --channel beta(记录 channel=beta;stable 默认纪律不变)。Q1 生产为什么只有一个网址了?
2026-09-10 迁港后,生产统一走 https://{DOMAIN}(Cloudflare 代理)。此前的 http://{ORIGIN_IP} IP 直连兜底入口随大陆源站退役一并取消。
Q2 我改了代码,为什么网站上还是旧的? 三种可能:(1) 只改了本机,没同步到服务器;(2) 生产静态缓存 7 天——网页引用的 js/css 必须换版本参数 ?v= 才会让浏览器拉新版(或强刷 Ctrl+F5);(3) API 改动后没有重启对应服务。
Q3 为什么改数据库要”先内测后生产”? 迁移文件要在内测库先跑一遍验证无误(幂等、可重试),再去生产库执行;两边各自记账,互不干扰,任何一边失败都可单独重试。
Q4 内测环境会不会被真实用户访问到? 内测网址只有受邀者知道;且它连的是独立账本,即使被访问也只是多一个测试账号,不影响生产。真担心可加访问限制(预留开关)。
Q5 为什么跑测试要开 VPN? VPN 只用于两件事:访问 GitHub 推送代码、登录 Cloudflare 控制台改 DNS。日常打开内测/生产网址不需要 VPN。
Q6 游戏里的”QA 钩子”是什么? 游戏移植时内置的自动化测试入口(模拟登录、自动点按钮),用于冒烟;出于安全它只在 {BETA_HOST}/localhost 放行,生产域名下即使拼了参数也会被忽略。
Q7 内存这么小,跑两套服务会不会崩? 生产与内测 API 是同一台香港服务器上的两个 Node 进程(另有 Caddy、狼人杀与 PostgreSQL)。已预留降载开关(内测不开 AI 任务);若内存吃紧,最坏回退方案见 docs/DEPLOY.md 4B 的”预案”小节。
Q8 内测环境怎么知道当前是哪个版本?
内测页随每次同步即时更新,无缓存;页面顶部有”内测环境”角标。版本号以 server/package.json 与 CHANGELOG 为准。
Q9 服务器挂了怎么办?
服务与数据库同在一台机器,主机故障即整站不可用。数据侧靠服务器每日 04:00 自动双库备份(保留 30 天),另有迁港时点快照与源站退役归档保存在本机 gitignored 的 local/backups/。注意:大陆源站已退役,没有”切回源站”这条回滚路径。
| 术语 | 解释 |
|---|---|
| L0 / L1 / L2 | 三层环境:本机 / 内测 / 生产 |
| 源站 | 真正运行服务的服务器;本项目即那台香港主机(同时承担 TLS、静态托管与 API) |
| Caddy | 本项目的 Web 服务器:自动 HTTPS + 静态直出 + 反向代理,取代了早期的 nginx + 中转两层结构 |
| TTL | DNS 记录存活时间(改动域名记录后等待生效的时长) |
| 金丝雀账号 | 只读巡检用的专用账号(类比”矿工的金丝雀”先探路) |
| 幂等 | 同一操作执行多次结果一致(迁移脚本可安全重跑) |
| CAS | 读-改-写带版本比对,防并发覆盖 |
| singlefile | 前端构建产物:一个 index.html 内嵌全部 js/css |