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 一律写「远程服务器」。
7.2 KiB
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 |
| 证书 | 保留(不影响) |
五、遗留与注意事项
- CF SSL 模式建议人工确认为 Full (Strict):token 无 zone 设置权限,只能由用户在 Cloudflare 面板确认(当前实测回源走 443,已是 Full 级别;Strict 仅多一层源站证书校验,而我们的证书有效,可直接切换)。同时建议开启 Always Use HTTPS。
- 全员需重新登录:
COOKIE_DOMAIN由.dsh.alotbuy.com变为.alotbuy.com,旧 Cookie 失效。 - Cookie 覆盖面扩大:
.alotbuy.com意味着该 Cookie 会随请求发往alotbuy.com下所有子域(含gao/mao/work/www)。若日后希望收窄,需改为在<用户名>.alotbuy.com上设置 host-only Cookie(涉及代码改动)。 - 宝塔面板会重写 vhost:在面板里保存站点配置可能抹掉
proxy_buffering off/gzip_proxied any/real_ip等自定义指令 → 流式或真实 IP 异常时先回来检查。 - 未完成项(独立跟踪):档案 21 §三 的 A1 禁用 HMR、A2 catch-all 默认站点。
六、红线遵守
- 未触碰 R1(不升级 dsh)与 R2(不改官方 dsh 主程序);仅改 nginx 站点配置、编排器环境变量与 DNS/证书。
- 全程保留可回滚副本(env / vhost / renewal conf 各有
*.bak-*)。 - 未改动 alotbuy.com 的 MX/邮件/TXT 记录与
gao/mao/work等既有子域记录。