---
title: 'Next.js Docker 化部署到 VPS 全流程:Caddy 反代、Cloudflare 与自定义域名'
video_id: WgezEq7_lWo
url: https://youtu.be/WgezEq7_lWo
title_en: "Dockerize Next.js & Deploy To VPS (SSL / HTTPS, CDN Cloudflare, Caddy, Custom Domain, Hostinger)"
channel: ByteGrad
published: 2026-06-12
duration: "29:50"
topics: [建站与技术栈]
noted: 2026-07-08
value: A
views: '3509'
---


[![封面](https://i.ytimg.com/vi/WgezEq7_lWo/maxresdefault.jpg)](https://youtu.be/WgezEq7_lWo)

> ByteGrad · 29:50 · 发布 2026-06-12 · 3509次观看(截至抓取) · [观看原视频](https://youtu.be/WgezEq7_lWo)

## 主旨

视频演示把一个 Next.js 应用从零容器化并部署到 Hostinger VPS 的完整链路:Next.js standalone 输出 → 写或复用 Dockerfile → 本地烟测 → 多架构镜像推送到 GHCR → 在 VPS 上拉取并以 Docker 容器运行 → 用 Caddy 做反向代理接管 HTTPS → 自定义域名解析 → Cloudflare CDN 接管静态资源。

## 核心论点

1. **使用 Next.js 的 `output: "standalone"` 是 Docker 化的关键前置**:它让构建产物自带一个最小化 Node.js server.js,服务器侧特性(路由处理器/server actions/中间件)都可以继续跑。([[#1-intro-与-nextjs-的-output-standalone-0000|→ 详解1]])
2. **AGENTS.md 适合写 agent 看不见的部署上下文**(Docker/Caddy/CDN 这一类不在项目文件里的运维决定),让编码 agent 不会被错误信息误导去改源码。([[#2-agentsmd-写部署上下文-0352|→ 详解2]])
3. **Dockerfile 既可以让 AI 起草,也可以直接复用官方模板,后者版本更新更及时**:Next.js docs 里 docker-standalone-output 模板自带 Node 长期支持版本、多阶段构建、缓存复用,适合先照搬。([[#3-dockerfile-生成ai-起草-vs-nextjs-官方模板-0458|→ 详解3]])
4. **跨平台构建必须显式指定 `--platform`**:本机与 VPS 架构常常不同(本片里本机是 MacBook,VPS 通常是 Linux),不指定平台镜像会被 VPS 直接拒绝。([[#4-docker-构建本地烟测与目标平台-0751|→ 详解4]])
5. **GHCR(ghcr.io)是 Docker 镜像的零成本托管**:用 GitHub Personal Access Token 登录后即可 `docker push`。([[#5-推镜像到-github-container-registry-ghcrio-1038|→ 详解5]])
6. **VPS 上跑容器时务必加 `--restart unless-stopped`**:VPS 自身可能重启或更新,容器不挂这个标志会一直处于停机状态。([[#6-vps-初始化ssh-与拉取运行镜像-1213|→ 详解6]])
7. **Caddy 是"开箱即 HTTPS"的反向代理**:只要给它一个域名,自动申请并续签 SSL 证书并 80→443 重定向,不需要额外配置证书或手动续签。([[#7-caddy-反向代理--自定义域名--https-1951|→ 详解7]])
8. **Cloudflare 免费档即可提供全球 CDN + 缓存命中可视化**:只要把域名的 name server 切到 Cloudflare,JS/CSS 等静态资源自动走边缘节点,响应头里能看到 `cf-cache-status: HIT/MISS`。([[#8-cloudflare-cdn-接入-2553|→ 详解8]])

## 知识点详解

### 1. Intro 与 Next.js 的 `output: standalone` [00:00](https://youtu.be/WgezEq7_lWo?t=0)

视频开头明确说"很久没讲 Docker 化 Next.js 并部署到 VPS 的主题了,而这一次可以比以前的视频做得更简单"。Next.js 部署文档列出了 Node.js 服务器与 Docker 容器两种主路径,两种都支持 server actions、route handlers、proxy、middleware 这类服务器侧特性;另有一种 static export 路径会让产物只剩纯 HTML,丢掉所有服务器侧能力。

Next.js 提供两类 Docker 模板:docker-standalone-output 与多环境模板。本片选 standalone 路线,因为它构建完会直接产出 `server.js` 这个最小化 Node 服务器,运行时只需 `node server.js`。具体前置动作是在 `next.config.js` 里写 `output: "standalone"`,这样 `npm run build` 之后 `.next/standalone/` 下就会带可独立运行的 server.js。这是把 Next.js 应用从托管平台挪到自有 VPS 的最干净入口。

`output: standalone` 与 `output: export` 的关键差别是:前者保留 Node 服务器与所有运行时特性,后者只生成静态 HTML。视频明确说"如果用了 static export,server actions/route handlers 这类都用不了",所以选了 standalone。

### 2. AGENTS.md 写部署上下文 [03:52](https://youtu.be/WgezEq7_lWo?t=232)

Wesley 提示:**AI 编码 agent 只看得见项目目录里的文件,看不见外部部署上下文**。Docker 用什么、镜像推到哪、反代用什么、CDN 在不在前面——这些信息不在源码里,agent 默认不知道。如果你想让 agent 帮你维护或扩展 Dockerfile/Caddyfile 等运维文件,把这些决定写进 AGENTS.md。

具体写法是写下"这里用 Docker 部署、镜像推到 GHCR、用 Caddy 做反代、Cloudflare CDN 在前面"这类句子,再补一句"不要做"清单(例如不要改某固定配置的容器)。如果暂时不需要 agent 介入,这个文件可以删掉;本片为了演示默认 Dockerfile 的版本,就把 AGENTS.md 移除了。

这条经验把 AGENTS.md 从 Claude Code 专有配置文件提升为"任何 agent 都需要看到的运行时/运维上下文"的载体——它原本被作为"每次会话开头自动注入"的系统级规范,这里把它推广到部署运维上下文。

### 3. Dockerfile 生成:AI 起草 vs Next.js 官方模板 [04:58](https://youtu.be/WgezEq7_lWo?t=298)

生成 Dockerfile 有两条路。**第一条是让 AI 编码 agent 起草**——好处是它会自动读 AGENTS.md 并指向 Next.js 文档,知道 standalone 输出需要把 `.next/static` 与 `public/` 手动复制到镜像里。一两分钟就能出一份多阶段 Dockerfile 与 `.dockerignore`,后者会顺手忽略 `.env`(避免把密钥烤进镜像)等敏感文件。

但 AI 起草容易把 node 版本钉死,例如旧版本镜像;**第二条路是直接复用 Next.js 官方 docker-standalone-output 模板的 Dockerfile**。视频里 Wesley 比对后说官方模板用的是更新版本的 Node 长期支持版本,这点比 AI 起草更跟得上节奏。模板还会处理多阶段构建(先在带 dev deps 的镜像里装依赖、跑 build,再切到最小运行时镜像只留产物体积)、cache mount 加速后续构建,以及自动按 `package-lock.json`/`yarn.lock`/`pnpm-lock.yaml` 判定包管理器。

实操上视频推荐:**先照搬官方模板,等跑通后再让 agent 优化**。这也呼应了 Skill 反推创建法 的精神——手动跑通一遍再让 AI 总结规律,而不是让 AI 直接给出"应该长这样"的 Dockerfile。

### 4. Docker 构建:本地烟测与目标平台 [07:51](https://youtu.be/WgezEq7_lWo?t=471)

**先在本地 `docker build` + `docker run` 跑一遍确认能用**,再考虑推到生产。这是视频明确强调的顺序:Mac 上用 Docker Desktop 构建并运行容器,把端口映射到 `localhost:3000`,访问页面、点 server actions、试导航——三项都正常才能进入下一步。

本地烟测的副作用是 Docker Desktop 镜像体积很大(包含整个 Node 运行时与所有依赖),跑完应当先 `docker rm` 容器再 `docker rmi` 镜像,把空间腾出来。否则一台机器很快被几十个废弃镜像塞满。

**给生产 VPS 构建时必须显式指定 `--platform`**。视频里 Wesley 提到本机是 MacBook、VPS 是 Linux 系统且通常是 AMD64;**不指定平台,镜像会被 VPS 的 Docker daemon 直接拒绝**。具体命令是 `docker build --platform linux/amd64 -t ghcr.io/<user>/<repo>:latest .`。

### 5. 推镜像到 GitHub Container Registry (ghcr.io) [10:38](https://youtu.be/WgezEq7_lWo?t=638)

VPS 不会自己构建镜像——它需要一个能 `docker pull` 的镜像源。视频全程用 **GHCR (GitHub Container Registry)**,域名为 `ghcr.io`,免费且与 GitHub 账号天然打通。推送前先用 `docker login ghcr.io` 登录,密码不是 GitHub 密码而是 **Personal Access Token (PAT)**:在 GitHub Settings → Developer settings → Personal access tokens → Tokens (classic) 生成,权限勾选与 `packages` 相关的 `read/write` 即可。

Wesley 建议设短过期(他本人几个月就轮换一次),并把 token 当作密码一样保护——它能推镜像进你的账号空间。登录成功后 `docker push ghcr.io/<user>/<repo>:latest` 把镜像推上去,GitHub 用户页面的 Packages tab 立即可见。

PAT + short expiry 是这一套流程里唯一的"凭据管理"环节。视频没展开讨论 secret rotation,但实操层面相当于把 GitHub 密码的子集授权给一台开发机,泄露面比直接交密码更小。

### 6. VPS 初始化、SSH 与拉取运行镜像 [12:13](https://youtu.be/WgezEq7_lWo?t=733)

**采购环节,视频选用 Hostinger 的 KVM 2 套餐**:2 vCPU / 8 GB RAM / 100 GB / 8 TB 月流量。视频提到 Hostinger 还提供 Docker Manager(可粘贴 docker-compose URL 自动构建),但他建议**新手至少先手动跑一遍**——等熟悉后,再切到 Docker Manager 这种托管方案。本片选纯 Ubuntu 系统镜像、勾选 malware scanner,采购流程里 server location 可选离目标用户最近的地域。

VPS 就绪后,**SSH 进入服务器**是第一步。视频使用 `ssh root@<ip>` 配合购买时设的 root 密码登录。**生产环境应当建一个非 root 用户并给 sudo 权限**,视频里为了简化演示直接以 root 继续——这是一个值得注意的简化,真实部署应单独处理。

登录后做三件事:**① `apt update` 把系统包升级到最新;② 验证 Docker 已预装**(Hostinger Ubuntu 镜像自带,省去 `apt install docker.io` 步骤);③ `docker run hello-world` 跑一个烟测,确认 daemon 在线并能拉远端镜像。

接下来**用同一份 PAT 登录 GHCR、`docker pull` 镜像**。然后是关键命令:`docker run -d --restart unless-stopped -p 3000:3000 ghcr.io/<user>/<repo>:latest`。**`--restart unless-stopped` 是 VPS 场景下的标配**:Ubuntu 可能因为系统更新或物理机重启自己重启,而这个标志让容器在 daemon 起来后自动跟上,不必每次手动 `docker start`。

到这里,在浏览器输入 `http://<VPS IP>:3000` 就能看到 Next.js 应用,服务器组件、route handler、server action 全部正常。Wesley 也跑了一次 `curl` 验证返回 `HTTP 200`,并用 `docker logs <container_id>` 看到了熟悉的 Next.js 启动日志。但此时**应用是裸奔在公网上**——任何人都能通过 IP+端口访问,没有 HTTPS、没有域名、没有缓存。下一节用 Caddy 把这一切收口。

### 7. Caddy 反向代理 + 自定义域名 + HTTPS [19:51](https://youtu.be/WgezEq7_lWo?t=1191)

裸跑 Next.js 容器有两个问题:**① 端口 3000 暴露在公网,直接给攻击面;② 没有 HTTPS,所有流量明文**。视频给出的方案是**停掉容器、用 `localhost:3000` 在容器内重新跑,再在外面套一层 Caddy**。Caddy 监听公网 80(HTTP)/443(HTTPS)端口,内部把请求反代到本机 3000 上的容器。

Caddy 的两个杀手特性:**① 自动 HTTPS**——只要给它一个域名,它自动申请并续签 SSL 证书并配置 80→443 重定向;"[it is using HTTPS even. So, it's automatically been able to do that as well](https://youtu.be/WgezEq7_lWo?t=1495)",用户无需手动管理证书续签;**② 配置文件极简**——Caddyfile 只写一行域名 + `reverse_proxy localhost:3000` 就完事,远比 Nginx 同等配置短。

域名接入步骤:**① 在域名注册商加 A 记录,把根域名指到 VPS IP**;**② `nslookup` 验证 DNS 已生效**;**③ 编辑 Caddy 配置文件,把 demo 域名换成自己的域名**;**④ 重新格式化 + 校验 + reload Caddy 服务**。完成后 `https://<your-domain>/` 直接显示 Next.js 应用,证书自动签发。

安全层面,Wesley 顺手演示了 `systemctl status caddy` 确认服务以 systemd 方式常驻,并提示**应当用 Ubuntu 防火墙或 Hostinger 自带防火墙把 3000/其他不必要端口关掉**,只留 80/443 + SSH。这与源站隔离(Origin Isolation) 的精神一致——让真实业务容器只在内网暴露,公网入口集中到反向代理。

### 8. Cloudflare CDN 接入 [25:53](https://youtu.be/WgezEq7_lWo?t=1553)

VPS 单点再快也有地理延迟。**Cloudflare 免费档提供全球 CDN + 安全防护 + TLS 终结**——而 Hostinger 自家的 CDN 仅限"website hosting"产品,VPS 用户必须走第三方,Cloudflare 是 Hostinger 官方文档里点名推荐的方案。

接入流程:**① Cloudflare 后台 Add a site → 选 free plan → 它自动发现两条 DNS 记录并启用代理**;**② 把域名的 name server 从原注册商切到 Cloudflare 分配的两个**;**③ 等待 NS 生效**,Cloudflare 自己说最长可能要几小时,实际上多数十几分钟到半小时就够了。视频里 Wesley 大约 5 分钟后回来刷新,状态已经是"my domain is now protected by Cloud Flare. Your web traffic is proxying through Cloud Flare"。

接入后**CDN 缓存状态可以从浏览器 Network 面板直接验证**:打开 DevTools → Network → 选中某个 JS 文件 → Response Headers,能看到 `cf-cache-status: MISS`(首次请求,Cloudflare 回源拉了一次)→ 刷新后再看 `cf-cache-status: HIT`(命中边缘节点)。更硬核的诊断是访问 `https://<your-domain>/cdn-cgi/trace`,Cloudflare 返回一段纯文本,展示本次请求命中的数据中心 colo code —— 证明流量确实经过 Cloudflare 边缘,而不是直连 VPS。

Cloudflare 的额外价值:与 Caddy 的自动 HTTPS 配合,Cloudflare 会用自家签发的证书(用户无需在源站再申请一次),Caddy 这边仍然处理源站到 Cloudflare 之间的 HTTPS 加密。这是一种很干净的"边缘终止 + 源站再加密"分层结构。

## 可执行步骤

- [ ] 在 `next.config.js` 里设 `output: "standalone"`,跑一次 `npm run build` 确认 `.next/standalone/server.js` 生成。
- [ ] 复制 Next.js 官方 `docker-standalone-output` 模板的 Dockerfile 与 `.dockerignore` 到项目根目录;手动调整 Node 版本号到当前长期支持版本。
- [ ] 本地 `docker build -t <name> .` + `docker run -p 3000:3000 <name>`,访问 `localhost:3000` 验证 server actions / route handlers / 路由跳转全部正常,然后 `docker rm` + `docker rmi` 清理。
- [ ] 在 GitHub 生成 Personal Access Token(勾选 packages 读写、短过期),本地 `docker login ghcr.io` 后用 `docker build --platform linux/amd64 -t ghcr.io/<user>/<repo>:latest .` 构建生产镜像并 `docker push`。
- [ ] 采购 Hostinger VPS(纯 Ubuntu 镜像),SSH 用 root 登录,`apt update` + `docker run hello-world` 验证 daemon;为安全起见建一个 sudo 用户并禁用 root SSH。
- [ ] 在 VPS 上 `docker login ghcr.io` → `docker pull ghcr.io/<user>/<repo>:latest` → `docker run -d --restart unless-stopped -p 127.0.0.1:3000:3000 ghcr.io/<user>/<repo>:latest`,让容器只在内网可访问。
- [ ] 在 VPS 上安装 Caddy,编辑它的配置文件把域名反向代理到 `localhost:3000`,`systemctl reload caddy`,让 Caddy 自动签发并续签 SSL 证书。
- [ ] 在域名注册商加 A 记录把根域名指向 VPS IP,并把 name server 切到 Cloudflare 分配的 NS,等 NS 生效后在 Cloudflare 后台启用代理。
- [ ] 用 Ubuntu 防火墙(或 Hostinger 自带防火墙)关闭 3000 等非必要端口,只保留 80/443/SSH;在浏览器 Network 面板验证 JS/CSS 请求带 `cf-cache-status: HIT`。

## 关联

- [[2026-01-30-买Mac Mini前先用VPS自托管AI助手agent]] — 互补 — 本片补齐"前端 Web 应用"的部署路径,对方补"自托管 AI 助手 agent"在 VPS 上的部署路径,主机相同但服务形态完全不同。
- [[2026-04-25-在VPS上自托管Hermes Agent与Dashboard面板]] — 互补 — 同上,本片讲带反向代理与 CDN 的 Web 应用部署,对方讲 Hermes Agent 与面板的部署,共享"同一台 VPS 可同时跑多服务"的论点。
- VPS 自托管 — 进阶 — 沿用本片同样的 VPS 采购与基础运维流程;先读本片掌握 Caddy/Cloudflare/HTTPS 的标准壳层,再回头把任意服务(自托管 agent、自建应用)塞进同一台 VPS。

## 术语

- Docker image vs Docker container:镜像是一份只读打包(代码+运行时+依赖),容器是镜像的运行实例。
- Dockerfile:声明镜像构建步骤的纯文本文件,常用多阶段写法让最终镜像只留产物体积。
- Standalone output:Next.js 的构建模式,使产物只带一个最小化 server.js,无需在镜像里复制整棵 node_modules。
- GHCR (GitHub Container Registry):GitHub 提供的免费 Docker 镜像托管,域名 `ghcr.io`,与 GitHub PAT 鉴权。
- Personal Access Token (PAT):GitHub 用于代替密码授权 API/Packages 的短过期凭据。
- Reverse proxy:对外接收 HTTP/HTTPS 请求、内部按规则转发到本机服务的中间层,本片用 Caddy。
- Caddy:现代 Web 服务器,以"自动 HTTPS"与极简配置文件著称。
- Cloudflare CDN:把静态资源缓存到全球边缘节点的免费 CDN,接入方式是把域名的 NS 切到 Cloudflare。
- `--platform linux/amd64`:跨架构 Docker 构建必备参数,让本机架构构建的镜像能被 VPS 接受。
- `--restart unless-stopped`:Docker run 的重启策略,VPS 重启后容器自动跟上。
- A 记录:把域名直接指向一个 IP 地址的 DNS 记录类型。
- Nameserver (NS):负责告诉 DNS 查询该域名由哪台权威服务器解析,接入 Cloudflare 时需要切到 Cloudflare 分配的 NS。
- `cf-cache-status`:Cloudflare 在响应头里返回的缓存命中状态,首次 MISS、刷新后变 HIT,证明请求确实走了 Cloudflare 边缘。

## 金句

> "we can make it much simpler than what we did in some of the other videos." — 把 Next.js Docker 化部署这件事的复杂度说清楚:与过去几期相比,本片的官方模板 + GHCR + Caddy 组合可以省掉手写反代配置与手动证书申请。([00:14](https://youtu.be/WgezEq7_lWo?t=14))

> "you may want to specify the platform for which the image is meant for." — 跨架构构建时最容易被忽略的一步,缺失会导致 VPS daemon 直接拒绝拉取。([10:09](https://youtu.be/WgezEq7_lWo?t=609))

> "Caddy is a reverse proxy as it's called. There are similar ones like Nginx." — 把 Caddy 在整个栈里的角色一句话说清:外部入口 + 内部反代,Next.js 容器在 localhost:3000 上完全私有。([21:20](https://youtu.be/WgezEq7_lWo?t=1280))

> "my domain is now protected by Cloud Flare. Your web traffic is proxying through Cloud Flare, meaning it should be faster with caching speed and traffic services." — Cloudflare 启用代理后的官方提示:从这一刻起所有流量都过边缘节点,缓存与 SSL/TLS 由 Cloudflare 终结。([28:04](https://youtu.be/WgezEq7_lWo?t=1684))

## 立场与利益

视频全程使用 Hostinger 作为示例 VPS 提供商,作者在 description 里写明 Hostinger 是当日赞助方并提供 coupon code `BYTEGRAD`;对 Hostinger 自带 Docker Manager 等"托管化"方案做了正面介绍,但同时明确建议"先手动跑一遍,理解流程再切到托管"。Kinde 在 description 里被列为付费品牌大使,但本片内容完全不涉及 Kinde。

把关键主张分档:

- **与利益同向(待印证)**:对 Hostinger VPS 与 Docker Manager 的整体推荐——选它确实方便,但 Hostinger 是否在所有 Next.js 场景下都是最优选择,与同价位其他家 VPS 提供商的对比未做,需要外部印证。
- **利益中性**:Caddy 反代、自动 HTTPS、`--restart unless-stopped`、`--platform` 显式指定、Cloudflare CDN 接入——这些是与赞助方无关的通用工程经验,按内容本身采信。
- **与利益反向(可信度最高)**:Wesley 在 Hostinger 自带 Docker Manager 段落里特意提醒"先手动跑一遍再切到托管方案"——这一句是反对"用脚手架图省事"的产品倾向,直接利好观众,与他作为博主希望简化流程的本能反向。

## 价值定位

- **适合谁**:已经在本地跑通 Next.js、希望把同一个应用放到自有 VPS 上公开访问的人;尤其是 solo builder / indie hacker 想绕开托管平台锁定、把应用和数据握在自己手里的场景。
- **解决什么**:给出一套"Next.js → Dockerfile → GHCR → VPS → Caddy → Cloudflare"的端到端最小可用栈,每一步都有可执行的命令和具体的坑位提示(平台架构、容器重启策略、端口暴露范围、Cloudflare NS 切换)。
- **认知 vs 实操**:两者兼备,但更偏实操——本片不是讲"为什么用 Docker 部署",而是带观众一步步敲命令并验证每一步(本地 3000 端口可访问、VPS IP+3000 可访问、域名+HTTPS 可访问、CDN 边缘命中)。读完后可以直接照搬复制一份到自己的 VPS。
- **与 [[2026-04-25-在VPS上自托管Hermes Agent与Dashboard面板]] 重叠**:对方是 Hermes Agent 一键部署,本片是手动版 Web 应用部署。重叠部分是"主机是 Hostinger VPS",独有增量是"Web 应用需要的 Caddy/HTTPS/Cloudflare 完整壳层"——对方没讲 Caddy 与 Cloudflare,本片没讲一键 agent 部署。

## 自检问题

1. 视频推荐用 Next.js 的哪种构建模式作为 Docker 化的前置,以及为什么?
   **答案**:在 `next.config.js` 里设 `output: "standalone"`,这样 `npm run build` 会产出最小化 Node server.js,镜像里只需带产物体积即可保留 server actions/route handlers 等服务器侧特性。见「知识点详解1」[00:00](https://youtu.be/WgezEq7_lWo?t=0)
2. 在 MacBook 上构建给 Linux VPS 用的镜像,哪条命令参数必须显式加上,缺失会导致什么后果?
   **答案**:`--platform linux/amd64`,因为本机与 VPS 架构不同(视频里本机 MacBook、VPS 通常是 Linux AMD64),缺失时 VPS 的 Docker daemon 会直接拒绝拉取镜像。见「知识点详解4」[10:09](https://youtu.be/WgezEq7_lWo?t=609)
3. 在 VPS 上跑 Next.js 容器时,为什么要加 `--restart unless-stopped`?
   **答案**:VPS 自身可能被重启或做系统更新,这个标志让 Docker daemon 恢复时自动把容器也拉起,避免每次都要手工 docker start。见「知识点详解6」[18:50](https://youtu.be/WgezEq7_lWo?t=1130)
4. Caddy 与 Nginx 相比,在 HTTPS 这一步上有什么简化?
   **答案**:Caddy 只要在 Caddyfile 里写域名就自动申请并续签 SSL 证书并配置 80→443 重定向,不需要手动写证书路径或续签脚本。见「知识点详解7」[22:32](https://youtu.be/WgezEq7_lWo?t=1352)
5. 把域名 NS 切到 Cloudflare 后,怎么确认 CDN 已经生效?
   **答案**:打开浏览器 Network 面板,选一个 JS/CSS 请求看 Response Headers 里的 `cf-cache-status`,首次是 MISS,刷新后变 HIT;更直接的是访问 `/cdn-cgi/trace` 看返回的 colo code 是不是 Cloudflare 数据中心。见「知识点详解8」[28:32](https://youtu.be/WgezEq7_lWo?t=1712)