Cloudflare Pages + Workers 入門:免費靜態網站部署與 GitHub 自動化
如果你有一個靜態網站(HTML + CSS + JS,或任何 SSG 產出的結果),Cloudflare Pages 是目前免費方案裡最值得用的部署平台。
串接 GitHub 之後,每次你 git push,Cloudflare 自動拉取最新程式碼、執行建置指令、部署到全球 CDN。整個過程你不需要管伺服器,不需要設定 CI/CD,通常一分鐘內上線。
Workers 是另一個功能:跑在 Cloudflare 邊緣的 JavaScript 函式,可以用來處理表單提交、API 代理、URL 轉址,甚至做簡單的後端邏輯。
這篇帶你從零開始把靜態網站部署到 Cloudflare Pages,然後介紹幾個 Workers 的實用場景。
Cloudflare Pages 是什麼
Pages 是 Cloudflare 的靜態網站托管服務,類似 Vercel 和 Netlify,但有一些差異:
| 項目 | Cloudflare Pages | Vercel | Netlify |
|---|---|---|---|
| 免費方案建置次數 | 500 次/月 | 100 次/月 | 300 次/月 |
| 免費方案頻寬 | 無限 | 100 GB/月 | 100 GB/月 |
| CDN 節點 | 全球 300+ | 全球 | 全球 |
| Workers 整合 | ✅ 原生 | Edge Functions | Edge Functions |
| 自訂域名 | ✅ 免費 HTTPS | ✅ | ✅ |
| 預覽部署(PR) | ✅ | ✅ | ✅ |
Cloudflare Pages 的頻寬無限是最大優勢,對流量不穩定的個人網站特別友善。
部署靜態網站到 Cloudflare Pages
方法一:串接 GitHub(推薦)
這是最常用、最自動化的方式。
Step 1:建立 Pages 專案
- 登入 Cloudflare Dashboard
- 左側選單 → Workers & Pages → Create
- 選擇 Pages → Connect to Git
- 授權 Cloudflare 存取你的 GitHub 帳號
- 選擇要部署的 Repository
Step 2:設定建置參數
| 欄位 | 說明 | 範例 |
|---|---|---|
| Project name | Pages 的名稱(也是預設子網域) | my-blog |
| Production branch | 部署到正式環境的分支 | main |
| Build command | 建置指令 | python build.py / npm run build |
| Build output directory | 建置產出的目錄 | dist / public / out |
常見 SSG 的設定:
| SSG 框架 | Build command | Output directory |
|---|---|---|
| 自製 Python SSG | python build.py |
dist |
| Hugo | hugo |
public |
| Astro | npm run build |
dist |
| Next.js(靜態) | npm run build && npm run export |
out |
| Eleventy | npx @11ty/eleventy |
_site |
| Jekyll | jekyll build |
_site |
Step 3:部署
點擊 Save and Deploy,Cloudflare 開始第一次建置。
建置完成後,網站會部署到 https://your-project.pages.dev。這個網址永遠有效,即使你之後綁定自訂域名。
方法二:直接上傳(無 Git)
如果你只是想快速部署一個靜態資料夾,不想串接 Git:
- Workers & Pages → Create → Pages → Upload assets
- 把建置好的資料夾直接拖曳上傳
這種方式不支援自動重新部署,每次更新都要手動上傳。
綁定自訂域名
- 進入你的 Pages 專案 → Custom domains → Set up a custom domain
- 填入你的網域(例如
yourdomain.com或blog.yourdomain.com) - 如果域名由 Cloudflare 管理,DNS 記錄自動設定完成
- HTTPS 憑證自動申請,無需手動操作
環境變數設定
敏感資訊(API Key、設定值)不應該放在 Git 裡,可以在 Pages 設定環境變數:
- Pages 專案 → Settings → Environment variables
- 新增變數(Production / Preview 可分開設定)
- 建置時這些變數會注入到環境中
# build.py 裡這樣讀取
import os
adsense_id = os.environ.get('ADSENSE_ID', '')
Preview 部署
每次建立 Pull Request,Cloudflare Pages 自動建置一個預覽版本,部署到獨立的 URL(格式:https://[branch-name].[project].pages.dev)。
這對審查內容變更、測試新功能很有用,不會影響正式環境。
Cloudflare Workers 是什麼
Workers 是跑在 Cloudflare 邊緣節點的 JavaScript / TypeScript 函式。每個請求進來,Workers 先攔截,你的程式碼決定怎麼處理。
和傳統伺服器的差異: - 不需要管伺服器 - 啟動時間幾毫秒(不是秒) - 全球同時部署,就近執行 - 免費方案每天 10 萬次請求,對個人網站很夠
Workers 實用場景
場景 1:表單提交轉寄 Email
靜態網站沒有後端,表單提交是個痛點。用 Workers 接收表單 POST,呼叫 Cloudflare Email Routing 或 Resend API 發信:
export default {
async fetch(request, env) {
if (request.method !== 'POST') {
return new Response('Method not allowed', { status: 405 });
}
const data = await request.json();
const { name, email, message } = data;
// 用 Resend API 發信
const response = await fetch('https://api.resend.com/emails', {
method: 'POST',
headers: {
'Authorization': `Bearer ${env.RESEND_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
from: 'contact@yourdomain.com',
to: 'your@gmail.com',
subject: `新訊息來自 ${name}`,
text: `${message}\n\n回信地址:${email}`,
}),
});
return new Response(JSON.stringify({ ok: true }), {
headers: { 'Content-Type': 'application/json' },
});
},
};
場景 2:URL 轉址(Redirect)
舊網址轉到新網址,比在 _redirects 文件裡設定更靈活:
export default {
async fetch(request) {
const url = new URL(request.url);
// 舊網址轉址
if (url.pathname.startsWith('/old-path/')) {
const newPath = url.pathname.replace('/old-path/', '/new-path/');
return Response.redirect(`https://yourdomain.com${newPath}`, 301);
}
return fetch(request);
},
};
場景 3:API 代理(隱藏 API Key)
前端呼叫第三方 API 需要帶 API Key,但 API Key 不能暴露在前端。Workers 當中間層,前端打 Workers,Workers 帶著 Key 打真正的 API:
export default {
async fetch(request, env) {
const apiUrl = 'https://api.example.com/data';
const response = await fetch(apiUrl, {
headers: {
'Authorization': `Bearer ${env.API_KEY}`,
},
});
return response;
},
};
Pages Functions(Pages 內建的 Workers)
如果你用 Cloudflare Pages,可以直接在 Repository 裡的 functions/ 目錄放 Workers 程式碼,不需要另外部署:
my-project/
├── dist/ ← 靜態網站檔案
├── functions/
│ ├── api/
│ │ └── contact.js ← 對應路徑 /api/contact
│ └── _middleware.js ← 全域 middleware
functions/api/contact.js 的內容就是一個標準 Workers 函式,Cloudflare Pages 部署時自動把它變成可呼叫的 API endpoint。
常見問題
Q:Pages 和 Workers 要分開計費嗎? Pages 免費方案有 500 次/月建置次數,Workers 免費方案有 10 萬次/天請求。Pages Functions 的請求計入 Workers 配額,但 10 萬次/天對個人網站完全夠用。
Q:_redirects 還有用嗎?
有,簡單的轉址還是用 _redirects 最快,不需要寫 Workers。複雜邏輯才用 Workers。
Q:Pages 支援 Server-Side Rendering(SSR)嗎? 支援,透過 Pages Functions 可以做 SSR,但設定比純靜態複雜。一般靜態 SSG 不需要。
Q:可以在 Pages 上跑 Python 嗎?
建置階段可以(跑 python build.py),但 Workers Runtime 只支援 JavaScript / TypeScript / WebAssembly,不支援 Python。
小結
Cloudflare Pages 是靜態網站部署的最佳免費選項之一,串接 GitHub 後完全自動化,頻寬無限,CDN 遍布全球。Workers 則補足了靜態網站缺少後端的痛點,表單、API 代理、轉址都能用幾十行程式碼解決。
這兩個工具組合在一起,幾乎可以取代 Vercel + Lambda 的組合,而且全部免費。
🔗 延伸閱讀
- Cloudflare Tunnel 完整教學:不開路由器端口,也能讓服務對外公開
- Cloudflare Zero Trust Access:自架服務加上 Google 登入牆
- Cloudflare Email Routing:免費設定自訂網域 Email 轉寄
- Markdown 寫作流程:從草稿到發佈的完整工作流