build / build-and-scan (push) Waiting to run
文档库:目录改为编号制(01-规范/02-架构设计/03-数据库/04-调整方案/
05-交接单/06-ops/07-scripts/08-skills/09-archive),顶层散文件归入 01-规范/;
INDEX.md 与 docs-manifest.json 重刷(档案 146 篇);旧目录名引用全量对齐。
IM 线:src/im/**(SDK / hub / store / presence / ws / gateway-token)、
src/web/routes/im.ts、src/db/plugin-data/**、src/supervisor/plugin-assembly.ts
及对应 test/**。
插件线:poc/{im-agent-bridge,im-connection-gateway,im-conversation-tabs,
business-plugins-im,carbon-mcp-probe}、src/web/routes/{sessions,overlay-device}.ts、
src/net/relay/{device-grant,instance-credential}.ts。
仓库卫生:清出 40 个历史误入库 / 已改名文件(34 个交接单归档 + 6 个旧结构,
本地均有副本);dsh-server-docs/.gitignore 补 tmp/;交接单不入库(政策)。
7.9 KiB
7.9 KiB
✅ 2026-09-19 07:3x 状态更新:本 RUNBOOK 已全部执行完,且「旧域彻底退役」那一步也一并做了。 原件原位于 47 的
/www/server/panel/vhost/nginx/_pending-ai1net/(该目录已于本日归档报废) ⇒ 本文件是该 RUNBOOK 的唯一在册副本。
- §1 阻塞项已解决:用户提供 ai1net.com 的 CF 令牌 ⇒ 落
/etc/cloudflare-ai1net.ini(600) ⇒certbot certonly --dns-cloudflare --dns-cloudflare-credentials /etc/cloudflare-ai1net.ini --dns-cloudflare-propagation-seconds 60 -d ai1net.com -d '*.ai1net.com' --cert-name ai1net.com签发成功(DNS-01)。- §2 的 S1–S5 全部执行(06:0x–07:3x):两份新 vhost 已启用;
/etc/dshs.env已切到ai1net.com/.ai1net.com;relay-direct.conf与dsh.alotbuy.com.conf已改指新域;106/etc/dshs-worker.env已补同份种子。- 🔴 §4 末尾那条「留待你确认退役时机」已被确认并落地(用户 2026-09-19 明令「旧域从项目中移除,后续全部使用 ai1net.com」):
alotbuy.com.conf由独立门户降级为 301 过渡装置;引导种子里的 2 条旧域项已撤。 ⇒ 完整判据 / 步骤 / 验收 / 回滚见04-调整方案/135-旧域alotbuy.com从项目移除.md。 ⚠️ 故本文件 §4 末条「本轮不做」的表述已被本次取代(⛔ §4 原文保留不改,仅在此更正)。- 回滚点:47
/root/_dompurge/(被替换的两份新配置、目录缓存备份、归档的_pending-ai1net-*); 生产侧/www/server/panel/vhost/nginx/alotbuy.com.conf.bak-dompurge-20260919-073004、/etc/systemd/system/dshs.service.d/overlay-443fb.conf.bak-dompurge-20260919-073101、 106/etc/dshs-worker.env.bak-dompurge-20260919-073149。
域名迁移 runbook —— alotbuy.com → ai1net.com(47 · 2026-09-19 建立)
本文件与同目录两个
*.conf一起放在 47 的/www/server/panel/vhost/nginx/_pending-ai1net/(待启用,nginx 只 include 该目录的*.conf一层,子目录天然不生效)。 目标:把线上部署的 DSH 服务域名由alotbuy.com切到ai1net.com(门户 + 实例子域 + 中继兜底入口 + 平台 env)。
0. 现状(2026-09-19 取证)
| 项 | 现状 |
|---|---|
| 门户 vhost | /www/server/panel/vhost/nginx/alotbuy.com.conf:alotbuy.com www.alotbuy.com *.alotbuy.com → 3080,/dshs-relay → 20080,证书 live/alotbuy.com(SAN alotbuy.com + *.alotbuy.com) |
| 实例子域 | <user>.alotbuy.com(一级标签,由门户 vhost 的 *.alotbuy.com 承载,无需第二张证书) |
| 旧名 301 | dsh.alotbuy.com.conf:dsh.alotbuy.com / *.dsh.alotbuy.com → 301 到 alotbuy.com / <label>.alotbuy.com,证书 live/dsh.alotbuy.com |
| 中继兜底 | relay-direct.conf:relay-direct.alotbuy.com(443),两端点 /dshs-relay + = /dshs-overlay/bootstrap(Host 改写成 alotbuy.com) |
| 平台 env | /etc/dshs.env:DSHS_BASE_DOMAIN=alotbuy.com、DSHS_COOKIE_DOMAIN=.alotbuy.com、DSHS_PORT=3080 |
| 中继引导种子 | lib/config.js 内置 ['https://alotbuy.com/dshs-relay'];env 覆盖键 = DSHS_OVERLAY_BOOTSTRAP_SEEDS(splitList,可多值) |
| 证书签发 | certbot 1.22.0 + dns-cloudflare 插件;凭据 /etc/cloudflare.ini(令牌仅覆盖 alotbuy.com 一个 zone) |
ai1net.com 侧已就绪的部分:DNS 已在 Cloudflare(ai1net.com / www / * / <x>.dsh 均解析到 CF)、CF→源站(47.77.182.89)链路已验证可达(用 80 端口探针文件经 CF 取回原文)、LE http-01 路径可用。
1. 🔴 唯一阻塞项(需用户侧提供)
*.ai1net.com 通配证书必须走 DNS-01(LE 对通配符只认 DNS-01),而 47 上现存的 CF 令牌只覆盖 alotbuy.com(实测 /zones 只返回 1 个 zone)⇒ 我无法为 ai1net.com 写 _acme-challenge TXT。
两条可选路径(任选其一):
- A. 给一份 ai1net.com 域的 CF API 令牌(权限最小化:
Zone → DNS → Edit,Zone Resources = 仅ai1net.com) → 落到/etc/cloudflare-ai1net.ini(dns_cloudflare_api_token = <令牌>,mode 600) → 我执行 S1:certbot certonly --dns-cloudflare --dns-cloudflare-credentials /etc/cloudflare-ai1net.ini --dns-cloudflare-propagation-seconds 60 -d ai1net.com -d '*.ai1net.com' --cert-name ai1net.com - B. 在 CF 面板生成 Origin CA 证书(主机名填
ai1net.com, *.ai1net.com),把 cert + key 文本给我 → 落到/etc/ssl/ai1net/{fullchain.pem,privkey.pem},ai1net.com.conf里两处证书路径改指它 → 无需给我任何 API 权限;代价是证书由 CF 侧管理、不参与 certbot 自动续期。
2. cutover 步骤(证书就绪后按序执行,每步带验收)
V=/www/server/panel/vhost/nginx
# S1 证书(见 §1;A 路径用 certbot,B 路径跳过)
certbot certificates | grep -A3 ai1net.com
# S2 启用两份 vhost(⛔ 证书不存在时**不要**做这步 ⇒ nginx 起不来 = 门户全挂)
cp -a $V/_pending-ai1net/ai1net.com.conf $V/ai1net.com.conf
cp -a $V/_pending-ai1net/relay-direct.ai1net.com.conf $V/relay-direct.ai1net.com.conf
nginx -t && nginx -s reload
# 验收:curl -s --http1.1 -o /dev/null -w '%{http_code}\n' https://ai1net.com/portal.html ⇒ 200
# S3 平台 env 切换(备份 → 改两项 → 追加种子(加性,保留 alotbuy 作第二种子)→ 重启)
cp -a /etc/dshs.env /etc/dshs.env.bak-dom-$(date +%Y%m%d-%H%M%S)
sed -i 's/^DSHS_BASE_DOMAIN=.*/DSHS_BASE_DOMAIN=ai1net.com/' /etc/dshs.env
sed -i 's/^DSHS_COOKIE_DOMAIN=.*/DSHS_COOKIE_DOMAIN=.ai1net.com/' /etc/dshs.env
grep -q '^DSHS_OVERLAY_BOOTSTRAP_SEEDS=' /etc/dshs.env || \
echo 'DSHS_OVERLAY_BOOTSTRAP_SEEDS=https://ai1net.com/dshs-relay,https://alotbuy.com/dshs-relay' >> /etc/dshs.env
systemctl restart dshs
# 验收:实例地址变成 <user>.ai1net.com 且能登录;中继仍在线(探针 29 PASS / 0 FAIL / 0 SKIP)
# S4 旧名连带项(**必须同批**,否则留半破状态)
# S4a relay-direct.conf(alotbuy 版)的 Host 改写也必须指向新基底域:
# proxy_set_header Host alotbuy.com; → ai1net.com
# S4b dsh.alotbuy.com.conf(旧名 301)的 map 目标改指新域(⚠️ 只改两行,别碰 server_name/正则):
# default alotbuy.com; → ai1net.com;
# ~^(?<label>[^.]+)\.dsh\.alotbuy\.com$ $label.alotbuy.com; → $label.ai1net.com;
nginx -t && nginx -s reload
# S5 worker 侧种子(可选,加性):/etc/dshs-worker.env 加同名多值 SEEDS,再 restart dshs-worker
# ⚠️ 改前 `--scene all` 演练含观察窗口,预算 ≥8 min;⛔ 别套短超时
3. 回滚(任一步失败都能退回)
- 删两份新 vhost ⇒
nginx -t && nginx -s reload(门户立即回到 alotbuy 版)。 cp -a /etc/dshs.env.bak-dom-<ts> /etc/dshs.env⇒systemctl restart dshs(回到alotbuy.com/.alotbuy.com)。- S4 的两处 sed 反向改回(alotbuy 版 vhost 与旧名 301 都可原样恢复)。
- 证书可留(不影响 alotbuy);
certbot delete --cert-name ai1net.com可彻底清掉。
4. 已知影响面(提前说明,非阻塞)
- 切换瞬间所有人需要在新域重登一次:cookie 域由
.alotbuy.com变.ai1net.com⇒ 旧 cookie 不再随请求发送(无法双域共存,一个 cookie 只能挂一个 Domain)。 - 实例地址由
<user>.alotbuy.com变为<user>.ai1net.com:旧地址在 alotbuy 版 vhost 仍可用(两套 vhost 并存期间);若要彻底退役旧域,再补一条alotbuy.com → ai1net.com的 301(本轮不做,留待你确认退役时机)。 work.alotbuy.com(Gitea · 154.40.35.3)与本次无关,不动。- 中继引导种子改成「新域为主、旧域为备」⇒ 两域任一存活都不影响 worker 入网。