Skip to content

Deployment

This site is a pure static site, and the build output can be deployed to any static hosting platform.

Build

bash
npm run docs:build:all

The output directory is docs/.vitepress/dist.

Note: npm run docs:build builds Simplified Chinese only by default (it will ask whether to build the multilingual versions); use npm run docs:build:all to publish the full multilingual site, and npm run docs:dev for daily development with live preview.

Option 1: GitHub Pages

  1. In the repository Settings → Pages, select the deployment branch and directory;
  2. Or use GitHub Actions for automated builds:
yaml
name: Deploy Docs

on:
  push:
    branches: [main]

permissions:
  contents: read
  pages: write
  id-token: write

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
      - run: npm ci
      - run: npm run docs:build:all
      - uses: actions/upload-pages-artifact@v3
        with:
          path: docs/.vitepress/dist

  deploy:
    needs: build
    runs-on: ubuntu-latest
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    steps:
      - id: deployment
        uses: actions/deploy-pages@v4

Option 2: Vercel / Netlify

Using Vercel as an example:

  1. Import the repository;
  2. Build command: npm run docs:build:all;
  3. Output directory: docs/.vitepress/dist;
  4. Click Deploy; it supports automatic deployment on every push and preview branches.

Option 3: Nginx

bash
# After uploading the build output to the server
scp -r docs/.vitepress/dist user@server:/var/www/docs

Example Nginx configuration:

nginx
server {
  listen 80;
  server_name docs.example.com;

  root /var/www/docs;
  index index.html;

  # Frontend routing fallback
  location / {
    try_files $uri $uri/ /index.html;
  }
}

Custom Domain and HTTPS

  • Bind a custom domain on the hosting platform;
  • Configure a CNAME record pointing to the platform;
  • The platform automatically issues and renews HTTPS certificates.

Option 4: Tencent Cloud COS + CDN

One of the most cost-effective low-latency solutions for access within mainland China; object storage + CDN acceleration, suitable for sites targeting mainland China users.

1. Preparation

  • Tencent Cloud account (new users can claim free tier, usually including 10GB of standard storage and some traffic, valid for several months);
  • An ICP-filed domain (to use mainland China CDN acceleration domains, ICP filing is mandatory, review takes about 1-3 weeks and is free).

ICP Filing Process in Detail (Tencent Cloud ICP Filing)

Prerequisites

  1. The domain must have completed real-name authentication (at the domain registrar, usually effective within 1-3 days);
  2. The Tencent Cloud account must have completed real-name authentication and own filing cloud resources such as a Tencent Cloud CVM or Lighthouse server (filing must be bound to cloud resources);
  3. Website content must comply with the "Measures for the Filing Administration of Non-Commercial Internet Information Services"; personal filing must not involve commercial content.
StepOperationRequired MaterialsEstimated Time
1. Verify domainLog in to the Tencent Cloud Filing Console, enter the domain, and the system automatically identifies the filing type (first-time filing/transfer filing, etc.)Filed domainInstant
2. Fill in informationFill in subject information (individual name/enterprise name, ID number) and service information (website name, domain, website owner, service content), upload ID photos and verification formFront and back of ID card, selfie photo (App face verification), website owner info, verification form (auto-generated)Depends on preparation
3. Tencent Cloud initial reviewTencent Cloud reviews the authenticity and completeness of the materials1-2 business days
4. SMS verificationMIIT sends a verification code; verify within 24 hours by logging in to the MIIT Filing SystemSMS verification code receivedWithin 24 hours
5. Regional bureau reviewThe local communications administration bureau does the final reviewUp to 20 business days
6. Filing completeReceive SMS/email notification with the filing numberPer notification

After filing is approved, two more things need to be done:

  1. Display the filing number at the bottom of the website, hyperlinking to the MIIT filing system https://beian.miit.gov.cn, e.g. 「粤ICP备2026000000号」;
  2. It is recommended to also apply for public security filing (within 30 days after filing approval); it is mandatory in some provinces.

Filing Tips

  • First-time individual filing usually completes in 1-2 weeks, depending on the efficiency of the regional bureau;
  • During filing, you can deploy on the COS default domain or an overseas node to go live, then switch to the custom domain after filing is approved;
  • Filing is a free service; be wary of paid agencies (agencies only provide guidance on preparing materials).

2. Create a Bucket

  1. In the console, go to Object Storage COS and create a bucket;
  2. Choose a nearby region (e.g. Guangzhou ap-guangzhou);
  3. Set access permission to Public Read / Private Write;
  4. Enable the "Static Website" feature, set the index document to index.html and the error document to 404.html.

3. Upload the Build Output

After building, upload the docs/.vitepress/dist directory:

bash
npm run docs:build:all

# 方式一:控制台上传(对象 → 上传文件夹,选 dist 下所有文件)
# 方式二:使用 COSCLI 命令行工具
pip install coscmd
coscmd config -a <SecretId> -s <SecretKey> -b <bucket-name>-<appid> -r ap-guangzhou
coscmd upload -rs ./docs/.vitepress/dist/ /
coscmd list -r /

4. Enable CDN Acceleration

  1. In the console, go to Content Delivery Network CDN and add an acceleration domain;
  2. Select Mainland China as the acceleration region (choose Hong Kong/overseas if not filed; speed is average);
  3. Select Object Storage COS as the origin type and choose the bucket just created;
  4. Choose CNAME for domain connection and follow the prompts to add a CNAME record at your DNS provider;
  5. Wait for the CNAME to take effect (about 10 minutes), then enable "Follow origin 301/302" and "Range back-to-origin".

5. Configure HTTPS

5.1 Apply for a Free Certificate

  1. In the console, go to SSL Certificates and select "Apply for Free Certificate";
  2. Select certificate type DV (domain validation) and bind the acceleration domain;
  3. Choose automatic DNS validation (one-click when the domain is on Tencent Cloud / DNS already hosted), then wait for issuance (minutes to hours).

5.2 Enable on CDN

  1. In CDN "Domain Management → HTTPS Configuration", select the issued certificate;
  2. Enable "HTTP forced redirect to HTTPS" (recommended; choose status code 301);
  3. After enabling, you can use "Purge & Prefetch" to prefetch the homepage URL before first access to speed up first visits.

Billing Notes

  • DV certificates are free with no renewal cost (the system reminds you before expiry; you can re-apply);
  • Note: CDN HTTPS request count is a value-added service, billed at 0.04 CNY per 10,000 requests — a docs site has low request volume (hundreds of thousands per month), costing a few yuan, negligible; if you want to completely avoid this cost, you can disable the HTTPS billing item under "Value-added Services" (not recommended, as you would lose encryption).

5.3 Verify the Deployment

bash
curl -I https://docs.example.com
# 期望返回:HTTP/2 200
# 响应头包含:strict-transport-security 等安全头(可后续在 CDN 响应头配置中自定义)

5.4 CNAME Configuration Notes

When connecting to CDN, the acceleration domain is assigned a CNAME record ending in .cdn.dnsv1.com, which you need to add at your DNS provider:

Record TypeHost RecordRecord ValueTTL
CNAMEdocsdocs.example.com.cdn.dnsv1.com600
  • Effective time is usually 10 minutes to 1 hour (depends on TTL);
  • Misconfiguration (e.g. mistakenly using an A record) will cause the domain to fail to resolve to the CDN and errors on access;
  • Verification: nslookup docs.example.com; success is indicated when the CNAME target is returned.

6. Cache Configuration

For static documentation sites, it is recommended to set long cache durations for resources (CDN hit rate can reach 99%+, with almost no back-to-origin traffic). Configure in the CDN console under "Domain Management → Cache Configuration".

PriorityMatch TypeContentCache TimeDescription
1File extension.html10 minutesTake effect as soon as possible after content updates
2File extension.js .css30 daysVitePress build output is hashed, safe for long caching
3File extension.png .jpg .svg .webp .ico30 daysStatic image assets
4File extension.woff .woff2 .ttf30 daysFont files
5All files*30 daysFallback rule

6.2 Cache Hits and Hit Rate

  • After a cache hit, the CDN directly returns edge node content, generating no back-to-origin traffic (saving the 0.15 CNY/GB back-to-origin fee);
  • The hit rate can be viewed in the console under "Statistics → Hit Rate"; docs sites usually stay above 99%;
  • If the hit rate is low, check whether "Ignore query string" is enabled: when enabled, page.html?ref=a and page.html?ref=b hit the same cache.

6.3 Cache Purge and Prefetch

  • Purge: run after content updates to clear edge node cache (URL purge takes effect in real time; directory purge takes about 5 minutes);
  • Prefetch: cache resources to edge nodes in advance, for launching new versions or promotions, so first visits no longer hit the origin;
  • Console path: "Purge & Prefetch" → enter URL/directory → submit;
  • Automation: in the publish script, call the CDN purge API (DescribeCdnHosts / purge URL API) after coscmd upload, or trigger via COS event notifications.

6.4 Browser Cache (Second-Level Cache)

Besides CDN edge caching, the browser itself also caches resources. You can add the following in COS or CDN "HTTP Response Header Configuration" for static assets:

http
Cache-Control: public, max-age=2592000   # 30 天,用于带 hash 的静态资源
Cache-Control: no-cache                   # HTML 每次回源验证(配合 10 分钟节点缓存)

6.5 Status Code Caching

Status CodeRecommended Cache TimeDescription
200Follow cache rulesNormal response
40410 secondsAvoid permanently caching error pages, which would keep returning 404 after the fix
403/500/5020Server errors are not cached, allowing quick recovery

7. Publish Script Automation (Upload + Auto-Purge)

This project includes a one-click publish script scripts/deploy.mjs that completes the full pipeline of "build → incremental upload → auto-purge CDN cache".

7.1 Environment Preparation

  1. Install dependencies: npm i -D cos-nodejs-sdk-v5 tencentcloud-sdk-nodejs-cdn;
  2. Create an API key in Access Management CAM;
  3. Copy .env.example to .env and fill it in:
bash
TENCENTCLOUD_SECRET_ID=your-secret-id
TENCENTCLOUD_SECRET_KEY=your-secret-key
COS_BUCKET=your-bucket-1250000000    # 含 appid 后缀
COS_REGION=ap-guangzhou              # 与存储桶地域一致
CDN_DOMAIN=docs.example.com          # 加速域名,设置后自动刷新 CDN

7.2 Usage

bash
npm run deploy                  # 正式发布:构建 + 备份 + 上传 + 刷新 CDN
npm run deploy -- --dry-run     # 演练:只输出执行计划,不实际变更
npm run deploy -- --refresh-all # 改为整站目录刷新(默认只刷新 .html)
npm run deploy -- --skip-build  # 跳过构建,直接上传现有产物
npm run deploy -- --no-backup   # 跳过发布前版本备份

7.3 Script Execution Flow

StepOperationDescription
1npm run docs:build:allBuild the static site
2Collect local filesCompute the MD5 of every file
3List remote objectsPaginate through existing COS files (MD5 stored in custom headers)
4Compute diffsSkip files with identical MD5; auto-clean remote files deleted locally
5Backup current versionSnapshot the live content to __backup/<timestamp>/ before publishing (COS same-bucket copy, zero traffic), keeping the latest 10 versions
6Incremental uploadUpload only changed files; HTML gets Cache-Control: no-cache, static assets get 30 days
7Purge CDNBy default, precisely purge all .html URLs (enough quota); --refresh-all switches to whole-site directory purge

Why only purge HTML? Static asset file names carry hashes, so when content changes the file name changes too; no purge needed. HTML is cached for 10 minutes and takes effect immediately after purge. This way each release only needs 10 purge quota entries.

7.4 CI/CD Integration (GitHub Actions Example)

yaml
name: Deploy Docs

on:
  push:
    branches: [main]
    paths: ['docs/**', 'package.json']

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
      - run: npm ci
      - run: npm run docs:build:all
      - name: 发布到 COS + 刷新 CDN
        run: node scripts/deploy.mjs --skip-build
        env:
          TENCENTCLOUD_SECRET_ID: ${{ secrets.TENCENTCLOUD_SECRET_ID }}
          TENCENTCLOUD_SECRET_KEY: ${{ secrets.TENCENTCLOUD_SECRET_KEY }}
          COS_BUCKET: ${{ secrets.COS_BUCKET }}
          COS_REGION: ap-guangzhou
          CDN_DOMAIN: ${{ secrets.CDN_DOMAIN }}

After configuring the above secrets in the repository Settings → Secrets, every push with docs/ changes will publish automatically.

7.5 Version Backup and Rollback

Before publishing, the script automatically snapshots the current live content to the __backup/<timestamp>/ prefix (COS same-bucket copy, no traffic charges), keeping the latest 10 versions, so you can roll back anytime if a release goes wrong.

bash
npm run rollback                            # 列出所有备份版本(时间 + 文件数)
npm run rollback -- --to 20260831103000     # 回滚到指定版本
npm run rollback -- --to 20260831103000 --prune    # 回滚并删除该版本之外的多余文件
npm run rollback -- --to 20260831103000 --dry-run  # 演练,只输出执行计划
npm run rollback -- --to 20260831103000 --refresh-all  # 回滚后整站刷新(默认只刷 .html)

Rollback principle: copy the backup objects back to the site root (preserving the original cache headers); --prune deletes files that are extra in the current live site, then the CDN cache is purged automatically and the site is restored immediately.

Security Design

  • Backup is completed before upload; if the backup fails, it is treated as a release risk — resolve it first before continuing;
  • Rollback only restores files in the backup and does not touch other backup versions (they don't affect each other);
  • --dry-run is fully offline; you can rehearse with fake keys.

7.6 Auto-Generated Changelog

A built-in scripts/changelog.mjs supports two modes (auto-detects git repositories):

bash
npm run changelog                  # 打印最近 30 天更新日志
npm run changelog -- --days 7      # 只看最近 7 天
npm run changelog -- --write       # 写入 CHANGELOG.md
npm run changelog -- --from <ref>  # git 模式:从指定 ref(tag/hash/HEAD~10)开始
npm run changelog -- --files       # 强制文件模式(无需 git)
  • git mode (recommended): based on git log, auto-categorized by Conventional Commit (feat→Added, fix→Fixed, docs→Docs, perf→Performance, etc.);
  • file mode (automatic fallback): when there is no git repository, scans the modification time and titles of Markdown files under docs/ and groups them by date.

It is recommended to pair with the publish flow: first run npm run changelog -- --write to update the log, then npm run deploy to publish.

7.7 Lightweight Alternative: coscli + tccli (No Coding Required)

If you prefer not to introduce the Node SDK, you can also use Tencent Cloud's official command-line tools:

bash
# 1. 安装 coscli(增量同步 + 删除多余文件)
curl -L https://github.com/tencentyun/coscli/releases/latest/download/coscli-darwin-amd64 -o /usr/local/bin/coscli
chmod +x /usr/local/bin/coscli
coscli config  # 按提示填写密钥

npm run docs:build:all
coscli sync ./docs/.vitepress/dist/ cos://your-bucket/ -r --delete --include ".*"

# 2. 安装 tccli 并刷新 CDN(腾讯云官方 CLI)
pip install tccli
tccli configure  # 配置密钥
tccli cdn PurgeUrlsCache --Urls '["https://docs.example.com/index.html"]' --Area mainland

Cost Estimate

Using a typical docs site (site 100MB, 10,000 monthly visits, about 2GB CDN traffic) as an example:

Billing ItemUnit PriceEstimated Monthly Cost
COS standard storage0.118 CNY/GB/monthabout 0.01 CNY (covered by new-user free tier)
COS request fee0.01 CNY per 10,000 requestsabout 0.01 CNY
CDN traffic (0-2TB tier)0.21 CNY/GBabout 0.42 CNY
CDN back-to-origin traffic0.15 CNY/GBabout 0 CNY (99%+ cache hit rate)
HTTPS certificateFree0 CNY
Totalabout 0.5 CNY/month

Cost Tips

  • The more traffic, the lower the CDN unit price: 2-10TB tier is 0.20 CNY/GB, 10-50TB tier is 0.18 CNY/GB;
  • You can buy CDN traffic packages for further discounts (promotions are common);
  • The only extra cost is the domain (common suffixes are about 20-60 CNY/year; first-year 1 CNY deals are common for new users); filing itself is free;
  • If you haven't filed, you can still use the COS default access domain, but you cannot use a custom domain and public outbound traffic is billed at 0.5 CNY/GB, so filing + CDN is recommended.

Note

For mainland China environments, besides Tencent Cloud COS + CDN, you can also use Alibaba Cloud OSS + CDN, Qiniu, Upyun and other object storage services to host static sites; costs and operations are similar.

Built with VitePress · Knowledge shared openly