Kế hoạch public wiki cá nhân qua Quartz và Cloudflare Pages

Tóm tắt

Không phải ingest từ tài liệu có sẵn — đây là ghi chú quyết định hướng đi, chốt qua trao đổi trực tiếp (2026-07-27): dùng quartz-static-site-generator để build các wiki trong lumina-wiki (markdown kiểu Obsidian, wikilink dạng ngoặc vuông kép + frontmatter, tương thích sẵn) thành site tĩnh, deploy lên cloudflare-pages bằng phương thức Direct Upload (wrangler pages deploy, không dùng Git integration), rồi khoá quyền truy cập bằng cloudflare-access (policy “Only me”, email OTP) — vì đây là wiki cá nhân, không phải nội dung công khai cho ai cũng xem được. Chưa triển khai — mới là ý định/hướng đã chọn.

Điểm chính

  • Static site generator: Quartz (quartz.jzhao.xyz) — build markdown Obsidian-style (frontmatter + wikilink dạng ngoặc vuông kép) thành site tĩnh, khớp định dạng wiki hiện có mà không cần chuyển đổi.
  • Hosting: Cloudflare Pages, dùng Direct Upload (npx wrangler pages deploy <thư-mục-build>) thay vì Git integration — lý do: không muốn nội dung wiki cá nhân nằm trên repo GitHub/GitLab của bên thứ ba. Build Quartz chạy local hoặc trên Pi, deploy thẳng bằng CLI wrangler.
  • Ràng buộc kỹ thuật đã biết: một khi chọn Direct Upload cho một project, không chuyển ngược sang Git integration được trên cùng project — muốn đổi phải tạo project Cloudflare Pages mới.
  • Free tier Cloudflare Pages đủ dùng cho quy mô wiki cá nhân: bandwidth không giới hạn ở mọi tier, 500 lượt build/tháng, 10GB storage, tối đa 20.000 file, mỗi file ≤25MiB.
  • Bảo mật: vì là wiki cá nhân (không public đại chúng), thêm hostname Cloudflare Pages (ví dụ wiki.nguyenbinhson.com) làm một Access Application trên Zero Trust Dashboard, policy “Only me” — cùng mô hình đã dùng cho Companion và SSH-Pi (xem vibe-companion-va-cloudflare-tunnel-tren-raspberry-pi, ssh-vao-pi-qua-cloudflare-tunnel-va-access). Access không phụ thuộc Cloudflare Tunnel — Tunnel chỉ cần khi origin sau NAT không có IP public; Cloudflare Pages đã có endpoint public sẵn nên bỏ qua Tunnel, chỉ cần Access đứng chắn trước.
  • Phương án đã cân nhắc và loại: build + serve static file ngay trên Raspberry Pi qua Docker + Cloudflare Tunnel riêng, theo đúng pattern đang dùng cho WordPress (~/services/wp_nguyenbinhson_com, xem topology-mang-homelab). Bị loại vì tốn công vận hành hơn — phải tự lo cơ chế rebuild và tải thêm CPU/RAM lên Pi vốn đã chạy nhiều service (AdGuard, WordPress, Companion…).
  • Wiki nào sẽ public: chưa chốt — cần rà nội dung trước khi publish, vì các wiki hiện có (đặc biệt homelab/) chứa chi tiết hạ tầng nhạy cảm (IP nội bộ, tunnel ID…) không nên đưa vào bản public nguyên trạng.

Tiến độ

  • Thử nghiệm local (2026-07-27): tạo lumina-wiki/quartz-site/ (clone từ jackyzha0/quartz qua degit, npm install), copy nội dung homelab/wiki/ vào quartz-site/content/ làm dữ liệu test — bản sao, không đụng wiki gốc. Dùng homelab chỉ để test giao diện/luồng build, chưa phải quyết định publish thật (xem câu hỏi mở bên dưới).
  • npx quartz build chạy sạch, không lỗi — 29 file markdown build thành site tĩnh (122 file output). Cảnh báo “couldn’t find git repository for content” vô hại — do lumina-wiki không phải git repo, Quartz chỉ không lấy được ngày sửa file cuối từ git.
  • Chạy npx quartz build --serve, xem thử tại localhost:8080 — đã xác nhận giao diện/kết quả build ổn, không cần chỉnh sửa gì thêm ở bước này. Đã dừng dev server sau khi xem xong.
  • Bước “cài Quartz, xem thử local” coi như đã hoàn thành. Các bước chưa làm: đăng nhập wrangler login, deploy thử bằng Direct Upload lên Cloudflare Pages, cấu hình Cloudflare Access.
  • quartz-site/ hiện là thư mục thử nghiệm cục bộ (project Quartz riêng, có node_modules/), chưa phải cấu trúc final.
  • Đã triển khai thật lên Cloudflare Pages (2026-07-27), dùng Direct Upload qua wrangler pages deploy như kế hoạch ban đầu.
  • Kiến trúc thực tế: mỗi wiki con là một Cloudflare Pages project riêng biệt, gắn custom domain dạng subdomain riêng (<tên-wiki>.wiki.nguyenbinhson.com), cộng với một project landing page riêng ở domain gốc (wiki.nguyenbinhson.com) liệt kê danh mục các wiki.
  • Đã live: wiki Toán tại toan.wiki.nguyenbinhson.com (project Pages wiki-nguyenbinhson, build từ quartz-site/, content copy từ toan/wiki/), và trang landing tại wiki.nguyenbinhson.com (project Pages wiki-landing, 1 trang HTML tĩnh tự viết tay, không dùng Quartz vì chỉ là danh mục liên kết).
  • Custom domain: DNS CNAME được tạo qua Cloudflare API (dns_records), trỏ subdomain/domain gốc về <project>.pages.dev tương ứng, proxied qua Cloudflare (đám mây cam).
  • Bảo mật: một Cloudflare Access Application duy nhất tên “Wiki cá nhân” bao phủ cả domain gốc lẫn wildcard subdomain (wiki.nguyenbinhson.com + *.wiki.nguyenbinhson.com) — dùng chung 1 policy “only me” (email cá nhân) cho mọi wiki con hiện tại và tương lai, thay vì tạo Access app riêng cho từng wiki. Đã xác nhận cả hai domain đều redirect (302) sang trang đăng nhập Cloudflare Access khi truy cập.
  • Vận hành API: dùng Cloudflare API token riêng (không phải token CI/CD dùng chung sẵn có trong môi trường) với 3 quyền: Zone:DNS:Edit, Account:Cloudflare Pages:Edit, Account:Access Apps and Policies:Edit. Token lưu trong file .env cục bộ (không commit git, đã thêm .env vào .gitignore của quartz-site/).
  • homelab, ai-knowledge, wiki0 hiện hiển thị “Sắp có” trên landing page — chưa build/deploy, sẽ lặp lại đúng quy trình này khi cần (build Quartz → project Pages mới → CNAME → gắn domain → thêm link vào landing page). homelab đặc biệt cần rà nội dung nhạy cảm (IP nội bộ, tunnel ID) trước khi build.

Khái niệm

Người liên quan

Câu hỏi mở

  • Wiki con nào (wiki0, homelab, ai-knowledge, toan) sẽ được chọn để public trước, và cần rà/lọc nội dung nhạy cảm nào trước khi build?
  • Build Quartz chạy ở đâu khi triển khai thật — local hay trên Pi — và ai/cái gì kích hoạt wrangler pages deploy mỗi lần wiki cập nhật (thủ công hay có script/cron)?