跳至主要內容

Cloudflare Pages 部署指南:從零到生產環境

Cloudflare Pages 部署指南:從零到生產環境

Cloudflare Pages 是 Cloudflare 提供的靜態網站與全端應用部署平台,免費方案就提供無限頻寬、無限請求、全球 CDN,對前端開發者來說是非常有吸引力的選擇。這篇文章從頭開始介紹如何部署和設定 Cloudflare Pages。

為什麼選擇 Cloudflare Pages?

  • 免費方案非常慷慨:無限頻寬、無限請求
  • 全球 CDN:Cloudflare 在全球有 300+ 節點
  • 與 Workers 深度整合:可以加入 serverless 後端邏輯
  • 預覽部署:每個 PR 自動建立預覽環境
  • 自訂網域:免費 SSL,簡單設定

部署靜態網站

方法一:連接 Git 儲存庫

  1. 登入 Cloudflare Dashboard
  2. 進入 Workers & Pages → Create
  3. 選擇 Pages → Connect to Git
  4. 授權 GitHub/GitLab 存取
  5. 選擇儲存庫和分支

設定建置參數:

# Nuxt 3
Build command: npm run generate
Build output directory: .output/public

# Next.js (靜態匯出)
Build command: npm run build && npm run export
Build output directory: out

# Vue + Vite
Build command: npm run build
Build output directory: dist

# 純靜態 HTML
Build command: (留空)
Build output directory: ./(或你的資料夾)

方法二:Wrangler CLI 部署

npm install -g wrangler

# 登入
wrangler login

# 建立專案(第一次)
wrangler pages project create my-project

# 部署
npm run build
wrangler pages deploy ./dist --project-name=my-project

環境變數設定

# 設定生產環境變數(敏感資料)
wrangler pages secret put API_KEY --project-name=my-project

# 設定一般環境變數
# 在 Dashboard → Settings → Environment variables

在 Dashboard 中可以分別為 Production 和 Preview 設定不同的環境變數:

Production:
  API_URL=https://api.example.com
  NODE_ENV=production

Preview:
  API_URL=https://staging-api.example.com
  NODE_ENV=staging

Cloudflare Pages Functions

Pages Functions 讓你在靜態網站旁邊加入 serverless API 端點,檔案放在 functions/ 目錄:

project/
├── public/          # 靜態資源
├── functions/
│   ├── api/
│   │   ├── users.ts        # /api/users
│   │   └── users/
│   │       └── [id].ts     # /api/users/:id
│   └── _middleware.ts      # 全域 middleware
└── package.json
// functions/api/users/[id].ts
import type { PagesFunction } from '@cloudflare/workers-types'

interface Env {
  DB: D1Database
  KV: KVNamespace
}

export const onRequestGet: PagesFunction<Env> = async ({ params, env }) => {
  const { id } = params
  
  // 從 D1 資料庫查詢
  const user = await env.DB.prepare(
    "SELECT id, name, email FROM users WHERE id = ?"
  ).bind(id).first()
  
  if (!user) {
    return new Response(JSON.stringify({ error: 'User not found' }), {
      status: 404,
      headers: { 'Content-Type': 'application/json' }
    })
  }
  
  return Response.json(user)
}

export const onRequestPut: PagesFunction<Env> = async ({ params, request, env }) => {
  const { id } = params
  const body = await request.json() as { name?: string; email?: string }
  
  await env.DB.prepare(
    "UPDATE users SET name = COALESCE(?, name), email = COALESCE(?, email) WHERE id = ?"
  ).bind(body.name, body.email, id).run()
  
  return Response.json({ success: true })
}

Middleware 設定

// functions/_middleware.ts
import type { PagesFunction } from '@cloudflare/workers-types'

export const onRequest: PagesFunction = async ({ request, next }) => {
  // 加入 CORS headers
  const response = await next()
  const newResponse = new Response(response.body, response)
  newResponse.headers.set('Access-Control-Allow-Origin', '*')
  newResponse.headers.set('X-Content-Type-Options', 'nosniff')
  return newResponse
}

自訂網域設定

# 在 Dashboard 中:
# Pages → 你的專案 → Custom domains → Set up a custom domain

# 如果網域已在 Cloudflare 管理,幾秒內就能完成設定
# 如果在其他地方管理,需要新增 CNAME 記錄:
# CNAME  www  your-project.pages.dev

wrangler.toml 設定檔

# wrangler.toml
name = "my-project"
pages_build_output_dir = "./dist"

[[ d1_databases ]]
binding = "DB"
database_name = "my-database"
database_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"

[[ kv_namespaces ]]
binding = "CACHE"
id = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

[vars]
APP_ENV = "production"

GitHub Actions 自動部署

# .github/workflows/deploy.yml
name: Deploy to Cloudflare Pages

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'
      
      - run: npm ci
      - run: npm run build
      
      - name: Deploy to Cloudflare Pages
        uses: cloudflare/wrangler-action@v3
        with:
          apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
          accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
          command: pages deploy ./dist --project-name=my-project

重定向和標頭設定

public/_redirects 檔案(靜態資源目錄):

# SPA fallback
/*  /index.html  200

# 重定向
/old-page  /new-page  301
/api/*  https://api.example.com/:splat  200

public/_headers 檔案:

/assets/*
  Cache-Control: public, max-age=31536000, immutable

/*
  X-Frame-Options: DENY
  X-Content-Type-Options: nosniff
  Referrer-Policy: strict-origin-when-cross-origin

Cloudflare Pages 對於前端專案來說是非常棒的部署平台,特別是免費方案就包含了大多數需求。搭配 Workers、D1、KV、R2 等服務,可以快速搭建出完整的全端應用,不需要管理任何伺服器。

分享這篇文章