Files
dsh_shenxian/dsh-server-docs/04-调整方案/22-服务域名迁移到alotbuy.com.md
T
admin 5ad755116e chore(docs): 文档库并入代码仓(R4 选 a)+ 索引/台账跟进
1) dsh-server-docs/ 从工作区(原 E:\...\aliyun-dsh-server\dsh-server-docs)**整体并入本仓**,
   保留目录名 ⇒ 仓库内 dsh-server-docs/... 的相对引用天然继续有效;旧目录(含其 .git)已归档到
   工作区 _中间产物_待清理/,未随本提交带入。
2) .gitattributes:新增 `dsh-server-docs/** -text` —— 原文档库是 `* -text` + autocrlf=false,
   必须保持纯 LF,否则会被本仓的 CRLF 规则翻掉。
3) 活引用里的绝对路径已全部改到新位置(docs 的 INDEX / README / scripts / skills + 用户级 skills
   + ~/.workbuddy/settings.json 的 hooks);历史档案(04-调整方案/、archive/)按「只增不改」未动。
   ⚠️ hooks 路径改动需「完全重启会话」才生效(配置是会话启动快照)。
4) 交接单/T08:新增 §16「生产整体切换执行记录」(形态 / 落地动作 / **4 个只有真上线才暴露的真 bug** /
   验收证据 / 回滚命令 / 残留项);台账 T08 行 → 已完成并归档;03-路线图 §二 登记 T08 收尾项。
5) 统一称谓:**「本机」只指跑 WorkBuddy 的开发机**,47 / 106 一律写「远程服务器」。
2026-09-15 18:47:13 +08:00

7.2 KiB
Raw Blame History

22 · 服务域名迁移:dsh.alotbuy.com → alotbuy.com

  • 日期:2026-09-10
  • 触发:用户裁定「服务域名改为 alotbuy.com」,并在两条路径中选定 路径 ②:走 Cloudflare 代理(橙云,零 DNS 改动)
  • 结论一句话:已完成迁移 —— 门户 = https://alotbuy.com,用户实例 = https://<用户名>.alotbuy.com;旧域名 dsh.alotbuy.com 全部 301 到新域名(含用户名映射);证书 alotbuy.com + *.alotbuy.com 已签发且续期演练参数已加固。
  • 状态:已上线;遗留:CF SSL 模式建议人工确认 Full (Strict)、全员需重新登录

TL;DR|结论:域名迁移完成:门户 alotbuy.com、用户实例 <用户名>.alotbuy.com;旧域 dsh.alotbuy.com 全部 301(含用户名映射)。 关键:走 Cloudflare 代理(橙云、零 DNS 改动);签 alotbuy.com + *.alotbuy.com 通配证书(DNS-01 传播必须 60 s)+ CF 真实 IP 还原。 状态:✅ 已上线(含回滚步骤)


一、决策与前置侦察(实测)

项 结果
alotbuy.com A 记录 已指向本机 47.77.182.89,经 Cloudflare 代理(橙云)
alotbuy.com 当时内容 nginx 404(空站) → 根域未被占用,接管无冲突 ✅
*.alotbuy.com 通配记录已存在(橙云)→ 用户子域天然可解析 ✅
同域其它记录 gao/mao→154.40.35.3、www→apex、work→apex、alimail/smtp→mxhichina、MX/TXT(SPF) → 迁移不触碰这些
CF token 权限 仅 DNS(Zone:DNS:Edit):能改记录、能签 DNS-01 证书;不能读写 zone 设置(SSL 模式需人工确认)
CF 回源端口(实测 ss) 全部 443,无 80 连接 → CF 处于 Full(或 Strict)模式,CF→源站已加密,无明文风险 ✅
备案 alotbuy.com 已在阿里云备案(否则子域无法访问)✅

二、执行步骤(含踩坑)

1. 签发通配证书(DNS-01)

certbot certonly --dns-cloudflare --dns-cloudflare-credentials /etc/cloudflare.ini \
  --dns-cloudflare-propagation-seconds 60 --non-interactive --agree-tos \
  --cert-name alotbuy.com -d alotbuy.com -d '*.alotbuy.com'

产物:/etc/letsencrypt/live/alotbuy.com/{fullchain,privkey}.pem(有效期至 2026-12-09,已配置自动续期)。

⚠️ 踩坑 1(重要):首次签发失败(No TXT record found at _acme-challenge.alotbuy.com)。certbot 日志显示 TXT 记录创建成功,只是默认只等 10 秒传播(CF 上实测 ~10 s 才可见,正好卡边界)。写临时 TXT 探测证实记录可被 Google/CF 解析到(无通配 CNAME 劫持),把传播等待改为 60 s 后即成功。 ⚠️ 踩坑 2(续期):certbot 只把该参数写进新证书的 renewal conf;旧证书(dsh.alotbuy.com)仍是默认 10 s → 会在 ~60 天后续期失败。已给两个 renewal conf 都补上 dns_cloudflare_propagation_seconds = 60。

2. nginx vhost(新域名)

  • 新增 /www/server/panel/vhost/nginx/alotbuy.com.conf:server_name alotbuy.com www.alotbuy.com *.alotbuy.com,80 段代理(不 301,兼容 CF 任一模式),443 段用新证书;
  • 继承 dsh 站点的三项优化:proxy_buffering off(流式)、gzip_proxied any(930 KB bundle 压缩)、/assets/ 长缓存;
  • CF 真实 IP 还原:set_real_ip_from <CF 全部回源段> + real_ip_header CF-Connecting-IP(写在 server 块内,避免全局生效;否则日志/风控里全是 CF 机房 IP)。

    踩坑 3:set_real_ip_from 写在 vhost 文件顶层会落到 http 上下文作用于全局,务必放进 server 块。

3. 切换域名配置(drain + 重启)

脚本:/opt/dsh/switch-domain-alotbuy.sh(幂等、带备份、drain 用按 pid 结束而非 pkill -f——后者会杀掉自身 ssh 会话,档案 20 已踩过)

env: DSHS_BASE_DOMAIN=alotbuy.com
     DSHS_COOKIE_DOMAIN=.alotbuy.com      (备份 /etc/dshs.env.bak-20260910-2332)
停服务 → 结束残留 dsh 子进程/scope → 起服务(残留实例数 = 0)

4. 旧域名 301(保留用户名映射)

dsh.alotbuy.com.conf 改为纯跳转,使用 map + 通配 server_name(正则 server_name 实测不匹配,踩坑 4):

map $host $alotbuy_new_host {
    default                               alotbuy.com;
    ~^(?<label>[^.]+)\.dsh\.alotbuy\.com$ $label.alotbuy.com;
}
server { listen 80;  server_name dsh.alotbuy.com *.dsh.alotbuy.com; return 301 https://$alotbuy_new_host$request_uri; }
server { listen 443 ssl; server_name dsh.alotbuy.com *.dsh.alotbuy.com; ssl_certificate …dsh.alotbuy.com…; return 301 https://$alotbuy_new_host$request_uri; }

三、验证结果

检查 结果
门户(经 CF) https://alotbuy.com/login.html → 200
用户子域(经 CF,未登录) https://admin.alotbuy.com/ → 401(正常:需登录)✅ 说明编排器已把该 Host 识别为用户子域
旧域名跳转 dsh.alotbuy.com/... → 301 → https://alotbuy.com/...;admin.dsh.alotbuy.com → 301 → https://admin.alotbuy.com/;x.dsh.* → x.alotbuy.com(通用映射)
源站证书校验 ssl_verify_result=0(链有效,CF Full (Strict) 亦可通过)
服务状态 active/enabled,编排器正常,残留实例 0(用户重新进入时按需拉起)
自动续期 两个证书 renewal conf 均含 dns_cloudflare_propagation_seconds = 60

四、回滚

项 回滚
域名配置 cp /etc/dshs.env.bak-20260910-2332 /etc/dshs.env → 跑 drain(停服务→清实例→起服务)
nginx cp /www/server/panel/vhost/nginx/{dsh.alotbuy.com.conf.bak-*-pre-redirect,alotbuy.com.conf} 还原/删除 → nginx -t && nginx -s reload
证书 保留(不影响)

五、遗留与注意事项

  1. CF SSL 模式建议人工确认为 Full (Strict):token 无 zone 设置权限,只能由用户在 Cloudflare 面板确认(当前实测回源走 443,已是 Full 级别;Strict 仅多一层源站证书校验,而我们的证书有效,可直接切换)。同时建议开启 Always Use HTTPS。
  2. 全员需重新登录:COOKIE_DOMAIN 由 .dsh.alotbuy.com 变为 .alotbuy.com,旧 Cookie 失效。
  3. Cookie 覆盖面扩大:.alotbuy.com 意味着该 Cookie 会随请求发往 alotbuy.com 下所有子域(含 gao/mao/work/www)。若日后希望收窄,需改为在 <用户名>.alotbuy.com 上设置 host-only Cookie(涉及代码改动)。
  4. 宝塔面板会重写 vhost:在面板里保存站点配置可能抹掉 proxy_buffering off / gzip_proxied any / real_ip 等自定义指令 → 流式或真实 IP 异常时先回来检查。
  5. 未完成项(独立跟踪):档案 21 §三 的 A1 禁用 HMR、A2 catch-all 默认站点。

六、红线遵守

  • 未触碰 R1(不升级 dsh)与 R2(不改官方 dsh 主程序);仅改 nginx 站点配置、编排器环境变量与 DNS/证书。
  • 全程保留可回滚副本(env / vhost / renewal conf 各有 *.bak-*)。
  • 未改动 alotbuy.com 的 MX/邮件/TXT 记录与 gao/mao/work 等既有子域记录。