Xây Dựng Blog Cá Nhân: Lộ Trình Hoàn Chỉnh

Chào mừng đến với series Xây Dựng Blog Cá Nhân! Lộ trình 8 bài này hướng dẫn bạn tạo một blog đầy đủ tính năng, tự host từ một thư mục trống đến một website hoạt động với tên miền riêng — mà không cần dựa vào Vercel, Netlify hay bất kỳ platform được quản lý nào.
Bạn sở hữu server. Bạn sở hữu tên miền. Bạn sở hữu dữ liệu.
Tại Sao Nên Tự Xây Dựng Blog?
Các platform như Hashnode, Dev.to và Medium rất tốt để bắt đầu. Nhưng đến một lúc nào đó, việc sở hữu nội dung và hạ tầng trở nên quan trọng:
✅ Toàn quyền kiểm soát — nội dung của bạn, thiết kế của bạn, luật chơi của bạn. Không có platform nào có thể thay đổi layout, giới hạn storage hay đóng cửa
✅ Tên miền riêng — chanh.blog thay vì chanh.hashnode.dev. Trông chuyên nghiệp, xây dựng thương hiệu cá nhân
✅ Không bị khóa vào vendor — bài viết của bạn là các file MDX thuần có thể chuyển đi bất cứ đâu
✅ Kỹ năng thực tế — Docker, Nginx, SSL, quản lý VPS, DNS — những thứ bạn sẽ cấu hình cho ứng dụng production
✅ Chi phí hợp lý — Hostinger KVM VPS bắt đầu từ ~$5-7/tháng. Không tính phí theo người dùng, không giới hạn traffic
✅ Portfolio ấn tượng — bản thân blog thể hiện kỹ năng full-stack, DevOps và hạ tầng
✅ Tích hợp PostgreSQL — theo dõi lượt xem bài viết, quản lý subscriber, lưu trữ bình luận — tính năng cơ sở dữ liệu thực mà platform không cung cấp
Bạn Sẽ Xây Dựng Gì?
Kết thúc series này, bạn sẽ có một blog production với:
- Next.js 16 App Router — file-based routing, Server Components, metadata API
- ShadCN/UI — các component đẹp, có accessibility dựa trên Radix UI và Tailwind CSS
- MDX on-demand rendering — viết bài bằng Markdown + JSX, render lúc có request
- PostgreSQL + Drizzle ORM — theo dõi lượt xem, quản lý subscriber, migration schema
- Hệ thống tag, tìm kiếm và phân trang — giúp độc giả khám phá nội dung
- Docker Compose — môi trường dev và production nhất quán
- Ubuntu VPS trên Hostinger — toàn quyền kiểm soát, ~$5-7/tháng
- Nginx reverse proxy + SSL — HTTPS qua Let's Encrypt (miễn phí)
- Tên miền riêng —
chanh.blogđược đăng ký và cấu hình trên Hostinger
Cấu Trúc Lộ Trình Hoàn Chỉnh
Bài #1: Xây Dựng Blog Cá Nhân — Lộ Trình (Tổng Quan) ✅ Bạn đang ở đây
- Tại sao tự host thay vì dùng platform
- Tổng quan full stack và kiến trúc
- Cấu trúc series với tất cả 8 bài
- Yêu cầu trước và thiết lập dev local
Phase 1: Nền Tảng
Bài #2: Phase 1 — Thiết Lập Dự Án: Next.js 16 + ShadCN/UI
Nội dung:
- Scaffold với
create-next-app— TypeScript, Tailwind, App Router - Cấu trúc thư mục dự án (
app/,components/,lib/,content/) - Cài đặt và cấu hình ShadCN/UI
- Xây dựng Header, Footer và responsive mobile nav với Sheet
- Dark/light theme với
next-themes+ ShadCNThemeProvider - Cấu hình
next/fontđể tải font không bị layout shift - Site metadata với
generateMetadata()
Kết Quả Học Tập:
✅ Scaffold dự án Next.js 16 App Router với TypeScript và Tailwind
✅ Cài đặt và sử dụng ShadCN/UI components
✅ Xây dựng responsive layout với dark mode
✅ Cấu hình SEO metadata cho site
Thời Gian Ước Tính: 2-3 ngày
Bài #3: Phase 2 — MDX On-Demand Rendering
Nội dung:
- MDX là gì và tại sao tuyệt vời cho blog
- Trade-off giữa on-demand rendering và static generation
next-mdx-remotevới React Server Componentsgray-mattercho frontmatter (title, date, tags, description)- Syntax highlighting với
rehype-pretty-code+ Shiki - GitHub Flavored Markdown với
remark-gfm - Xây dựng trang
/blog— đọc tất cả file MDX - Xây dựng
/blog/[slug]— biên dịch MDX on-demand - Custom MDX components và TypeScript types cho frontmatter
Kết Quả Học Tập:
✅ Thiết lập MDX với on-demand server-side rendering
✅ Parse frontmatter và render metadata bài viết
✅ Thêm syntax highlighting hỗ trợ dark/light mode
✅ Xây dựng trang danh sách blog và trang chi tiết bài viết
Thời Gian Ước Tính: 2-3 ngày
Bài #4: Phase 3 — Tích Hợp PostgreSQL + Drizzle ORM
Nội dung:
- Tại sao thêm database bên cạnh MDX (cách tiếp cận hybrid)
- PostgreSQL trong Docker cho local development
- Drizzle ORM vs Prisma vs TypeORM — tại sao chọn Drizzle
- Thiết lập
drizzle-orm+drizzle-kitvàdrizzle.config.ts - Thiết kế schema:
post_views,subscribers,comments(tùy chọn) - Chạy migration với
drizzle-kit generatevàmigrate - Đếm lượt xem bài viết qua Server Action hoặc API Route
- Quản lý newsletter subscriber
- Environment variables và
DATABASE_URL
Kết Quả Học Tập:
✅ Kết nối Next.js với PostgreSQL qua Drizzle ORM
✅ Thiết kế và migrate database schema
✅ Xây dựng bộ đếm lượt xem bài viết
✅ Quản lý newsletter subscriber trong database
Thời Gian Ước Tính: 2-3 ngày
Phase 2: Tính Năng
Bài #5: Phase 4 — Tags, Search & Pagination
Nội dung:
- Trích xuất tag từ MDX frontmatter
- Trang index tag tại
/blog/tags/[tag] - ShadCN/UI Badge để hiển thị tag
- Tìm kiếm phía client với
useStatevs phía server với?q=param - Phân trang — chia mảng bài viết, điều khiển prev/next
- ShadCN/UI Pagination component
- Tính thời gian đọc
- Sắp xếp bài viết theo ngày và theo lượt xem
- SEO: metadata cho trang tag
Kết Quả Học Tập:
✅ Xây dựng hệ thống tag với trang tag riêng
✅ Implement tìm kiếm với URL-based state
✅ Thêm phân trang cho danh sách blog
✅ Hiển thị thời gian đọc và sắp xếp bài viết
Thời Gian Ước Tính: 2-3 ngày
Phase 3: Hạ Tầng
Bài #6: Phase 5 — Docker Compose cho Local Dev & Production
Nội dung:
- Tại sao Docker quan trọng ngay cả với blog cá nhân
- Multi-stage
Dockerfilecho Next.js standalone build docker-compose.yml— serviceapp+dbcho local devdocker-compose.prod.yml— production overrides (restart, logging)- Chạy Drizzle migration trong Docker khi khởi động
- Best practice
.dockerignore - Health check cho Postgres và Next.js
- Quản lý environment variable trên các môi trường
Kết Quả Học Tập:
✅ Dockerize ứng dụng Next.js với multi-stage build
✅ Chạy Next.js + PostgreSQL cục bộ với Docker Compose
✅ Viết Docker Compose overrides cho production
✅ Tự động chạy database migration trong Docker
Thời Gian Ước Tính: 2-3 ngày
Bài #7: Phase 6 — Deploy lên Ubuntu VPS trên Hostinger
Nội dung:
- Chọn gói Hostinger VPS phù hợp (KVM 1 vs KVM 2)
- Thiết lập ban đầu Ubuntu 24.04: SSH keys,
ufwfirewall,fail2ban - Cài đặt Docker và Docker Compose trên Ubuntu
- Clone repo, thiết lập
.env.production - Deploy production với Docker Compose
- Nginx reverse proxy: định tuyến traffic từ port 80/443 sang Next.js
- SSL certificate với Certbot (Let's Encrypt) — HTTPS miễn phí
- Workflow re-deploy không có downtime
- Đọc log với
docker compose logs -f
Kết Quả Học Tập:
✅ Provision và bảo mật Ubuntu VPS trên Hostinger
✅ Cài đặt Docker và deploy với Docker Compose
✅ Cấu hình Nginx làm reverse proxy
✅ Thiết lập HTTPS miễn phí với Let's Encrypt
Thời Gian Ước Tính: 3-4 ngày
Bài #8: Phase 7 — Cấu Hình Tên Miền Riêng trên Hostinger
Nội dung:
- Đăng ký tên miền
.blogtrên Hostinger - Hướng dẫn quản lý DNS trên Hostinger
- Thêm
Arecord cho apex vàwww - DNS propagation — những gì cần biết và cách kiểm tra
- SSL certificate bao gồm cả
chanh.blogvàwww.chanh.blog - Nginx redirect từ
wwwsang apex domain - Kiểm tra end-to-end — HTTPS, trang bài viết, tìm kiếm
- Tùy chọn: Cloudflare DNS proxy để bảo vệ DDoS
- Checklist sau khi ra mắt: Google Search Console, sitemap, OG preview
Kết Quả Học Tập:
✅ Đăng ký và cấu hình tên miền riêng
✅ Thiết lập DNS record và kiểm tra propagation
✅ Redirect www sang apex domain
✅ Gửi site lên Google Search Console
Thời Gian Ước Tính: 1-2 ngày
Kiến Trúc Full Stack Hoàn Chỉnh
Đây là cách tất cả các phần kết nối trong blog cuối cùng:
Tổng Quan Tech Stack
| Tầng | Công Nghệ | Mục Đích |
|---|---|---|
| Framework | Next.js 16 (App Router) | Routing, SSR, metadata, API routes |
| UI | ShadCN/UI + Tailwind CSS | Components và styling |
| Nội dung | MDX + next-mdx-remote | Định dạng và render bài viết |
| Frontmatter | gray-matter | Parse metadata bài viết (title, date, tags) |
| Syntax highlighting | rehype-pretty-code + Shiki | Code block với hỗ trợ theme |
| Database | PostgreSQL 17 | Lượt xem, subscriber, bình luận |
| ORM | Drizzle ORM + drizzle-kit | Type-safe SQL, migration |
| Container hóa | Docker + Docker Compose | Local dev và production |
| Reverse proxy | Nginx | Định tuyến HTTPS traffic sang Next.js |
| SSL | Certbot (Let's Encrypt) | Chứng chỉ HTTPS miễn phí |
| Hosting | Hostinger KVM VPS | Máy chủ Ubuntu 24.04 |
| Tên miền | Hostinger Domains | Đăng ký và DNS cho chanh.blog |
| Theme | next-themes | Toggle dark/light mode |
Lộ Trình Học
Lộ Trình A: Frontend-First (2-3 tuần)
Dành cho developer quen với React nhưng chưa biết về hạ tầng.
| Tuần | Bài | Trọng Tâm |
|---|---|---|
| 1 | BLOG-1, BLOG-2 | Thiết lập dự án và design system |
| 2 | BLOG-3, BLOG-4 | MDX content + database |
| 3 | BLOG-5, BLOG-6, BLOG-7, BLOG-8 | Tính năng + deployment |
Lộ Trình B: DevOps-First (2-3 tuần)
Dành cho developer muốn hiểu hạ tầng trước khi xây dựng app.
| Tuần | Bài | Trọng Tâm |
|---|---|---|
| 1 | BLOG-1, BLOG-6 | Tổng quan + nền tảng Docker |
| 2 | BLOG-7, BLOG-8 | Deploy VPS + thiết lập tên miền |
| 3 | BLOG-2, BLOG-3, BLOG-4, BLOG-5 | Tính năng ứng dụng |
Lộ Trình C: Tuyến Tính (8-10 ngày)
Làm theo thứ tự các bài — một bài mỗi ngày.
| Ngày | Bài | Trọng Tâm |
|---|---|---|
| 1 | BLOG-1 | Hiểu toàn bộ bức tranh |
| 2-3 | BLOG-2 | Thiết lập Next.js + ShadCN/UI |
| 4-5 | BLOG-3 | MDX rendering |
| 6-7 | BLOG-4 | PostgreSQL + Drizzle |
| 8 | BLOG-5 | Tags, tìm kiếm, phân trang |
| 9 | BLOG-6 | Docker Compose |
| 10 | BLOG-7 | Deploy VPS + Nginx + SSL |
| 11 | BLOG-8 | Thiết lập tên miền + ra mắt |
Yêu Cầu Trước
Series này yêu cầu:
- JavaScript / TypeScript cơ bản — biến, hàm, async/await, types
- Kiến thức React cơ bản — components, props, useState (mức nông cũng được)
- Quen với command line —
npm install,git, điều hướng thư mục - Một code editor — VS Code được khuyến nghị
- Không cần kinh nghiệm Docker hay VPS trước — chúng ta bắt đầu từ đầu
Bạn KHÔNG cần kinh nghiệm với Next.js, PostgreSQL, hay bất kỳ công cụ hạ tầng nào. Mỗi bài bắt đầu từ zero.
Thiết Lập Development
Trước khi bắt đầu Bài #2, hãy cài đặt các công cụ này:
# Node.js 20+ (dùng nvm để quản lý version dễ dàng)
nvm install 20
nvm use 20
# Kiểm tra version
node --version # v20.x.x
npm --version # 10.x.x
# Docker Desktop (bao gồm Docker Compose)
# Tải tại: https://www.docker.com/products/docker-desktop/
# Kiểm tra Docker
docker --version # Docker 27.x.x
docker compose version # Docker Compose v2.x.xVS Code Extensions Được Khuyến Nghị:
- Tailwind CSS IntelliSense — autocomplete cho Tailwind classes
- Prettier — định dạng code nhất quán
- ESLint — bắt lỗi khi gõ
- MDX — syntax highlighting cho file
.mdx - Docker — quản lý container từ VS Code
Tại Sao Chọn Những Công Nghệ Này?
Next.js 16 thay vì React thuần
React là UI library. Next.js thêm mọi thứ mà blog cần: routing, server rendering, image optimization, metadata management và con đường deploy rõ ràng. App Router (ra mắt trong Next.js 13) làm server-side rendering là mặc định — các trang nhanh mà không cần cấu hình thêm.
ShadCN/UI thay vì thư viện component khác
ShadCN/UI không phải thư viện component truyền thống — bạn copy component vào dự án và sở hữu chúng. Không xung đột version, không bloat node_modules, không theming cứng nhắc không thể override. Được xây trên Radix UI (có accessibility) và Tailwind CSS (utility-first). Trông đẹp ngay từ đầu.
MDX thay vì CMS
MDX cho phép bạn viết bài blog dưới dạng file Markdown với JSX components nhúng. Bài viết nằm trong git repository — có version, portable và tìm kiếm được. Không có API call đến CMS, không bị khóa vào vendor, không mất phí CMS hàng tháng. On-demand rendering có nghĩa là bạn không cần build lại sau mỗi bài viết.
Drizzle ORM thay vì Prisma
Drizzle nhẹ hơn, TypeScript-first và generate SQL bạn có thể đọc. Schema được định nghĩa trong TypeScript — không cần file .prisma riêng. Migration là SQL thuần bạn có thể kiểm tra. Drizzle cũng nhanh hơn và có footprint nhỏ hơn, quan trọng trên VPS nhỏ.
Docker Compose thay vì cài trực tiếp
Docker đảm bảo cùng một môi trường trong development và production. Nếu hoạt động trong Docker local, nó sẽ hoạt động trên VPS. Không còn vấn đề "works on my machine". Dễ dàng chuyển blog sang VPS khác hay cloud provider — chỉ cần clone và docker compose up.
Hostinger VPS thay vì Vercel
Vercel xuất sắc cho Next.js — nhưng tính phí theo thành viên team, có giới hạn bandwidth ở gói miễn phí và không cung cấp server thực. Hostinger KVM VPS cho bạn một máy Ubuntu đầy đủ với ~$5-7/tháng. PostgreSQL, Nginx, Docker — bất cứ thứ gì bạn cần. Bản thân series blog này thể hiện kỹ năng quan trọng hơn việc dùng platform được quản lý.
Câu Hỏi Thường Gặp
Tôi có thể dùng hosting provider khác không? Có. Bài #7 và #8 dùng Hostinger, nhưng thiết lập Docker + Nginx + Certbot hoạt động trên bất kỳ Ubuntu VPS nào — DigitalOcean, Hetzner, Linode, Vultr, v.v.
Tôi có thể dùng Vercel thay vì VPS không? Có cho ứng dụng Next.js, nhưng bạn cần một PostgreSQL host riêng (Neon, Supabase) và bỏ qua các phần Docker và Nginx. Series được thiết kế xung quanh self-hosting, nhưng code ứng dụng cũng hoạt động trên Vercel.
Tôi có cần mua tên miền .blog không?
Không. Bạn có thể dùng bất kỳ tên miền nào (.com, .dev, .io) từ bất kỳ nhà đăng ký nào. Bài #7 và #8 dùng Hostinger vì VPS và tên miền ở cùng một nơi, nhưng thiết lập DNS giống nhau ở mọi nơi.
Nếu tôi đã biết Docker thì sao?
Bạn có thể đi qua Bài #6 nhanh hơn. Tập trung vào các pattern đặc thù Next.js (standalone build, output: 'standalone') và thiết lập Drizzle migration.
Tôi có thể deploy lên subdomain thay vì apex domain không?
Có — blog.chanh.dev thay vì chanh.blog. Cấu hình Nginx và DNS record thay đổi một chút, nhưng quy trình giống hệt nhau.
Bài Viết & Series Liên Quan
Series này xây dựng trên và kết nối với:
- Lộ Trình Học React.js & Next.js — đi sâu hơn vào các khái niệm React và Next.js
- Lộ Trình Docker & Kubernetes — Docker và container orchestration toàn diện
- Lộ Trình SQL & NoSQL Database — nền tảng database và thiết kế
- Lộ Trình TypeScript Full-Stack — TypeScript patterns dùng xuyên suốt series này
- Nền Tảng Cơ Sở Dữ Liệu Quan Hệ — khái niệm PostgreSQL và thiết kế schema
- Bun + Hono + Neon + Upstash: Full Stack API trên Vercel — cách tiếp cận serverless thay thế
Tóm Tắt
Xây dựng blog cá nhân là một trong những dự án full-stack hoàn chỉnh nhất bạn có thể làm. Nó chạm đến mọi tầng của stack:
- Frontend: React components, ShadCN/UI, dark mode, responsive design
- Nội dung: MDX rendering, frontmatter, syntax highlighting
- Backend: PostgreSQL schema, Drizzle ORM, API routes, Server Actions
- Hạ tầng: Docker Compose, Nginx, SSL, Ubuntu VPS
- Tên miền: DNS record, HTTPS,
wwwredirect
Kết thúc series này, bạn sẽ có một blog production thực sự chạy trên server của mình với tên miền riêng — và bạn sẽ hiểu mọi dòng hạ tầng giữ nó hoạt động.
Bắt đầu với Bài #2: Phase 1 — Thiết Lập Dự Án: Next.js 16 + ShadCN/UI
Mục Lục Series
| Bài | Tiêu Đề | Trạng Thái |
|---|---|---|
| BLOG-1 | Xây Dựng Blog Cá Nhân — Lộ Trình | ✅ Bạn đang ở đây |
| BLOG-2 | Phase 1: Thiết Lập Dự Án — Next.js 16 + ShadCN/UI | ✅ Hoàn Thành |
| BLOG-3 | Phase 2: MDX On-Demand Rendering | ✅ Hoàn Thành |
| BLOG-4 | Phase 3: PostgreSQL + Drizzle ORM | ✅ Hoàn Thành |
| BLOG-5 | Phase 4: Tags, Search & Pagination | ✅ Hoàn Thành |
| BLOG-6 | Phase 5: Docker Compose | ✅ Hoàn Thành |
| BLOG-7 | Phase 6: Deploy lên Ubuntu VPS trên Hostinger | ✅ Hoàn Thành |
| BLOG-8 | Phase 7: Cấu Hình Tên Miền Riêng trên Hostinger | ✅ Hoàn Thành |
📬 Đăng ký nhận bản tin
Nhận những bài viết mới nhất qua email mỗi tuần. Không spam, hủy đăng ký bất cứ lúc nào.
Chúng tôi tôn trọng quyền riêng tư của bạn. Hủy đăng ký bất cứ lúc nào.
💬 Comments
Đăng nhập để bình luận
Chúng tôi sẽ không đăng bất cứ điều gì mà không có sự cho phép của bạn.