← 教程列表

🖥️ 自托管 DSH Radar(30 分钟)

中级 · 30 分钟 · 2026-08-16

把 DSH Radar 部署到自己的服务器 / Cloudflare Pages / Vercel,完全掌控数据。 整站是 MIT 开源、零追踪的 Astro 静态站——没有后端、没有数据库、没有登录态, 产物就是 web/dist/ 里的一堆 HTML/JS/JSON,扔到任何能发静态文件的地方都能跑。 本教程涵盖 3 种托管方案 + 自建 Nginx,按推荐度排序。

先跑通本地构建

不管选哪种方案,前提都是这两步能跑通。抓数据脚本零依赖,只要 Node.js ≥ 18(内置 fetch):

git clone https://github.com/dsh-radar/dsh-radar.git
cd dsh-radar

# ① 抓 npm + GitHub 数据,算 5 维评分,写入 data/
node scripts/build-data.mjs
# 初次试跑建议限流:LIMIT=50 node scripts/build-data.mjs

# ② 构建静态站,产物在 web/dist/
cd web && npm install && npm run build

方案对比

方案 难度 费用 推荐场景
Cloudflare Pages⭐ 简单免费(不限带宽)99% 的人;国内访问最稳
GitHub Pages⭐ 简单免费(吃 Actions 配额)数据更新已经跑在 Actions 上,想一条龙
Vercel⭐⭐免费额度想要 preview deploy / CLI 一把梭
自建 Nginx⭐⭐⭐服务器费用内网 / 数据合规 / 接私有 registry

三个托管平台的本质差异只有一个:谁来跑 build-data.mjs。 在平台构建容器里直接抓数据会撞上 GitHub API 60 次/小时的匿名限流; 更稳的做法是让 GitHub Actions 定时抓数据并提交回仓库,托管平台只负责 npm run build。 GitHub Pages 天然适合前者,Cloudflare / Vercel 适合后者。

方案 1:Cloudflare Pages(推荐)

步骤 1:准备 fork

  1. Fork dsh-radar/dsh-radar
  2. 本地 clone:
    git clone https://github.com/YOU/dsh-radar.git
  3. 跑一次构建确保环境 OK:
    cd dsh-radar/web
    npm install --cache /tmp/npm-cache
    npm run build

步骤 2:连 Cloudflare Pages

  1. 登录 Cloudflare Dashboard
  2. Workers & Pages → Create application → Pages → Connect to Git
  3. 选你的 fork 仓库
  4. 配置:
    Build command:   cd web && npm install --cache /tmp/npm-cache && npm run build
    Build output:    web/dist
    Root directory:  /
  5. 环境变量(Settings → Environment variables):
    NODE_VERSION         = 22
    PUBLIC_WEB3FORMS_KEY = <your-key>
  6. Save and Deploy

步骤 3:自定义域名

  1. Pages → 你的项目 → Custom domains → Set up a custom domain
  2. 输入域名(如 radar.yourcompany.com
  3. Cloudflare 会给一个 CNAME,在你的 DNS 添加
  4. 等待 DNS 生效(5-30 分钟)

方案 2:Vercel(最简单)

# 1. 安装 vercel CLI
npm i -g vercel

# 2. 在项目根目录
cd dsh-radar
vercel login
vercel --prod

# 3. 跟着提示选 framework = Other
#    Root Directory = web
#    Build Command Override = npm run build
#    Output Directory Override = dist

# 或者跳过全部交互,一行搞定:
cd dsh-radar/web
vercel --prod --yes \
  --build-env NODE_VERSION=22 \
  --env PUBLIC_WEB3FORMS_KEY=<your-key>

Vercel 会把这些设置写进 .vercel/project.json,之后每次只要 vercel --prod 即可。

方案 3:自建 Nginx

构建产物

# 本地
cd dsh-radar/web
npm run build

# 上传
rsync -avz --delete dist/ user@server:/var/www/dsh-radar/

Nginx 配置

server {
    listen 443 ssl http2;
    server_name radar.yourcompany.com;

    ssl_certificate     /etc/letsencrypt/live/radar.yourcompany.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/radar.yourcompany.com/privkey.pem;

    root /var/www/dsh-radar;
    index index.html;

    # 启用 gzip
    gzip on;
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

    # 静态资源长缓存(文件名带 hash)
    location /_astro/ {
        expires 1y;
        add_header Cache-Control "public, immutable";
    }

    # 数据 JSON 短缓存:每周才更新一次,5 分钟足够
    location ~* \.json$ {
        expires 5m;
        add_header Cache-Control "public, must-revalidate";
    }

    # 关键:目录式路径 + SPA fallback
    # astro.config 用了 build.format: 'directory',页面产物是 /plugins/index.html,
    # 少了这行,直接刷新 /plugins/xxx 这类深链接会 404
    location / {
        try_files $uri $uri/ $uri.html /index.html;
    }

    # sitemap + robots 显式返回
    location = /sitemap.xml { add_header Cache-Control "public, max-age=3600"; }
    location = /robots.txt { add_header Cache-Control "public, max-age=86400"; }

    # 安全头
    add_header X-Content-Type-Options "nosniff";
    add_header X-Frame-Options "SAMEORIGIN";
    add_header Referrer-Policy "no-referrer-when-downgrade";
}

每周自动更新(cron)

# crontab -e
# 每周一 UTC 02:00 重新拉数据 + 重新 build + 重启 nginx
0 2 * * 1 cd /opt/dsh-radar && git pull && node scripts/build-data.mjs && (cd web && npm run build) && rsync -avz --delete web/dist/ /var/www/dsh-radar/ && nginx -s reload

环境变量配置

整站只有一个前端环境变量PUBLIC_WEB3FORMS_KEY, 供 /subscribe 页面的表单使用。 PUBLIC_ 是 Astro 的约定前缀——带这个前缀的变量会被编译进客户端产物, 所以它天生就是公开的,绝对不要往里塞任何私密凭据。

# web/.env(本地开发用,已在 .gitignore 里)
PUBLIC_WEB3FORMS_KEY=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

# 代码里这样读,没配置时优雅降级成空串(表单回退 mailto):
# const web3formsKey = import.meta.env.PUBLIC_WEB3FORMS_KEY || '';

抓数据阶段另有两个可选变量,它们只作用于 scripts/build-data.mjs,不会进前端产物: GITHUB_TOKEN(把 GitHub API 限流从 60 次/小时提到 5000 次/小时)与 LIMIT(只处理下载量前 N 个包,0 表示全量)。 DSH Radar 本身零追踪,不需要任何统计脚本的 key。

自定义域名 DNS 配置

三个平台都是同一套 CNAME 逻辑,区别只在目标值:

# 子域名(推荐,最省事)
类型     名称     值
CNAME    radar    your-project.pages.dev      # Cloudflare Pages
CNAME    radar    cname.vercel-dns.com        # Vercel
CNAME    radar    <用户名>.github.io           # GitHub Pages

# 根域名(apex 上 CNAME 不合法,用平台 flatten 或 A 记录)
Cloudflare : CNAME @ → your-project.pages.dev(自动 CNAME flattening)
Vercel     : A     @ → 76.76.21.21
GitHub     : A     @ → 185.199.108.153(官方 4 个 IP 全部添加)

加完记录一定要回平台后台把域名 Add / Verify 一遍,证书才会自动签发。 用 GitHub Pages 还要额外在 web/public/CNAME 里写上域名, 否则每次部署都会把自定义域名重置掉。DNS 生效一般 5-30 分钟。

部署后自检清单

常见问题

构建失败:Cannot find module 'astro'

没装依赖。跑 cd web && npm install

部署后页面是旧的

浏览器缓存。强制刷新(Ctrl+Shift+R / Cmd+Shift+R),或在 URL 加 ?v=2

怎么绑定自己的域名到 Cloudflare Pages?

Pages → Custom domains → 输入域名 → 按提示加 CNAME。也可以把整个域名 NS 迁到 Cloudflare(推荐,免费 DNSSEC)。

🚀 下一步

部署好后,配 GitHub Actions 每周自动更新