Đến nội dung chính
phamnam.me
Quay lại

Triển khai Astro lên Cloudflare Pages: từ cài đặt đến tên miền riêng

Hướng dẫn thực tế để đưa một blog Astro tĩnh lên Cloudflare Pages: cài đặt, cấu hình build, kết nối GitHub, gắn tên miền, bảo vệ trang quản trị và xử lý lỗi thường gặp.

11 phút đọc

Astro là một lựa chọn rất hợp cho blog cá nhân: nội dung viết bằng Markdown, trang được render sẵn thành HTML tĩnh, ít JavaScript và dễ đưa lên CDN. Cloudflare Pages là phần còn lại của bức tranh: nối repo GitHub, chạy build mỗi khi có commit và phân phối file tĩnh qua mạng lưới của Cloudflare.

Bài này ghi lại quy trình mình đang dùng cho blog này, từ lúc tạo project Astro đến khi có tên miền riêng chạy HTTPS. Các bước không phụ thuộc vào một template cụ thể; bạn có thể áp dụng cho blog, portfolio hoặc site tài liệu.

Bài viết tập trung vào static site — cách đơn giản và rẻ nhất. Nếu bạn cần SSR, API Routes hoặc xử lý request động, xem phần cuối bài.

Bạn sẽ làm gì

Luồng tổng quát:

Máy local ──git push──> GitHub ──webhook──> Cloudflare Pages
                                             │
                                             ├─ pnpm build
                                             ├─ tạo thư mục dist/
                                             └─ deploy lên CDN
                                                       │
Tên miền riêng ──HTTPS──> Cloudflare CDN <─────────────┘

Có bốn phần chính:

  1. Tạo và chạy thử project Astro ở local.
  2. Cấu hình build và đưa code lên GitHub.
  3. Kết nối GitHub với Cloudflare Pages.
  4. Gắn tên miền, bật HTTPS và kiểm tra sau deploy.

1. Chuẩn bị

Bạn cần:

Kiểm tra nhanh:

node -v
pnpm -v
git --version

2. Tạo project Astro

Tạo project mới:

pnpm create astro@latest my-blog
cd my-blog
pnpm install
pnpm dev

Khi được hỏi, chọn template Blog nếu muốn có sẵn layout, RSS và Markdown; chọn Minimal nếu muốn tự dựng từ đầu. Có thể truyền template trực tiếp:

pnpm create astro@latest my-blog --template blog

Mở http://localhost:4321 để xem thử. Sau đó build thử bản production:

pnpm build
pnpm preview

Nếu thành công, Astro tạo thư mục dist/. Đây chính là thứ Cloudflare Pages sẽ deploy. Kiểm tra nhanh:

ls dist

Bạn sẽ thấy index.html, các thư mục asset và có thể cả rss.xml, sitemap-index.xml tùy template.

3. Cấu hình Astro cho production

Mở astro.config.mjs (hoặc .ts) và đặt site thành domain thật:

import { defineConfig } from "astro/config";

export default defineConfig({
  site: "https://example.com",
  trailingSlash: "always",
});

Vì sao cần site?

trailingSlash: "always" là tùy chọn, nhưng nên chọn một kiểu và giữ nhất quán. Blog này dùng dấu / ở cuối URL, ví dụ /posts/ten-bai/. Nếu bạn dùng kiểu không có dấu /, đặt "never" và kiểm tra lại link nội bộ.

Ghim phiên bản Node và pnpm

Tạo file .nvmrc ở root:

24.22.1

Trong package.json, giữ trường packageManager:

{
  "packageManager": "[email protected]",
  "engines": {
    "node": ">=24.22.1 <25"
  }
}

Cloudflare Pages đọc .nvmrc (hoặc .node-version) để chọn Node. Với pnpm, build image v3 không tự suy ra version từ pnpm-lock.yaml, nên ta sẽ đặt PNPM_VERSION ở bước sau. Trường packageManager vẫn hữu ích để đồng bộ môi trường local.

Thêm header bảo mật cơ bản

Tạo public/_headers:

/*
  X-Content-Type-Options: nosniff
  Referrer-Policy: strict-origin-when-cross-origin
  X-Frame-Options: DENY
  Permissions-Policy: camera=(), microphone=(), geolocation=()

/admin/*
  X-Robots-Tag: noindex, nofollow
  Cache-Control: no-store

Cloudflare Pages đọc file này và áp header cho site tĩnh. Đây chỉ là lớp bảo vệ cơ bản; với trang quản trị, hãy dùng thêm Cloudflare Access và xác thực của CMS.

Kiểm tra build lần cuối

pnpm build

Nếu dùng Pagefind để tìm kiếm, nhớ chạy nó sau khi Astro build xong:

pnpm build
pnpm dlx pagefind --site dist

Không chạy Pagefind trước astro build, vì lúc đó chưa có HTML để index.

4. Đưa code lên GitHub

Nếu project chưa có Git:

git init
git add .
git commit -m "feat: khoi tao blog Astro"
git branch -M main
git remote add origin https://github.com/<user>/<repo>.git
git push -u origin main

Một vài lưu ý:

5. Kết nối Cloudflare Pages

Vào Cloudflare Dashboard:

  1. Chọn Workers & Pages.
  2. Chọn Create application → Pages → Connect to Git.
  3. Cấp quyền cho Cloudflare truy cập repo GitHub.
  4. Chọn repo và nhấn Begin setup.

Điền cấu hình:

TrườngGiá trị
Project namemy-blog (hoặc tên bạn muốn)
Production branchmain
Framework presetAstro
Build commandpnpm build
Build output directorydist
Root directory/ (hoặc thư mục con nếu monorepo)

Cloudflare có thể tự điền npm run build khi chọn preset Astro. Hãy sửa lại thành pnpm build nếu repo dùng pnpm.

Biến môi trường

Với static site, biến môi trường chỉ có tác dụng tại thời gian build. Nếu cần ghim phiên bản:

NODE_VERSION=24.22.1
PNPM_VERSION=12.15.0

Chỉ đặt những biến thật sự cần. Lưu ý:

Nhấn Save and Deploy. Theo dõi log build. Khi thành công, bạn nhận được URL dạng:

https://my-blog.pages.dev

Mở URL này và kiểm tra vài trang trước khi gắn domain.

Cách khác: deploy trực tiếp bằng Wrangler

Nếu chưa muốn nối GitHub, có thể build ở local rồi upload:

pnpm build
pnpm dlx wrangler pages deploy dist --project-name my-blog

Cách này nhanh nhưng không có tự động build khi push. Với blog cần cập nhật thường xuyên, nối Git vẫn tiện hơn.

6. Gắn tên miền riêng

Trong project Pages:

  1. Vào Custom domains.
  2. Thêm domain gốc, ví dụ example.com.
  3. Thêm cả www.example.com nếu muốn người dùng gõ www vẫn vào được.
  4. Làm theo hướng dẫn DNS mà Cloudflare hiển thị.

Nếu domain đang dùng nameserver của Cloudflare, việc tạo bản ghi thường gần như tự động. Nếu DNS nằm ở nơi khác:

Đừng vội kết luận site lỗi nếu vừa thêm domain mà thấy 522 hoặc lỗi SSL. DNS và certificate có thể cần vài phút; hãy kiểm tra lại trạng thái trong Pages trước.

Chọn một URL chính thức

Nên chọn một trong hai:

https://example.com
https://www.example.com

rồi chuyển hướng cái còn lại về đó bằng 301. Với Cloudflare, dùng Rules → Redirect Rules:

Kiểm tra:

curl -I "https://www.example.com/posts/ten-bai/?x=1"

Kết quả mong đợi là 301 và Location trỏ về https://example.com/posts/ten-bai/?x=1.

Sau đó đảm bảo site trong astro.config là URL chính thức, để canonical, RSS và sitemap không sinh ra địa chỉ www.

7. Quy trình cập nhật và rollback

Sau khi nối Git, mỗi lần push lên main sẽ kích hoạt build production. Các nhánh khác có thể tạo preview deployment với URL riêng — hữu ích để xem thử trước khi merge.

Một số thói quen nên giữ:

Bỏ qua build khi cần

Cloudflare Pages bỏ qua build nếu commit message chứa các token như [skip ci]. Blog này dùng [skip ci] cho những commit chỉ sửa tài liệu hoặc lưu bản nháp từ CMS.

Ví dụ:

git commit -m "docs: cap nhat ghi chu [skip ci]"

Chỉ dùng khi thật sự không cần deploy. Nếu bạn đang chờ một thay đổi quan trọng lên production, đừng thêm token này.

Rollback

Trong Pages → Deployments, chọn một deployment production cũ và nhấn Rollback. Cloudflare sẽ phục vụ lại bản build đó.

Lưu ý: rollback chỉ đổi bản đang phục vụ, không sửa repo. Nếu lỗi vẫn còn trong source, lần build tiếp theo sẽ đưa lỗi trở lại. Cách bền vững là revert commit hoặc sửa source rồi deploy lại.

8. Kiểm tra sau khi deploy

Đừng chỉ nhìn trang chủ. Một checklist ngắn:

Có thể kiểm tra nhanh bằng curl:

curl -I https://example.com/
curl -I https://example.com/rss.xml
curl -I https://example.com/sitemap-index.xml
curl -I https://example.com/khong-ton-tai/

9. Lỗi thường gặp

Hiện tượngNguyên nhân thường gặpCách xử lý
pnpm: not foundBuild image chưa bật pnpm/CorepackĐặt PNPM_VERSION, thêm bước corepack enable, hoặc dùng npm nếu project không phụ thuộc pnpm
Build lỗi phiên bản Node.nvmrc hoặc NODE_VERSION không khớpKiểm tra log; đặt NODE_VERSION đúng major mà Pages hỗ trợ
Build thành công nhưng site 404Sai output directory hoặc root directoryĐặt output dist, root / (hoặc đúng thư mục con)
CSS/JS/ảnh 404Sai site, base hoặc trailingSlashKiểm tra astro.config; dùng đường dẫn nhất quán; xem URL thực tế trong HTML
Domain mới báo 522/SSL pendingDNS chưa đúng hoặc certificate chưa cấpKiểm tra custom domain status, bản ghi CNAME/ALIAS; chờ thêm
Push rồi nhưng nội dung không đổiBuild bị skip, sai branch hoặc đang xem cacheXem commit message có [skip ci] không; kiểm tra deployment mới nhất; hard-refresh
RSS/sitemap trỏ về localhostThiếu site trong Astro configĐặt site thành domain thật rồi build lại
Tìm kiếm không có kết quảPagefind chạy trước Astro buildChạy astro build trước, sau đó mới index dist
Redirect www bị vòng lặpRule redirect ngược hoặc sai SSL/TLS modeKiểm tra rule một chiều www → apex; không tạo rule ngược lại
Biến môi trường không có trong browserBiến không phải PUBLIC_*, hoặc site tĩnhChỉ dùng PUBLIC_* cho giá trị công khai; secret phải xử lý ở backend

Một lỗi ít được chú ý: đừng thêm fallback SPA kiểu /* /index.html 200 cho một site Astro nhiều trang. Nó sẽ biến mọi URL sai thành trang chủ và làm hỏng SEO/404. Astro đã tạo sẵn các file HTML tĩnh; không cần fallback trừ khi bạn thật sự xây SPA.

10. Khi nào cần Workers hoặc SSR?

Với blog tĩnh, Cloudflare Pages là đủ. Bạn chỉ cần chuyển sang hướng Workers/SSR khi:

Khi đó, thêm adapter Cloudflare của Astro, chuyển output sang chế độ server và deploy qua Workers thay vì chỉ upload file tĩnh. Secret lúc này nên đặt bằng wrangler secret hoặc trong dashboard, không nằm trong biến PUBLIC_*.

Đừng thêm adapter SSR chỉ vì “cho hiện đại”. Static site build nhanh, ít lỗi runtime, ít chi phí và dễ cache hơn.

11. Bảo mật và chi phí

Một blog tĩnh trên Cloudflare Pages thường nằm gọn trong gói Free:

Vài nguyên tắc:

12. Áp dụng cho blog này

Blog này dùng AstroPaper với Astro, pnpm và Pagefind. Cấu hình thực tế:

Node:            24.22.1
pnpm:            12.15.0
Build command:   pnpm build
Output:          dist
Domain chính:    https://phamnam.me
www:             301 → https://phamnam.me

Script pnpm build trong repo không chỉ chạy astro build mà còn kiểm tra type, tạo index tìm kiếm Pagefind và copy asset cần thiết. Vì vậy trên Cloudflare Pages chỉ cần đúng một lệnh pnpm build; không cần thêm bước build thủ công.

Trang quản trị /admin/ được đặt sau Cloudflare Access, và CMS có lớp đăng nhập GitHub riêng. Đây là mô hình hai lớp: Access chặn truy cập ở edge, CMS kiểm tra quyền ghi repo. Không lớp nào thay thế lớp còn lại.

Tóm lại

Quy trình ngắn gọn:

  1. Tạo Astro project, chạy pnpm build và kiểm tra dist/.
  2. Đặt site, ghim Node/pnpm, commit lockfile.
  3. Push lên GitHub.
  4. Nối repo với Cloudflare Pages; build pnpm build, output dist.
  5. Gắn domain, bật HTTPS, chọn URL chính và redirect www bằng 301.
  6. Kiểm tra RSS, sitemap, 404, canonical và mobile sau mỗi lần deploy.

Cloudflare Pages không làm blog của bạn “tự động hay hơn”, nhưng nó lo phần vận chuyển rất tốt: build từ Git, CDN toàn cầu, HTTPS và rollback đều có sẵn. Phần còn lại — nội dung, cấu trúc và trải nghiệm đọc — vẫn là việc của bạn.

Tài liệu tham khảo


Chia sẻ bài viết: