Website được thiết kế tối ưu cho thành viên chính thức. Hãy Đăng nhập hoặc Đăng ký để truy cập đầy đủ nội dung và chức năng. Nội dung bạn cần không thấy trên website, có thể do bạn chưa đăng nhập. Nếu là thành viên của website, bạn cũng có thể yêu cầu trong nhóm Zalo "CNTT" các nội dung bạn quan tâm.

2. Kiến trúc tổng thể hệ thống Web Server sẽ triển khai

ICT

1. Vì sao phải xác định kiến trúc ngay từ đầu?

Một sai lầm rất phổ biến khi triển khai Web Server là:

Cài từng thành phần theo nhu cầu trước mắt, không có kiến trúc tổng thể.

Hệ quả thường gặp:

  • Ban đầu chạy ổn, nhưng càng về sau càng khó mở rộng

  • Mỗi lần sửa cấu hình đều lo “sập hệ thống”

  • Không dám cập nhật, không dám tối ưu

  • Khi có sự cố, không biết bắt đầu kiểm tra từ đâu

Vì vậy, trước khi cài bất kỳ gói phần mềm nào, cần xác định rõ:

  • Hệ thống sẽ được tổ chức theo mô hình nào

  • Vai trò của từng thành phần

  • Ranh giới giữa các lớp (layer)

Bài viết này đóng vai trò bản thiết kế tổng thể cho toàn bộ loạt triển khai phía sau.


2. Nguyên tắc thiết kế kiến trúc Web Server

Kiến trúc trong loạt bài này được xây dựng dựa trên các nguyên tắc sau:

  1. Đơn giản nhưng đủ dùng cho production

  2. Phù hợp với 1 server vật lý / VPS (single node)

  3. Dễ mở rộng khi cần, không khóa cứng ngay từ đầu

  4. Ưu tiên:

    • Dễ vận hành

    • Dễ debug

    • Dễ bàn giao

Kiến trúc này đã và đang được sử dụng phổ biến trong:

  • Cổng thông tin điện tử

  • Website chuyên ngành

  • Hệ thống quản trị nội bộ

  • Website bệnh viện, đơn vị sự nghiệp


3. Mô hình kiến trúc tổng thể

Hệ thống Web Server sẽ được tổ chức theo mô hình phân lớp rõ ràng như sau:

3.1. Sơ đồ logic tổng quát

Mỗi thành phần đảm nhiệm một vai trò duy nhất, tránh chồng chéo chức năng.


4. Vai trò của từng thành phần trong kiến trúc

4.1. Nginx – Lớp Web Server (Frontend)

Nginx là điểm tiếp xúc đầu tiên giữa người dùng và hệ thống.

Nhiệm vụ chính:

  • Nhận request từ Internet

  • Xử lý HTTPS / SSL

  • Phục vụ file tĩnh (HTML, CSS, JS, ảnh)

  • Chuyển request động sang PHP-FPM

  • Ghi log truy cập và lỗi

Lý do chọn Nginx:

  • Nhẹ, ổn định, hiệu năng cao

  • Cấu hình rõ ràng, dễ kiểm soát

  • Phù hợp cho môi trường nhiều website trên một server

Tất cả hệ thống website của mình hiên tại (chủ yếu dùng Drupal) đang chạy rất ổn với Nginx.


4.2. PHP-FPM – Lớp xử lý ứng dụng

PHP-FPM đảm nhiệm việc:

  • Thực thi mã PHP

  • Quản lý process PHP

  • Tách biệt rõ giữa web server và application

Ưu điểm của việc tách PHP-FPM:

  • Không để Nginx xử lý logic ứng dụng

  • Dễ giới hạn tài nguyên

  • Có thể chạy nhiều version PHP song song

Thực tế các hệ thống mình đang chạy ở nhiều phiên bản khác nhau, cần các phiên bản PHP khác nhau. Nên mình cài nhiều phiên bản PHP. Khi cấu hình Nginx với mỗi site/domain sẽ xác định dùng phiên bản PHP nào.

Trong kiến trúc này:

  • Nginx không chạy PHP

  • PHP-FPM không expose trực tiếp ra Internet


4.3. MySQL / MariaDB – Lớp dữ liệu

Database được đặt ở lớp cuối cùng, với nguyên tắc:

  • Không truy cập trực tiếp từ Internet

  • Chỉ cho phép kết nối từ localhost hoặc service nội bộ

  • Phân quyền chặt chẽ theo từng website

Kiến trúc này giúp:

  • Giảm bề mặt tấn công

  • Dễ backup và phục hồi

  • Dễ tách database sang server khác khi cần

Mình dùng MariaDB cho tất cả các sites. Và chạy ổn.


5. Tổ chức nhiều website trên cùng một Web Server

Hệ thống sẽ được thiết kế để:

  • Một server → nhiều domain

  • Mỗi website có:

    • Virtual host riêng

    • Thư mục source riêng

    • Database riêng

    • User database riêng

Nguyên tắc:

  • Không dùng chung database

  • Không dùng chung thư mục source

  • Hạn chế tối đa ảnh hưởng chéo khi có sự cố

Với nhiều hệ thống mạnh, đặc biệt drupal việc share code (multisites) cực kỳ mạnh. Giúp hệ thống ổn định, tạo sites mới cũng như bảo trì vận hành sau này. Mình đang sử dụng mulsites cho các nhóm web/app giống nhau.


6. Phân tách rõ môi trường cấu hình

Ngay trên một server, kiến trúc vẫn được tổ chức theo tư duy:

  • Cấu hình hệ điều hành

  • Cấu hình web server

  • Cấu hình ứng dụng

  • Cấu hình dữ liệu

Điều này giúp:

  • Dễ sao chép cấu hình sang server khác

  • Dễ viết script tự động hóa

  • Dễ kiểm soát thay đổi (change management)

Các cấu hình này đều cần backup định kỳ. Thực tế việc sử dụng để restore rất ít. Nhưng rất cần khi muốn tra cứu, xem lại để triển khai hệ thống mới, tương tự.


7. Vì sao chưa dùng Docker ngay từ đầu?

Trong loạt bài này:

  • Giai đoạn đầu không dùng Docker

  • Ưu tiên hiểu rõ hệ thống chạy như thế nào ở mức OS

Lý do:

  • Docker là công cụ tốt, nhưng không thay thế kiến thức nền

  • Khi có sự cố production, vẫn phải quay về:

    • Log

    • Process

    • Network

    • File cấu hình

Docker sẽ được giới thiệu ở giai đoạn sau, khi:

  • Kiến trúc đã rõ

  • Nhu cầu nhân bản / chuẩn hóa xuất hiện

Thực tế, hệ thống nào đã chạy lâu dài, ổn định, mình đã đưa vào docker hết. Nhưng hệ thống mới mình vẫn để ở mức OS.


8. Kiến trúc này có thể mở rộng như thế nào?

Khi hệ thống lớn hơn, kiến trúc này cho phép:

  • Tách database sang server riêng

  • Thêm cache (Redis, Memcached)

  • Thêm reverse proxy / load balancing

  • Kết hợp Docker hoặc CI/CD

Quan trọng nhất:

Không cần phá bỏ kiến trúc cũ để mở rộng

Nhu cầu cần nhất có thể là dual server, ngoài cân bằng tải còn có thể backup khi 1 server gặp sự cố.


9. Liên hệ với các bài triển khai phía sau

Toàn bộ các bài tiếp theo đều dựa trên kiến trúc đã xác định ở đây:

  • Cài Ubuntu/Debian: phục vụ lớp nền

  • Cài Nginx: lớp frontend

  • Cài PHP-FPM: lớp application

  • Cài database: lớp dữ liệu

  • SSL, backup, giám sát: lớp vận hành

Nếu bỏ qua bài này, rất dễ:

  • Cài sai vai trò

  • Cấu hình chồng chéo

  • Khó debug về sau

Bạn cần xác định rõ kiến trúc tổng thể để bắt đầu nhé. Loạt bài này được soạn khi mình cài 1 server mới, độc lập để chạy web trước. Sau khi ổn định sẽ có các cài đặt chuyên sâu hơn với các nhu cầu phức tạp hơn.