yeg
2026-09-29 61ba7945213c8c64e4ccaeb5675f1d24344d2f28
docs(server): 443 改为占位页,测试环境移回 8081

域名分工调整:www.dqrcfwpt.com 预留给生产环境,目前尚未部署,所以 443 只显示占位页(不再对外提供测试环境);测试环境回到 8081(完整功能,走共享 snippet)。80 仍 301 跳 https。

生产上线时的切换写在配置注释里:把 443 块里的 root 与 location 换成 snippet include 即可,80 的 301 不用动。另:/api 在这个域名上返回 503 JSON,避免请求落到静态页上被误解为可用。
1个文件已添加
1个文件已修改
74 ■■■■■ 已修改文件
.scratch/server-testenv/nginx-talent-card.conf 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.scratch/server-testenv/placeholder-index.html 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.scratch/server-testenv/nginx-talent-card.conf
@@ -1,24 +1,20 @@
# 东区人才卡 —— 站点(2026-09-22)
# 东区人才卡 —— 站点(2026-09-29)
#
# 部署位置:/etc/nginx/sites-available/talent-card  (再软链到 sites-enabled/)
# 部署位置:/etc/nginx/sites-available/talent-card  (软链到 sites-enabled/)
#
# 三个 server 块共用 snippets/talent-card-locations.conf,
# 所以「前端托管 + /api 反代 + /uploads 反代」只有一份定义,加端口不会漂移。
# 端口分工:
#   8081 → **测试环境**(完整功能,用 snippets/talent-card-locations.conf)
#   80   → 只做 301 跳到 https
#   443  → 这个域名留给**生产环境**,目前**尚未部署**,所以只显示占位页
#
# 8081:备案前的唯一入口,现在保留(堡垒机/内网调试也走它)。
#       ⚠️ 它仍然是**全公网可达的明文端口**,上面挂着后台 API;HTTPS 稳定后建议请云管理方关掉。
# 80  :只做 301 跳转到 https。
# 443 :正式入口。证书是华为云签发的 DV 证书(TrustAsia 签发,链:叶子 → TrustAsia DV TLS RSA CA 2025
#       → DigiCert Global Root G2),SAN 覆盖 `dqrcfwpt.com` 与 `www.dqrcfwpt.com`。
#       ssl_certificate 必须指向**含中间链的 bundle**,不能只给叶子证书。
# 生产上线时怎么切:把下面 443 那个 server 块里的 `root` 与两个 location 换成
# `root <生产的 dist 目录>;` + `include snippets/talent-card-locations.conf;`,
# 80 的 301 不用动。占位页在 /data/talent-card/placeholder/index.html。
#
# 证书到期:2027-02-11。**华为云的证书不会自动续到本机**,到期前要在华为云重新下载再传一次
# (或那时改用 Let's Encrypt —— 80 已通,certbot 一条命令且自带自动续期)。
#
# HSTS 目前是**第一步**:max-age=86400(1 天),且**没有** includeSubDomains / preload。
# 观察一段时间没问题后,再把 max-age 提到 31536000(1 年)。不加 includeSubDomains 的原因:
# 一旦哪天新增子域(例如 OSS 的 img.)还没配好 HTTPS,HSTS 会把那个子域也锁死;而 preload 是单向门,更难退出。
# 第一次成功续期之后再考虑这两项。
# 证书:华为云 DV(TrustAsia 签发),SAN 覆盖 `dqrcfwpt.com` 与 `www.dqrcfwpt.com`。
#       `/etc/nginx/ssl/talent-card/server.crt` **必须含中间链**(bundle,4451 字节)。
#       **2027-02-11 到期,且不会自动续到本机** —— 到期前重新下载再传一次。
# HSTS 仍是第一步:max-age=86400,无 includeSubDomains / preload。
server {
    listen 8081;
@@ -26,7 +22,6 @@
    include snippets/talent-card-locations.conf;
}
# 80:只做跳转,不再直接提供内容
server {
    listen 80;
    server_name www.dqrcfwpt.com dqrcfwpt.com;
@@ -40,7 +35,6 @@
    ssl_certificate         /etc/nginx/ssl/talent-card/server.crt;
    ssl_certificate_key     /etc/nginx/ssl/talent-card/server.key;
    # 同一份 bundle:叶子 + 中间链,供 OCSP stapling 校验用
    ssl_trusted_certificate /etc/nginx/ssl/talent-card/server.crt;
    ssl_protocols             TLSv1.2 TLSv1.3;
@@ -53,8 +47,16 @@
    ssl_stapling on;
    ssl_stapling_verify on;
    # HSTS 第一步:1 天,先观察
    add_header Strict-Transport-Security "max-age=86400" always;
    include snippets/talent-card-locations.conf;
    root /data/talent-card/placeholder;
    location / {
        try_files $uri /index.html;
    }
    # 这个域名上还没有后端。别让 /api 落到静态页上、让人以为接口可用。
    location /api/ {
        default_type application/json;
        return 503 '{"code":503,"message":"production not deployed"}';
    }
}
.scratch/server-testenv/placeholder-index.html
New file
@@ -0,0 +1,30 @@
<!doctype html>
<html lang="zh-CN">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>攀枝花市东区人才卡</title>
  <style>
    html, body { height: 100%; margin: 0; }
    body {
      display: flex; align-items: center; justify-content: center;
      background: #f5f6f8; color: #333;
      font: 16px/1.8 -apple-system, BlinkMacSystemFont, "Segoe UI", "Microsoft YaHei", sans-serif;
    }
    .box {
      max-width: 30rem; margin: 1rem; padding: 2.5rem 2rem;
      background: #fff; border-radius: 12px; text-align: center;
      box-shadow: 0 2px 12px rgba(0, 0, 0, .06);
    }
    h1 { margin: 0 0 .75rem; font-size: 1.2rem; font-weight: 600; }
    p { margin: .35rem 0; color: #666; font-size: .95rem; }
  </style>
</head>
<body>
  <div class="box">
    <h1>攀枝花市东区人才卡</h1>
    <p>本域名对应的生产环境尚未部署。</p>
    <p>如你是项目成员,请联系管理员获取测试环境地址。</p>
  </div>
</body>
</html>