Hướng dẫn thực hành • cập nhật theo tài liệu Cloudflare 2026

Deploy nhiều website HTML/JS tĩnh lên Cloudflare Free

Tài liệu này dành cho trường hợp website của bạn đã là static output: HTML/CSS/JS thuần hoặc React/Vite đã build ra dist/. Mục tiêu: mỗi website có một Cloudflare Pages project và có thể gắn một domain riêng.

Không cần VPSKhông Nginx, PM2, Docker hay Node runtime.
Nhiều domainMỗi site một project và một hoặc nhiều custom domain.
Deploy nhanhDrag & Drop khi bắt đầu, Wrangler khi số lượng site tăng.

0. Kiến trúc cần đạt được

Domain
site-a.com
→
Cloudflare DNS
SSL / CDN
→
Pages project
site-a
→
Static files
HTML / JS

Khi có nhiều website, bạn lặp lại theo mô hình dưới đây:

Cloudflare Account
├── Pages: customer-a   → customer-a.com
├── Pages: customer-b   → customer-b.com
├── Pages: landing-x    → landing-x.vn
└── Pages: portfolio    → myportfolio.com
Khuyến nghị: một website độc lập = một Pages project. Nếu nhiều domain cùng hiển thị một website thì có thể gắn nhiều custom domain vào cùng project.

1. Đăng ký tài khoản Cloudflare

1
Mở trang đăng ký

Truy cập dash.cloudflare.com/sign-up, nhập email và mật khẩu, sau đó xác minh email nếu Cloudflare yêu cầu.

2
Đăng nhập Dashboard

Sau đăng nhập, bạn sẽ quản lý cả Domains / DNS và Workers & Pages trong cùng một tài khoản.

Home

Websites

Workers & Pages

DNS
Cloudflare Dashboard • UI minh họa

Account Home

Ở các bước sau bạn chủ yếu dùng hai khu vực:

Workers & Pages để deploy website và Websites / DNS để quản lý domain.

2. Thêm domain vào Cloudflare

Nếu bạn muốn dùng domain gốc như example.com, Cloudflare yêu cầu domain đó được thêm làm zone và nameserver trỏ về Cloudflare.

1
Chọn Add a domain / Add a site

Nhập domain, ví dụ customer-a.com.

2
Chọn Free plan

Với website static thông thường, Free plan là đủ để bắt đầu.

3
Cloudflare đưa cho bạn 2 nameserver

Ví dụ minh họa:

alice.ns.cloudflare.com
bob.ns.cloudflare.com
4
Đổi nameserver tại nơi mua domain

Vào Hostinger/Namecheap/GoDaddy/... và thay nameserver hiện tại bằng hai nameserver Cloudflare cung cấp.

5
Chờ trạng thái Active

Quay lại Cloudflare và kiểm tra zone đã Active. Thời gian cập nhật DNS tùy registrar.

Quan trọng: không copy nameserver ví dụ ở trên. Hãy dùng đúng hai nameserver Cloudflare hiển thị cho domain của bạn.

3. Chuẩn bị website static

Cloudflare Pages chỉ cần thư mục chứa file đã sẵn sàng để phục vụ.

HTML/JS thuần

site-a/
├── index.html
├── about.html
├── css/
│   └── style.css
├── js/
│   └── main.js
└── images/

React/Vite đã build

dist/
├── index.html
└── assets/
    ├── index-abc123.js
    └── index-def456.css
Test trước khi upload: đảm bảo trong thư mục deploy có index.html ở cấp gốc.

4. Deploy website đầu tiên bằng Drag & Drop

Đây là cách dễ nhất khi bạn mới bắt đầu và đã có sẵn HTML/JS build output.

1
Vào Workers & Pages

Dashboard → Workers & Pages.

2
Create application

Chọn tạo Pages project và phương án Drag and drop your files.

3
Đặt project name

Ví dụ: customer-a. Cloudflare sẽ tạo địa chỉ mặc định dạng customer-a.pages.dev.

4
Upload thư mục static

Kéo các asset HTML/CSS/JS đã build vào vùng upload và chọn Deploy site.

Workers & Pages

Overview

Deployments

Custom domains
UI minh họa — tên nút có thể thay đổi nhẹ

Create Pages project

Project name: customer-a
Drop your static assets here
Deploy site

Sau khi thành công, hãy mở:

https://customer-a.pages.dev

5. Gắn domain riêng cho website

1
Mở Pages project

Workers & Pages → customer-a.

2
Mở Custom domains

Chọn Set up a domain.

3
Nhập domain

Ví dụ customer-a.com. Nếu zone đã nằm trên Cloudflare, DNS record cần thiết thường được tạo trong luồng cấu hình.

4
Thêm www nếu cần

Bạn có thể thêm tiếp www.customer-a.com như một custom domain khác.

Theo tài liệu Cloudflare, với apex domain như example.com, zone phải nằm trong Cloudflare và nameserver phải trỏ về Cloudflare. Với subdomain, có thể dùng CNAME tới <project>.pages.dev, nhưng vẫn nên thực hiện bước Add custom domain trong Pages trước.

6. Deploy website thứ 2, 3, 4...

Lặp lại mỗi website thành một project riêng:

Project Thư mục deploy Domain
customer-a ./customer-a customer-a.com
customer-b ./customer-b customer-b.com
landing-x ./landing-x landing-x.vn
site-a.com
↓
Pages A
site-b.com
↓
Pages B
site-c.vn
↓
Pages C
site-d.net
↓
Pages D

Free plan hiện có giới hạn theo tài liệu Cloudflare như: tối đa 500 builds/tháng, 20.000 files/site, file riêng lẻ tối đa 25 MiB và 100 custom domains/project. Với nhu cầu nhiều site static nhỏ, đây thường là mức khá thoải mái.

7. Khi có nhiều site: chuyển sang Wrangler CLI

Drag & Drop tốt để học. Khi đã có nhiều website, dùng Wrangler giúp deploy nhanh và có thể script hóa.

7.1 Kiểm tra Node.js

node -v
npm -v

Nếu chưa có Node.js, cài bản LTS từ nodejs.org.

7.2 Đăng nhập Cloudflare

npx wrangler login

Trình duyệt sẽ mở để bạn cấp quyền cho Wrangler.

7.3 Deploy một website

npx wrangler pages deploy ./site-a --project-name=site-a

Nếu là React/Vite đã build:

npx wrangler pages deploy ./dist --project-name=customer-a
Nếu project chưa tồn tại, tùy phiên bản Wrangler/flow hiện tại bạn có thể cần tạo Pages project trước trong Dashboard. Khi project đã tồn tại, lệnh trên dùng để đẩy version mới.

7.4 Xem các deployment

npx wrangler pages deployment list --project-name=customer-a

8. Tự động deploy nhiều website

Trong gói tải về cùng tài liệu này có sẵn sites.json, deploy-one.sh và deploy-all.sh.

sites.json

[
  {
    "name": "site-a",
    "dir": "./examples/site-a",
    "domain": "site-a.example.com"
  },
  {
    "name": "site-b",
    "dir": "./examples/site-b",
    "domain": "site-b.example.com"
  }
]

Deploy một site

chmod +x deploy-one.sh deploy-all.sh
./deploy-one.sh site-a ./examples/site-a

Deploy tất cả

./deploy-all.sh

Script mẫu dùng npx wrangler pages deploy. Domain chỉ mang tính metadata trong file config; custom domain nên cấu hình một lần trong Dashboard cho mỗi project.

9. Update website sau khi đã deploy

Sau lần deploy đầu tiên, các lần cập nhật sau không cần tạo lại Pages project, DNS hay custom domain. Bạn chỉ sửa source code, build lại nếu cần, rồi deploy version mới vào đúng project cũ.

Sửa source
HTML / JS / React
→
Build lại
nếu framework cần
→
Deploy lại
cùng project
→
Domain cũ
tự dùng bản mới

9.1 Website HTML/JS thuần

Ví dụ cấu trúc:

site-a/
├── index.html
├── css/
│   └── style.css
└── js/
    └── app.js

Sau khi sửa code, chạy lại:

npx wrangler pages deploy ./site-a \
  --project-name=site-a
Điểm quan trọng: giữ nguyên --project-name=site-a. Wrangler sẽ tạo deployment mới cho chính website đó.

9.2 React/Vite đã build

Khi source là React/Vite, bạn build lại trước:

npm run build

Sau đó deploy thư mục output:

npx wrangler pages deploy ./dist \
  --project-name=site-a

Domain cũ vẫn giữ nguyên:

site-a.pages.dev
domain-a.com

Bạn không phải cấu hình lại:

DNS
Custom domain
SSL
Nameserver

9.3 Update bằng script có sẵn

Nếu dùng bộ script trong handbook này:

./deploy-one.sh site-a ./examples/site-a

Mỗi lần update chỉ cần chạy lại cùng lệnh.

9.4 Chỉ deploy site đã thay đổi

Nếu bạn có nhiều site:

projects/
├── customer-a/
├── customer-b/
└── customer-c/

Nếu chỉ sửa customer-b, chỉ deploy:

./deploy-one.sh customer-b ./customer-b
Khuyến nghị: không chạy deploy-all.sh nếu chỉ một website thay đổi. Deploy riêng từng site giúp giảm số lần build/deploy và hạn chế rủi ro.

10. Thêm tính năng, quản lý version và rollback

Khi website đã chạy ổn định, workflow tốt nhất là xem mỗi lần thêm tính năng như một version mới của cùng Pages project.

10.1 Quy trình thêm tính năng

1
Sửa source code

Ví dụ thêm form liên hệ, section mới, analytics, menu, animation hoặc tính năng JavaScript.

2
Test local

Mở website local và kiểm tra HTML/CSS/JS trước khi đưa production.

3
Build nếu cần

HTML thuần không cần build. React/Vite thường chạy npm run build.

4
Deploy vào project cũ

Dùng cùng --project-name để Cloudflare tạo deployment mới.

5
Kiểm tra production

Test domain thật, DevTools Console, Network và responsive.

10.2 Mô hình version

site-a
│
├── Deployment v1
│   └── Homepage ban đầu
│
├── Deployment v2
│   └── Thêm Contact section
│
├── Deployment v3
│   └── Update JavaScript
│
└── Deployment v4
    └── Bản hiện tại

Mỗi lần deploy, Cloudflare tạo một deployment mới thay vì bạn phải ghi đè thủ công lên server.

10.3 Rollback khi version mới lỗi

Trong Dashboard:

Cloudflare Dashboard
→ Workers & Pages
→ Chọn project
→ Deployments
→ Chọn deployment ổn định trước đó
→ Rollback / Promote
Thực hành tốt: sau mỗi lần deploy production, hãy kiểm tra nhanh các trang chính trước khi tiếp tục phát triển tính năng khác.

10.4 Nên dùng Git khi bắt đầu update thường xuyên

Khi website chỉ upload một lần, Drag & Drop là đủ. Nhưng nếu bạn sửa site thường xuyên, nên quản lý source bằng Git.

git add .
git commit -m "Add contact section"
git push

Workflow phát triển sẽ rõ ràng hơn:

Developer
Edit source
→
Git
Commit
→
Build
Static output
→
Wrangler
Deploy
→
Cloudflare
Production

10.5 Workflow mình khuyên dùng

Tình huống Cách làm
Site mới Tạo Pages project → deploy lần đầu → gắn domain.
Sửa HTML/CSS/JS Sửa source → test → deploy lại cùng project.
React/Vite Sửa source → npm run build → deploy dist/.
Chỉ một site thay đổi Dùng deploy-one.sh.
Nhiều site cùng thay đổi Dùng deploy-all.sh.
Version mới bị lỗi Rollback deployment trước trong Dashboard.
Update thường xuyên Dùng Git + Wrangler, sau này có thể nâng lên CI/CD.

10.6 Ví dụ thực tế: thêm tính năng cho customer-b

Giả sử bạn sửa website:

projects/customer-b/
├── index.html
├── css/
│   └── style.css
└── js/
    └── app.js

Sau khi sửa xong:

./deploy-one.sh customer-b ./projects/customer-b

Luồng thực tế:

customer-b.com
      │
      ├── Version cũ
      │
      └── Deploy version mới
              ↓
       customer-b.com
       tự dùng bản mới
Kết luận: lần đầu deploy là bước thiết lập hạ tầng. Những lần sau chỉ là chu kỳ Edit → Test → Build → Deploy.

11. Các lỗi thường gặp

Hiện tượng Nguyên nhân thường gặp Cách xử lý
Trang trắng / 404 Upload sai cấp thư mục, thiếu index.html Đảm bảo index.html nằm ngay root của thư mục deploy.
CSS/JS không load Đường dẫn asset tuyệt đối sai Kiểm tra DevTools → Network và đường dẫn trong HTML.
Domain chưa hoạt động Nameserver chưa cập nhật hoặc custom domain chưa active Kiểm tra zone status, DNS, Custom domains.
CNAME thủ công bị 522 Chỉ tạo CNAME nhưng chưa add domain trong Pages Vào Pages → Custom domains → Set up a domain trước.
File upload thất bại File quá lớn Pages Free giới hạn asset đơn lẻ 25 MiB; file lớn nên cân nhắc R2.
HTML route behavior: Pages tự phục vụ các file HTML theo route và bạn có thể tạo 404.html để tùy biến trang Not Found.

Checklist triển khai một website mới

📘 Chuyên đề: GitHub Monorepo → nhiều Cloudflare Pages projects

Dành cho cấu trúc websites/site-a, site-b, site-c. Hướng dẫn Root directory, Build output, Build watch paths, auto deploy, preview branch và workflow update.

Mở hướng dẫn Monorepo

Tài liệu Cloudflare chính thức