Cloudflare Pages — Deploy Full-Stack miễn phí trên Edge toàn cầu
Posted on: 4/26/2026 11:16:06 PM
Table of contents
- 1. Cloudflare Pages là gì?
- 2. Ba cách Deploy lên Cloudflare Pages
- 3. Pages Functions — Biến trang tĩnh thành Full-Stack
- 4. Bindings — Kết nối hệ sinh thái Cloudflare
- 5. Preview Deployments và Rollback
- 6. So sánh Cloudflare Pages với Vercel và Netlify
- 7. Deploy Vue.js lên Cloudflare Pages — Hướng dẫn thực tế
- 8. Giới hạn Free Tier chi tiết
- 9. Tối ưu Performance trên Cloudflare Pages
- 10. Workflow CI/CD cho Team
- 11. Khi nào không nên dùng Cloudflare Pages?
- Kết luận
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.
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 path | Route | Ghi chú |
|---|---|---|
functions/api/hello.ts | /api/hello | Static route |
functions/api/users/[id].ts | /api/users/:id | Dynamic param |
functions/api/posts/[[path]].ts | /api/posts/* | Catch-all route |
functions/_middleware.ts | Mọi route | Middleware 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 Pages | Vercel | Netlify |
|---|---|---|---|
| Bandwidth (Free) | Unlimited | 100 GB/tháng | 100 GB/tháng |
| Builds/tháng (Free) | 500 | 6,000 | 300 phút |
| Serverless Functions | 100K req/ngày | 100K req/tháng | 125K req/tháng |
| Edge Runtime | V8 Isolate (mọi nơi) | Edge + Serverless | Edge Functions (Deno) |
| Database tích hợp | D1 (SQLite), 5GB free | Postgres (Neon) | Không |
| Object Storage | R2 (10GB, không phí egress) | Blob Storage | Blobs |
| Cold Start | ~0ms (V8 isolate) | ~250ms (Lambda) | ~200ms |
| Custom Domains (Free) | 100/project | 50/project | Không giới hạn |
| DDoS Protection | Tích hợp sẵn, miễn phí | Cơ bản | Cơ 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 Tier | Ghi chú |
|---|---|---|
| Pages Hosting | Unlimited bandwidth, 500 builds/tháng | Không cần credit card |
| Pages Functions | 100,000 requests/ngày | Chạy trên Workers runtime |
| Workers KV | 100K đọc/ngày, 1K ghi/ngày, 1GB | Eventually consistent |
| D1 Database | 5M đọc/ngày, 100K ghi/ngày, 5GB | SQLite serverless |
| R2 Storage | 10GB, 10M đọc/tháng, 1M ghi/tháng | S3-compatible, không phí egress |
| Workers AI | 10,000 neurons/ngày | Nhiều model miễn phí |
| Queues | 1M operations/tháng | Message 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
ClickHouse 26.x — Columnar Database cho Real-Time Analytics tỷ dòng dữ liệu mỗi giây
Drizzle ORM — TypeScript ORM siêu nhẹ đang thay đổi cách viết SQL
Disclaimer: The opinions expressed in this blog are solely my own and do not reflect the views or opinions of my employer or any affiliated organizations. The content provided is for informational and educational purposes only and should not be taken as professional advice. While I strive to provide accurate and up-to-date information, I make no warranties or guarantees about the completeness, reliability, or accuracy of the content. Readers are encouraged to verify the information and seek independent advice as needed. I disclaim any liability for decisions or actions taken based on the content of this blog.