Cloudflare Pages + Zero Trust

小白极客指南: 如何打造绝对私密的个人站点

个人站点
Cloudflare Pages
Zero Trust
手把手教你如何将 Quarto 站点通过 GitHub Actions 部署到 Cloudflare Pages,并配置 Zero Trust 邮箱验证门禁。特别收录多 GitHub 账号授权避坑指南及 Policy 配置细节。
Published

April 16, 2026

在这篇指南中,我们将从零开始,把一个本地的 Quarto 静态网站,自动化部署到 Cloudflare Pages,并且加上 Cloudflare Zero Trust 的安全防护。最终的效果是:网站在互联网上是隐藏的,只有在验证框输入你指定的邮箱,并填写验证码后,才能看到内容。

这非常适合用于部署家庭记录、个人金融投研系统、内部文档等高度隐私的站点。

前置准备

  1. 一个 GitHub 账号,并已经创建了一个 Private(私有) 仓库。
  2. 一个注册好的 Cloudflare 账号,并且在 Cloudflare 中托管了你的自定义域名(比如 example.com)。
  3. 你的网站源代码已经推送到 GitHub 仓库的 main 分支。

步骤一:配置 GitHub Actions 自动化流水线

由于我们的仓库是私有的,为了让 Cloudflare 能够访问到最终生成的网页(而不是源代码),我们需要用 GitHub Actions 把网站“编译”好,放到一个叫做 deploy 的特殊分支里。

在项目根目录下,创建 .github/workflows/publish.yml,并写入以下内容(如果你用的是 Quarto):

name: Deploy Quarto to Cloudflare Pages (Zero Trust)

on:
  push:
    branches:
      - main

# 必须开启写权限,否则无法推送到 deploy 分支
permissions:
  contents: write

jobs:
  build-deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Check out repository
        uses: actions/checkout@v4

      # (可选) 设置 R/Python 环境...
      - name: Set up R
        uses: r-lib/actions/setup-r@v2
        with:
          use-public-rspm: true

      - name: Set up renv
        uses: r-lib/actions/setup-renv@v2

      - name: Set up Quarto
        uses: quarto-dev/quarto-actions/setup@v2

      - name: Render Quarto Project
        run: quarto render

      # 关键步骤:将生成的 _site 文件夹推送到 deploy 分支
      - name: Deploy to Private Branch for Cloudflare
        uses: peaceiris/actions-gh-pages@v3
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          publish_dir: ./_site
          publish_branch: deploy
          force_orphan: true

提交并推送代码后,等待 Action 运行完毕。此时你的仓库中会多出一个 deploy 分支,里面全是纯静态的 HTML/CSS 文件。


步骤二:创建 Cloudflare Pages(⚠️ 避坑:多 GitHub 账号授权)

接下来我们要让 Cloudflare 去拉取刚才生成的 deploy 分支。

  1. 登录 Cloudflare 控制台,左侧菜单选择 Workers & Pages -> 点击 Create application -> 选择 Pages 选项卡 -> 点击 Connect to Git
  2. 选择你的 GitHub 账号并选择刚刚的私有仓库。

🛑 避坑指南:多 GitHub 账号授权问题

症状表现: 如果你有两个 GitHub 账号(比如 A 账号用来工作,B 账号用来搞副业),而你之前在浏览器里用 A 账号授权过 Cloudflare。当你想在下拉框选择 B 账号并点击 “Add account” 时,网页可能会毫无反应,下拉框里死活选不中 B 账号,导致无法点击 Begin setup 按钮。

根本原因: 浏览器的 Cookies 缓存了你上一次 GitHub 授权的 Session 状态。Cloudflare 在尝试跳转 GitHub 授权时,静默读取了旧账号的 Cookies,导致授权逻辑发生冲突。

完美解决办法: 1. 终极大法:使用无痕模式 (Incognito/Private Window)。打开浏览器的无痕窗口,先登录 GitHub 的 B 账号,再登录 Cloudflare,重新走一遍添加账号的流程,绝对能一次成功。 2. 平替方法:换一个浏览器。平时用 Chrome,授权时用 Edge 打开。 3. 彻底清理:在当前浏览器退出 GitHub 当前账号,清理 github.com 和 cloudflare.com 的 Cookies。

配置构建参数 (Set up builds and deployments)

成功选定仓库后,进入配置页面:

  • Production branch: 选择 deploy。(极其重要!不要选 main
  • Framework preset: 选择 None
  • Build command: 留空
  • Build output directory: 留空

点击 Save and Deploy。部署完成后,你可以绑定自己的自定义域名(比如 portal.example.com)。


步骤三:配置 Zero Trust 身份门禁 (⚠️ 隐蔽步骤解析)

现在你的网站已经在网上了,但只要知道网址,任何人都能看。我们需要加上 Zero Trust 大门。

  1. 在 Cloudflare 左侧菜单中,找到并进入 Zero Trust 面板。
  2. 左侧菜单选择 Access -> Applications -> 点击 Add an application
  3. 选择 Self-hosted

进入详细配置页面后,按以下重点填写:

1. Destinations (目标域名)

  • Subdomain: 填入你的子域名前缀(如 portal)。
  • Domain: 选择你的主域名(如 example.com)。
  • (这样组合起来就是你要保护的网址 portal.example.com)

2. Details (应用详情)

  • Name: 给门禁起个名字,比如 “My Private Portal”。
  • Session Duration: 选择 24 hours 或者更长,在此期间验证过的人不需要重新输入验证码。

🛑 避坑指南:Add a policy (添加策略)

这一步的 UI 容易让人迷糊。滚动到 “Access policies” 区域,默认显示的是 “No policies added”。很多人会忽略这一步直接往下划,导致配置无效。

正确操作: 仔细寻找区域内的新建策略入口(有的界面叫 “Add current policies”“Add a policy”)。 配置策略的核心逻辑是:谁(Who)被允许(Allow)访问?

  • Policy Name: 随便填,比如 Allow Owners
  • Action: 确保选中的是 Allow(允许访问)。
  • Configure rules (配置规则)
    • Include 区域,Selector 下拉框选择 Emails
    • 在旁边的 Value 框里,敲入你允许访问的邮箱地址(比如 your_name@gmail.com),输入完后按回车键确认。
    • (如果你有多个朋友要看,继续敲入他们的邮箱并回车。)

3. Authentication (认证方式)

  • 保持 Accept all available identity providers 处于 On 状态即可。
  • (前提:确保你在 Zero Trust 的 Settings -> Authentication 里已经开启了 One-time PIN。默认通常是开启的。)

点击最底部的 Add application 保存。


验收成果 🎉

现在,在浏览器的无痕窗口中输入你的自定义域名 portal.example.com

你将不会看到网站内容,而是看到一个印着 Cloudflare Logo 的拦截页面,要求你输入邮箱地址。 输入你刚才配置的授权邮箱,点击发送。你的邮箱会收到一个 6 位数的验证码(One-time PIN)。将验证码填入网页。

Boom! 网站瞬间呈现。恭喜你,你的私有堡垒搭建完成了!