Back to blog

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

nextjsreactpostgresqldockervps
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 + ShadCN ThemeProvider
  • 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-remote với React Server Components
  • gray-matter cho 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-kit và drizzle.config.ts
  • Thiết kế schema: post_views, subscribers, comments (tùy chọn)
  • Chạy migration với drizzle-kit generate và 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 useState vs 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 Dockerfile cho Next.js standalone build
  • docker-compose.yml — service app + db cho local dev
  • docker-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, ufw firewall, 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 .blog trên Hostinger
  • Hướng dẫn quản lý DNS trên Hostinger
  • Thêm A record 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.blog và www.chanh.blog
  • Nginx redirect từ www sang 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ầngCông NghệMục Đích
FrameworkNext.js 16 (App Router)Routing, SSR, metadata, API routes
UIShadCN/UI + Tailwind CSSComponents và styling
Nội dungMDX + next-mdx-remoteĐịnh dạng và render bài viết
Frontmattergray-matterParse metadata bài viết (title, date, tags)
Syntax highlightingrehype-pretty-code + ShikiCode block với hỗ trợ theme
DatabasePostgreSQL 17Lượt xem, subscriber, bình luận
ORMDrizzle ORM + drizzle-kitType-safe SQL, migration
Container hóaDocker + Docker ComposeLocal dev và production
Reverse proxyNginxĐịnh tuyến HTTPS traffic sang Next.js
SSLCertbot (Let's Encrypt)Chứng chỉ HTTPS miễn phí
HostingHostinger KVM VPSMáy chủ Ubuntu 24.04
Tên miềnHostinger DomainsĐăng ký và DNS cho chanh.blog
Themenext-themesToggle 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ầnBàiTrọng Tâm
1BLOG-1, BLOG-2Thiết lập dự án và design system
2BLOG-3, BLOG-4MDX content + database
3BLOG-5, BLOG-6, BLOG-7, BLOG-8Tí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ầnBàiTrọng Tâm
1BLOG-1, BLOG-6Tổng quan + nền tảng Docker
2BLOG-7, BLOG-8Deploy VPS + thiết lập tên miền
3BLOG-2, BLOG-3, BLOG-4, BLOG-5Tí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àyBàiTrọng Tâm
1BLOG-1Hiểu toàn bộ bức tranh
2-3BLOG-2Thiết lập Next.js + ShadCN/UI
4-5BLOG-3MDX rendering
6-7BLOG-4PostgreSQL + Drizzle
8BLOG-5Tags, tìm kiếm, phân trang
9BLOG-6Docker Compose
10BLOG-7Deploy VPS + Nginx + SSL
11BLOG-8Thiế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.x

VS 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:


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, www redirect

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àiTiêu ĐềTrạng Thái
BLOG-1Xây Dựng Blog Cá Nhân — Lộ Trình✅ Bạn đang ở đây
BLOG-2Phase 1: Thiết Lập Dự Án — Next.js 16 + ShadCN/UI✅ Hoàn Thành
BLOG-3Phase 2: MDX On-Demand Rendering✅ Hoàn Thành
BLOG-4Phase 3: PostgreSQL + Drizzle ORM✅ Hoàn Thành
BLOG-5Phase 4: Tags, Search & Pagination✅ Hoàn Thành
BLOG-6Phase 5: Docker Compose✅ Hoàn Thành
BLOG-7Phase 6: Deploy lên Ubuntu VPS trên Hostinger✅ Hoàn Thành
BLOG-8Phase 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.