Cloudflare Pages — Deploy Full-Stack miễn phí trên Edge toàn cầu

Posted on: 4/26/2026 11:16:06 PM

Bạn đã bao giờ muốn deploy một ứng dụng web full-stack mà không tốn đồng nào, không cần quản lý server, và website tự động phân phối đến hơn 330 data center trên toàn cầu chưa? Cloudflare Pages biến điều đó thành hiện thực. Đây không chỉ là một nền tảng hosting tĩnh — với Pages Functions, bindings đến KV, D1, R2, và cả Workers AI — Cloudflare Pages đã trở thành một nền tảng full-stack serverless hoàn chỉnh chạy trên edge.

330+Data center toàn cầu
Chi phí bandwidth (unlimited)
500Builds miễn phí/tháng
100KFunction requests/ngày (free)

1. Cloudflare Pages là gì?

Cloudflare Pages là nền tảng JAMstack cho phép bạn deploy ứng dụng web trực tiếp lên mạng lưới edge toàn cầu của Cloudflare. Khác với các hosting truyền thống đặt server ở một region duy nhất, Pages phân phối nội dung đến node gần người dùng nhất — giảm latency xuống mức tối thiểu.

Điểm đặc biệt: Cloudflare Pages không giới hạn bandwidth ngay ở free tier. So với Vercel (100GB/tháng) hay Netlify (100GB/tháng), đây là lợi thế cực lớn cho các website có traffic cao.

graph TB
    A["Developer push code"] --> B["Git Provider
(GitHub/GitLab)"] B --> C["Cloudflare Build Pipeline"] C --> D["Static Assets"] C --> E["Pages Functions"] D --> F["CDN Edge
330+ PoPs"] E --> G["Workers Runtime
Edge Compute"] F --> H["Người dùng toàn cầu"] G --> H style A fill:#f8f9fa,stroke:#e94560,color:#2c3e50 style B fill:#f8f9fa,stroke:#e94560,color:#2c3e50 style C fill:#e94560,stroke:#fff,color:#fff style D fill:#2c3e50,stroke:#fff,color:#fff style E fill:#2c3e50,stroke:#fff,color:#fff style F fill:#4CAF50,stroke:#fff,color:#fff style G fill:#4CAF50,stroke:#fff,color:#fff style H fill:#e94560,stroke:#fff,color:#fff

Hình 1: Luồng deploy và phân phối nội dung trên Cloudflare Pages

2. Ba cách Deploy lên Cloudflare Pages

2.1. Git Integration (Khuyến nghị)

Kết nối repository từ GitHub hoặc GitLab. Mỗi khi push code, Cloudflare tự động build và deploy. Branch main deploy lên production, các branch khác tạo preview deployment riêng với URL duy nhất.

# Cấu trúc project Vue.js + Pages Functions
my-app/
├── src/                    # Frontend source
│   ├── App.vue
│   └── main.ts
├── functions/              # Pages Functions (server-side)
│   ├── api/
│   │   ├── hello.ts       # GET /api/hello
│   │   └── users/
│   │       └── [id].ts    # GET /api/users/:id
│   └── _middleware.ts      # Middleware cho mọi route
├── public/
├── package.json
└── wrangler.toml           # Cấu hình Cloudflare

2.2. Direct Upload

Upload thư mục build sẵn qua Dashboard hoặc Wrangler CLI. Phù hợp khi bạn dùng CI/CD riêng (GitHub Actions, GitLab CI) và muốn kiểm soát quá trình build.

# Upload qua Wrangler CLI
npx wrangler pages deploy ./dist --project-name=my-app

# Hoặc tạo project mới và deploy
npx wrangler pages project create my-app
npx wrangler pages deploy ./dist --project-name=my-app --branch=main

2.3. C3 (Create Cloudflare CLI)

Công cụ scaffolding chính thức, tự động phát hiện framework và cấu hình build:

# Tạo project mới với framework tùy chọn
npm create cloudflare@latest my-app

# Chọn framework: Vue, React, Nuxt, Astro, SvelteKit, Remix...
# C3 tự cấu hình wrangler.toml và deploy command

3. Pages Functions — Biến trang tĩnh thành Full-Stack

Pages Functions chạy trên Cloudflare Workers runtime, sử dụng file-based routing giống Next.js hoặc Nuxt. Mỗi file trong thư mục functions/ tương ứng một API endpoint.

Ưu điểm so với serverless truyền thống

Pages Functions khởi động trong vài millisecond (không có cold start như AWS Lambda). Code chạy trên V8 isolate, không phải container — nhẹ hơn, nhanh hơn, tiết kiệm tài nguyên hơn.

3.1. File-based Routing

File pathRouteGhi chú
functions/api/hello.ts/api/helloStatic route
functions/api/users/[id].ts/api/users/:idDynamic param
functions/api/posts/[[path]].ts/api/posts/*Catch-all route
functions/_middleware.tsMọi routeMiddleware toàn cục

3.2. Viết API endpoint

// functions/api/hello.ts
export const onRequestGet: PagesFunction = async (context) => {
  return Response.json({
    message: "Xin chào từ Cloudflare Edge!",
    timestamp: new Date().toISOString(),
    colo: context.request.cf?.colo, // Data center gần nhất
  });
};

// functions/api/users/[id].ts
interface Env {
  DB: D1Database;  // Binding đến D1
}

export const onRequestGet: PagesFunction<Env> = async (context) => {
  const userId = context.params.id;
  const user = await context.env.DB
    .prepare("SELECT * FROM users WHERE id = ?")
    .bind(userId)
    .first();

  if (!user) {
    return new Response("Not found", { status: 404 });
  }
  return Response.json(user);
};

3.3. Middleware — Xác thực và logging

// functions/_middleware.ts
export const onRequest: PagesFunction = async (context) => {
  const start = Date.now();
  const response = await context.next();
  response.headers.set("Access-Control-Allow-Origin", "*");
  response.headers.set("X-Response-Time", `${Date.now() - start}ms`);
  return response;
};

// functions/api/_middleware.ts — chỉ áp dụng cho /api/*
export const onRequest: PagesFunction = async (context) => {
  const authHeader = context.request.headers.get("Authorization");
  if (!authHeader?.startsWith("Bearer ")) {
    return new Response("Unauthorized", { status: 401 });
  }
  context.data.user = await verifyToken(authHeader.slice(7));
  return context.next();
};

4. Bindings — Kết nối hệ sinh thái Cloudflare

Sức mạnh thực sự của Pages Functions nằm ở bindings — kết nối trực tiếp đến các dịch vụ Cloudflare mà không cần gọi API qua mạng. Dữ liệu truyền trong cùng data center, latency gần như bằng 0.

graph LR
    PF["Pages Functions"] --> KV["Workers KV
Key-Value Store"] PF --> D1["D1 Database
Serverless SQLite"] PF --> R2["R2 Storage
Object Storage"] PF --> DO["Durable Objects
Stateful Edge"] PF --> AI["Workers AI
ML Inference"] PF --> Q["Queues
Message Queue"] style PF fill:#e94560,stroke:#fff,color:#fff style KV fill:#f8f9fa,stroke:#e94560,color:#2c3e50 style D1 fill:#f8f9fa,stroke:#e94560,color:#2c3e50 style R2 fill:#f8f9fa,stroke:#e94560,color:#2c3e50 style DO fill:#f8f9fa,stroke:#e94560,color:#2c3e50 style AI fill:#f8f9fa,stroke:#e94560,color:#2c3e50 style Q fill:#f8f9fa,stroke:#e94560,color:#2c3e50

Hình 2: Bindings kết nối Pages Functions với hệ sinh thái Cloudflare

4.1. KV — Key-Value Storage siêu nhanh

Workers KV là hệ thống lưu trữ key-value phân tán trên toàn bộ edge network. Phù hợp cho cache, configuration, session data với thời gian đọc dưới 10ms tại edge.

// wrangler.toml
[[kv_namespaces]]
binding = "CACHE"
id = "xxxx"

// functions/api/config.ts
interface Env {
  CACHE: KVNamespace;
}

export const onRequestGet: PagesFunction<Env> = async (context) => {
  let config = await context.env.CACHE.get("site-config", "json");

  if (!config) {
    config = await fetchConfigFromOrigin();
    await context.env.CACHE.put("site-config", JSON.stringify(config), {
      expirationTtl: 3600,
    });
  }

  return Response.json(config);
};

4.2. D1 — SQL Database trên Edge

D1 là cơ sở dữ liệu SQLite serverless, chạy tại edge. Free tier cho phép 5 triệu lượt đọc/ngày và 100K lượt ghi/ngày — quá đủ cho hầu hết project cá nhân và startup giai đoạn đầu.

# Tạo database và chạy migration
npx wrangler d1 create my-db
npx wrangler d1 execute my-db --file=./schema.sql

-- schema.sql
CREATE TABLE posts (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  title TEXT NOT NULL,
  slug TEXT UNIQUE NOT NULL,
  content TEXT NOT NULL,
  created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);

CREATE INDEX idx_posts_slug ON posts(slug);

4.3. R2 — Object Storage không phí Egress

R2 tương thích S3 API nhưng không tính phí egress (phí truyền dữ liệu ra). Free tier: 10GB storage, 10 triệu lượt đọc/tháng. Lý tưởng cho lưu trữ hình ảnh, file upload, static assets.

// functions/api/upload.ts
interface Env {
  ASSETS: R2Bucket;
}

export const onRequestPost: PagesFunction<Env> = async (context) => {
  const formData = await context.request.formData();
  const file = formData.get("file") as File;

  if (!file) {
    return new Response("No file uploaded", { status: 400 });
  }

  const key = `uploads/${Date.now()}-${file.name}`;
  await context.env.ASSETS.put(key, file.stream(), {
    httpMetadata: { contentType: file.type },
  });

  return Response.json({ url: `/cdn/${key}`, size: file.size });
};

4.4. Workers AI — ML Inference tại Edge

Chạy các model AI trực tiếp trên Cloudflare infrastructure — text generation, image classification, embedding, translation — không cần GPU server riêng.

// functions/api/summarize.ts
interface Env {
  AI: Ai;
}

export const onRequestPost: PagesFunction<Env> = async (context) => {
  const { text } = await context.request.json();

  const result = await context.env.AI.run(
    "@cf/meta/llama-3.1-8b-instruct",
    {
      messages: [
        { role: "system", content: "Tóm tắt nội dung sau bằng tiếng Việt, ngắn gọn trong 3 câu." },
        { role: "user", content: text },
      ],
    }
  );

  return Response.json({ summary: result.response });
};

5. Preview Deployments và Rollback

Mỗi pull request tự động nhận URL preview riêng biệt (dạng abc123.my-app.pages.dev). Reviewer có thể truy cập trực tiếp để kiểm tra thay đổi mà không ảnh hưởng production.

Rollback tức thì

Phát hiện lỗi sau deploy? Chỉ cần một click trên Dashboard để rollback về bất kỳ deployment nào trước đó. Không cần revert code, không cần build lại — deployment cũ được kích hoạt ngay lập tức vì mọi phiên bản đều đã được lưu trên edge.

6. So sánh Cloudflare Pages với Vercel và Netlify

Tiêu chíCloudflare PagesVercelNetlify
Bandwidth (Free)Unlimited100 GB/tháng100 GB/tháng
Builds/tháng (Free)5006,000300 phút
Serverless Functions100K req/ngày100K req/tháng125K req/tháng
Edge RuntimeV8 Isolate (mọi nơi)Edge + ServerlessEdge Functions (Deno)
Database tích hợpD1 (SQLite), 5GB freePostgres (Neon)Không
Object StorageR2 (10GB, không phí egress)Blob StorageBlobs
Cold Start~0ms (V8 isolate)~250ms (Lambda)~200ms
Custom Domains (Free)100/project50/projectKhông giới hạn
DDoS ProtectionTích hợp sẵn, miễn phíCơ bảnCơ bản

Khi nào chọn Cloudflare Pages?

Chọn Pages khi cần bandwidth không giới hạn, latency thấp toàn cầu, và zero cold start. Chọn Vercel khi dùng Next.js với ISR/SSR phức tạp. Chọn Netlify khi cần CMS integration và form handling sẵn.

7. Deploy Vue.js lên Cloudflare Pages — Hướng dẫn thực tế

Quy trình từ A đến Z để deploy ứng dụng Vue.js với API backend trên Pages Functions:

# Bước 1: Tạo project Vue + Cloudflare
npm create cloudflare@latest my-vue-app -- --framework=vue

# Bước 2: Thêm Pages Functions
mkdir -p functions/api

# Bước 3: Cấu hình wrangler.toml
name = "my-vue-app"
compatibility_date = "2026-04-01"
pages_build_output_dir = "./dist"

[[d1_databases]]
binding = "DB"
database_name = "my-db"
database_id = "your-database-id"

[[kv_namespaces]]
binding = "CACHE"
id = "your-kv-id"

# Bước 4: Dev local
npx wrangler pages dev -- npx vite

# Bước 5: Deploy
npx wrangler pages deploy ./dist

Cấu hình proxy cho dev local trong vite.config.ts:

// vite.config.ts
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';

export default defineConfig({
  plugins: [vue()],
  server: {
    proxy: {
      '/api': {
        target: 'http://localhost:8788',
        changeOrigin: true,
      },
    },
  },
});

8. Giới hạn Free Tier chi tiết

Dịch vụFree TierGhi chú
Pages HostingUnlimited bandwidth, 500 builds/thángKhông cần credit card
Pages Functions100,000 requests/ngàyChạy trên Workers runtime
Workers KV100K đọc/ngày, 1K ghi/ngày, 1GBEventually consistent
D1 Database5M đọc/ngày, 100K ghi/ngày, 5GBSQLite serverless
R2 Storage10GB, 10M đọc/tháng, 1M ghi/thángS3-compatible, không phí egress
Workers AI10,000 neurons/ngàyNhiều model miễn phí
Queues1M operations/thángMessage queue

Giới hạn cần lưu ý

Mỗi file asset tối đa 25 MB. Mỗi site tối đa 20,000 file (free) hoặc 100,000 file (paid). Build timeout sau 20 phút. Workers CPU time giới hạn 10ms (free) hoặc 30 giây (paid) mỗi request.

9. Tối ưu Performance trên Cloudflare Pages

9.1. Cache Control cho Static Assets

// functions/_middleware.ts
export const onRequest: PagesFunction = async (context) => {
  const response = await context.next();
  const url = new URL(context.request.url);

  // Immutable cache cho assets có content hash
  if (url.pathname.match(/\/assets\/.*\.[a-f0-9]{8}\./)) {
    response.headers.set(
      "Cache-Control",
      "public, max-age=31536000, immutable"
    );
  }

  return response;
};

9.2. Smart Placement

Mặc định Functions chạy tại edge gần người dùng. Nếu function cần gọi database ở region cụ thể, Smart Placement tự động di chuyển function về gần data source để giảm round-trip.

# wrangler.toml
[placement]
mode = "smart"

9.3. Tự động tích hợp CDN

Khi thêm custom domain, website tự động nhận đầy đủ tính năng Cloudflare:

  • HTTP/3 + QUIC — giao thức truyền tải nhanh nhất hiện tại
  • Brotli compression — nén nhỏ hơn Gzip 20-30%
  • Early Hints (103) — browser bắt đầu load tài nguyên trước khi response chính đến
  • DDoS Protection — miễn phí, không giới hạn, tự động
  • SSL/TLS — HTTPS miễn phí cho mọi custom domain
  • Web Analytics — privacy-first analytics không cần client-side script

10. Workflow CI/CD cho Team

sequenceDiagram
    participant Dev as Developer
    participant GH as GitHub
    participant CF as Cloudflare Pages
    participant Edge as Edge Network

    Dev->>GH: Push feature branch
    GH->>CF: Webhook trigger
    CF->>CF: Build & test
    CF->>Edge: Deploy preview
    CF-->>GH: Comment preview URL

    Note over Dev,GH: Code review trên preview URL

    Dev->>GH: Merge to main
    GH->>CF: Webhook trigger
    CF->>CF: Build production
    CF->>Edge: Deploy toàn cầu
    CF-->>Dev: Deploy notification

Hình 3: Workflow CI/CD tự động với Git integration

11. Khi nào không nên dùng Cloudflare Pages?

Pages phù hợp hầu hết web app, nhưng có trường hợp nên cân nhắc giải pháp khác:

  • Long-running processes — Workers CPU time giới hạn 30 giây (paid). Xử lý nặng nên dùng Queues + Workers hoặc chuyển sang container (Fly.io, Railway).
  • Database quan hệ phức tạp — D1 là SQLite, không hỗ trợ stored procedure phức tạp hay multi-master replication. Cần PostgreSQL/MySQL đầy đủ thì kết hợp với database ngoài (Neon, PlanetScale).
  • Next.js App Router đầy đủ — Một số tính năng ISR on-demand của Next.js chưa được hỗ trợ hoàn toàn trên Pages. Vercel vẫn tối ưu nhất cho Next.js.
  • WebSocket persistent — Pages Functions là stateless. WebSocket cần dùng Durable Objects kết hợp Workers.

Kết luận

Cloudflare Pages đã vượt xa khái niệm "static site hosting" ban đầu. Với Pages Functions, bindings đến D1/KV/R2/AI, và mạng lưới 330+ data center — đây là nền tảng full-stack serverless miễn phí mạnh nhất hiện tại. Bandwidth không giới hạn, zero cold start, tích hợp sâu với hệ sinh thái bảo mật Cloudflare (WAF, DDoS, Bot Management) khiến nó trở thành lựa chọn hàng đầu cho developer cá nhân, startup, và cả dự án production quy mô lớn.

Nếu bạn đang tìm kiếm nơi deploy ứng dụng Vue.js, Nuxt, Astro hay bất kỳ framework nào mà không lo chi phí bandwidth, Cloudflare Pages xứng đáng là lựa chọn đầu tiên.

Nguồn tham khảo