127.0.0.1 SỔ TAY VẬN HÀNH MÁY CHỦ & CỨU HỘ WORDPRESS THỰC CHIẾN
MINH BẠCH

Cấu hình Virtual Host (Server Block) NGINX cho domain và www: Chia phòng chuẩn chỉnh, không lo khách vào nhầm nhà

Hướng dẫn cấu hình Virtual Host (Server Block) NGINX cho domain chính và www: tạo web root, kiểm tra Host header, cú pháp nginx -t và cách rollback.

Hosting & WordPress // localhost.vn
Mục lục bài viết (10 mục)
ĐÚC KẾT THỰC CHIẾN

DNS chỉ là anh tài xế chở khách đến đúng cổng tòa nhà VPS, còn Server Block của NGINX mới là lễ tân nhìn bảng tên Host header để dẫn khách vào đúng căn hộ website.

Phạm vi thực hành: Cấu hình mẫu HTTP cổng 80 dưới đây được thiết kế cho giai đoạn khởi tạo website mới trên Ubuntu 24.04 LTS, trước khi cài đặt mã nguồn WordPress. Do máy chủ LAB-CF-02 đã có sẵn website WordPress đang vận hành, chúng tôi tuyệt đối không ghi đè file HTML thử nghiệm vào thư mục /var/www/lab-cf02 hay sửa trực tiếp Virtual Host đang chạy. Đợt thực nghiệm ngày 01/10 sử dụng thư mục gốc và file cấu hình tách biệt với hai tên miền đuôi .test lắng nghe nội bộ tại 127.0.0.1:8082; số liệu được tổng hợp ở phần cuối bài. Tiếp đó, vào ngày 02/10, chúng tôi đã thực nghiệm thêm với hai tên miền công khai độc lập là vhost-cf02.localhost.vn và www.vhost-cf02.localhost.vn kèm chứng chỉ HTTPS và chuyển hướng 301, rồi thu dọn sạch sẽ sau khi nghiệm thu.

Hãy tưởng tượng chiếc VPS của bạn giống như một tòa chung cư cao tầng, và địa chỉ IP chính là số nhà ngoài mặt phố. Bản ghi DNS chỉ làm nhiệm vụ chở khách đến đúng cổng tòa nhà đó, nhưng làm sao để biết vị khách này muốn lên căn hộ A hay căn hộ B? Đó chính là lúc bạn cần cấu hình Virtual Host NGINX (trong thuật ngữ chính thức của NGINX thì gọi là Server Block). Khi trình duyệt gửi yêu cầu tới IP máy chủ, nó luôn đính kèm một tấm danh thiếp gọi là Host header, và NGINX sẽ đối chiếu tấm danh thiếp này với chỉ thị server_name để mở đúng cửa website tương ứng. Hiểu được cơ chế này, bạn sẽ không còn hoang mang khi thấy gõ địa chỉ IP thì ra trang chào mừng mặc định (Welcome to nginx!), còn gõ tên miền thì lại ra một giao diện hoàn toàn khác.

Chốt tên miền chính và tên miền phụ (alias www) ngay từ đầu

Trong bài hướng dẫn này, tên miền chính được sử dụng là lab-cf02.localhost.vn. Bạn chỉ nên đưa thêm bí danh www.lab-cf02.localhost.vn vào cấu hình khi bạn thực sự đã tạo bản ghi DNS cho nhánh www đó và có ý định phục vụ người dùng qua cả hai đường. Đừng nhầm lẫn giữa www.lab-cf02.localhost.vn với tên miền gốc www.localhost.vn nhé, và nhớ nguyên tắc bất di bất dịch: không bao giờ lôi tên miền đang chạy sản phẩm thật (production) vào file cấu hình thử nghiệm.

Trước khi bắt tay vào gõ lệnh, hãy đảm bảo dịch vụ NGINX đang chạy ổn định, tên miền thử nghiệm đã trỏ DNS đúng về IP máy chủ và cổng TCP 80 đã được mở thông suốt. Ở chặng này, chúng ta chỉ mới dựng một trang HTML tĩnh đơn giản để kiểm tra luồng điều hướng chứ chưa hề đăng nhập hay truyền mật khẩu quản trị WordPress qua giao thức HTTP thuần. Việc thiết lập mã hóa HTTPS trước khi đăng nhập sẽ được giải quyết ở Bài 37, còn quy trình quản lý và gia hạn chứng chỉ tự động sẽ nằm ở Bài 43.

Thói quen tốt của một kỹ sư hệ thống già dặn là luôn chạy lệnh ls -l /etc/nginx/sites-enabled/ để ngó xem những website nào đang hoạt động trên máy chủ, tránh trường hợp khai báo trùng lặp server_name gây tranh chấp. Nếu cần chỉnh sửa bất kỳ file cấu hình sẵn có nào, hãy tạo một bản sao lưu (backup) cất ở thư mục riêng bên ngoài web root. Toàn bộ các bước dưới đây dành cho việc tạo mới hoàn toàn một website độc lập: nếu hệ thống báo thư mục gốc, file cấu hình hay đường dẫn liên kết mềm (symlink) đã tồn tại, bạn hãy dừng lại kiểm tra hiện trạng chứ đừng nhắm mắt xóa đè lên website đang chạy.

Sơ đồ dns và virtual host: DNS chọn địa chỉ máy; Host chọn server block; Root chọn thư mục; Index chọn trang đầu

Sơ đồ minh họa hành trình của một request từ lớp phân giải DNS vào đến đúng thư mục gốc của Virtual Host do đội ngũ localhost.vn biên soạn.

Bước 1: Tạo thư mục chứa mã nguồn (Web Root) riêng biệt cho site

(
  for vhost_path in /var/www/lab-cf02 \
    /etc/nginx/sites-available/lab-cf02 \
    /etc/nginx/sites-enabled/lab-cf02; do
    if sudo test -e "$vhost_path" || sudo test -L "$vhost_path"; then
      printf 'Dung: duong dan da ton tai: %s\n' "$vhost_path" >&2
      exit 1
    fi
  done
  sudo mkdir -m 755 -- /var/www/lab-cf02 &&
    sudoedit /var/www/lab-cf02/index.html
)

Đoạn mã trên được bọc trong cặp ngoặc đơn ( ... ) để chạy trong một tiến trình shell con (subshell). Điểm tinh tế của cách viết này là: nếu phát hiện bất kỳ đường dẫn nào đã tồn tại sẵn, lệnh exit 1 sẽ lập tức dừng thao tác để bảo vệ dữ liệu cũ mà không làm văng mất cửa sổ kết nối SSH hiện tại của bạn. Khi thấy trình soạn thảo mở ra suôn sẻ cho thư mục mới, bạn hãy dán đoạn mã HTML tối giản dưới đây vào rồi lưu lại:

<!doctype html>
<html lang="vi">
<meta charset="utf-8">
<title>Lab WordPress</title>
<h1>Lab CF02 — kiểm virtual host</h1>
<p>Đây là trang HTML thử trước khi cài WordPress.</p>
</html>

Việc đặt một dòng chữ có dấu hiệu nhận diện rõ ràng (như tên dự án hoặc mã ký hiệu lab) giúp bạn nhìn phát biết ngay NGINX đã trỏ đúng vào thư mục mới hay vẫn đang lạc trôi ở trang mặc định. Tất nhiên, đừng bao giờ ghi thông tin nhạy cảm của máy chủ, địa chỉ email cá nhân hay các chuỗi khóa bí mật vào file HTML công khai này. Theo mặc định, thư mục vừa tạo bằng mkdir -p sẽ mang quyền 755; chúng ta chỉ cần ấn định quyền 644 cho file tĩnh index.html để các tiến trình worker của NGINX đọc được một cách an toàn:

sudo test -f /var/www/lab-cf02/index.html &&
  sudo test ! -L /var/www/lab-cf02/index.html &&
  sudo chmod 644 -- /var/www/lab-cf02/index.html

Hãy nhớ chỉ áp dụng lệnh phân quyền này cho đúng file tĩnh vừa tạo sau khi đã kiểm tra kỹ đường dẫn. Tuyệt đối tránh thói quen chạy lệnh chmod -R đệ quy bừa bãi lên các thư mục website đang vận hành.

Bước 2: Khởi tạo file cấu hình Server Block cho giao thức HTTP

Sau khi đã có thư mục gốc và trang HTML mồi, chúng ta tiếp tục kiểm tra chắc chắn rằng file cấu hình trong sites-available chưa tồn tại rồi mới mở trình soạn thảo:

if sudo test -e /etc/nginx/sites-available/lab-cf02 || \
   sudo test -L /etc/nginx/sites-available/lab-cf02; then
  printf '%s\n' 'Dung: config da ton tai, can doc truoc khi sua.' >&2
else
  sudoedit /etc/nginx/sites-available/lab-cf02
fi

Dưới đây là cấu trúc một khối server chuẩn mực lắng nghe trên cổng 80 cho cả tên miền chính lẫn nhánh bí danh www:

server {
    listen 80;
    server_name lab-cf02.localhost.vn www.lab-cf02.localhost.vn;
    root /var/www/lab-cf02;
    index index.html;

    access_log /var/log/nginx/lab-cf02.access.log;
    error_log /var/log/nginx/lab-cf02.error.log;

    location / {
        try_files $uri $uri/ =404;
    }
}

Nếu dự án của bạn không có nhu cầu sử dụng nhánh www, hãy mạnh dạn lược bỏ nó khỏi dòng server_name cho gọn gàng. Tương tự, đối với chỉ thị lắng nghe IPv6 (listen [::]:80;), bạn chỉ nên thêm vào khi VPS của bạn thực sự đã được cấp phát địa chỉ IPv6 hoạt động và bạn đã trỏ bản ghi AAAA chuẩn xác. Đừng cố nhồi nhét cấu hình IPv6 theo phong trào khi hạ tầng mạng bên dưới chưa sẵn sàng.

Một lưu ý nhỏ nhưng hay gây lỗi ngớ ngẩn: chỉ thị root phải trỏ tới thư mục chứa web (/var/www/lab-cf02), tuyệt đối không viết cả tên file /var/www/lab-cf02/index.html vào dòng root. Ở giai đoạn thử nghiệm file HTML tĩnh này, dòng try_files $uri $uri/ =404; đảm bảo rằng ai gõ đường dẫn không có thật sẽ nhận về mã lỗi 404 Not Found dứt khoát. Sau này khi đưa bộ mã nguồn WordPress vào, chúng ta mới điều chỉnh quy tắc đó thành chuyển hướng các đường dẫn tĩnh (permalink) về cho index.php xử lý. Việc chia nhỏ từng bước như vậy giúp bạn khoanh vùng lỗi cực nhanh: hỏng ở tầng phục vụ file tĩnh của NGINX hay hỏng ở tầng xử lý PHP của ứng dụng.

Bước 3: Kích hoạt site qua Symlink và kiểm tra cú pháp cấu hình

sudo ln -s /etc/nginx/sites-available/lab-cf02 \
  /etc/nginx/sites-enabled/lab-cf02 &&
  sudo nginx -t

Để kích hoạt một website trên Ubuntu/Debian, chúng ta tạo một liên kết mềm (symbolic link) từ thư mục sites-available sang thư mục sites-enabled. Nếu hệ thống báo liên kết đã tồn tại, bạn hãy dùng ls -l để soi xem nó đang trỏ đi đâu chứ đừng vội thêm cờ -f để ép ghi đè. Ngay sau đó, lệnh sudo nginx -t đóng vai trò như người gác cổng: nếu bạn lỡ tay quên dấu chấm phẩy ; ở cuối dòng, đóng mở ngoặc nhọn {} lệch nhau hay gõ sai chính tả tên chỉ thị, nginx -t sẽ chỉ thẳng tên file và số dòng bị lỗi để bạn sửa ngay trước khi làm ảnh hưởng đến dịch vụ đang chạy.

Chỉ khi nào màn hình hiện dòng thông báo quen thuộc syntax is ok và test is successful, chúng ta mới ra lệnh cho NGINX nạp lại cấu hình:

sudo nginx -t && sudo systemctl reload nginx

Thao tác reload giúp NGINX áp dụng cấu hình mới một cách êm ái mà không làm đứt đoạn các kết nối hiện tại, và tất nhiên bạn hoàn toàn không cần phải khởi động lại (reboot) cả chiếc VPS chỉ vì thêm một Virtual Host. Bạn cũng cứ yên tâm giữ nguyên file cấu hình default trong môi trường lab, bởi khi có request gửi kèm Host header khớp với server_name cụ thể, NGINX sẽ luôn ưu tiên chọn đúng khối server của bạn thay vì rơi vào khối mặc định. Đừng xóa bừa file default hay các website khác trên máy chỉ vì thấy gõ IP trần vẫn hiện trang chào mừng.

Sơ đồ áp dụng cấu hình an toàn: Tạo file riêng cho lab; Bật liên kết đúng file; nginx -t trước reload; Thử tên chính và bí danh

Sơ đồ quy trình 4 bước kích hoạt cấu hình Virtual Host an toàn do đội ngũ localhost.vn biên soạn.

Bước 4: Tuyệt chiêu kiểm tra Host header bỏ qua mọi rào cản Cache DNS

Thay vì phải ngồi chờ DNS cập nhật khắp nơi, các kỹ sư dày dạn kinh nghiệm thường dùng cờ --resolve của công cụ curl. Bạn chỉ cần thay địa chỉ IP minh họa 203.0.113.10 bằng địa chỉ IP thực tế của VPS và gõ lệnh ngay trên máy tính cá nhân:

curl --resolve lab-cf02.localhost.vn:80:203.0.113.10 \
  http://lab-cf02.localhost.vn/
curl --resolve www.lab-cf02.localhost.vn:80:203.0.113.10 \
  http://www.lab-cf02.localhost.vn/

Cờ --resolve ép curl gửi thẳng gói tin HTTP đến đúng địa chỉ IP bạn chỉ định nhưng vẫn đính kèm hoàn chỉnh tấm danh thiếp Host: lab-cf02.localhost.vn. Nếu cả tên miền chính lẫn nhánh www đều trả về đúng nội dung HTML mà bạn vừa gõ ở Bước 1, xin chúc mừng: lễ tân NGINX đã nhận diện chuẩn xác căn hộ của bạn! Bước tiếp theo, bạn chỉ việc chạy lại lệnh curl bình thường (bỏ phần --resolve đi) để kiểm tra xem hệ thống DNS công cộng ngoài đời thực đã dẫn khách về đúng địa chỉ IP đó hay chưa.

Ngoài đường dẫn trang chủ /, hãy thử gõ thêm một đường dẫn không có thật như /khong-co-trang-nay để xác nhận máy chủ trả về đúng mã lỗi 404. Nếu chẳng may thấy nội dung của một website khác trên cùng máy chủ hiện ra, hãy rà soát lại ngay xem có bị trùng server_name, lệch cổng listen hay nhầm địa chỉ IP đích hay không. Bạn cũng nên mở file nhật ký truy cập /var/log/nginx/lab-cf02.access.log để tận mắt thấy dòng log ghi nhận request vừa đi vào đúng căn hộ của mình.

Chọn định dạng URL chuẩn (Canonical) và lưu ý quan trọng về nhánh www

Ở bước dựng khung ban đầu, việc để cả tên miền không có www và có www cùng hiển thị chung một file HTML là cách rất tốt để kiểm tra kết nối. Tuy nhiên, trước khi chính thức đưa website vào hoạt động hoặc cài đặt WordPress, bạn nên chọn dứt khoát một địa chỉ làm tên miền chính (Canonical URL) và cấu hình chuyển hướng cố định (301 Moved Permanently) từ nhánh còn lại về địa chỉ chính đó. Một kinh nghiệm xương máu: hãy đợi đến khi bạn cài đặt xong chứng chỉ SSL/TLS và mở thông cổng 443 rồi mới bật chuyển hướng sang HTTPS. Đừng quên rằng nếu người dùng gõ https://www.ten-mien.com, quá trình bắt tay bảo mật TLS sẽ diễn ra trước khi máy chủ kịp trả về lệnh chuyển hướng 301 — nghĩa là chứng chỉ SSL của bạn bắt buộc phải bao phủ hợp lệ cho cả tên miền chính lẫn nhánh www.

Thêm một chi tiết kỹ thuật mà nhiều người dùng Cloudflare hay vấp phải: chứng chỉ Universal SSL miễn phí ở tầng Proxy mặc định chỉ bảo vệ tên miền gốc (localhost.vn) và một cấp tên miền con (*.localhost.vn). Nếu bạn dùng tên miền con nhiều cấp kiểu như www.lab-cf02.localhost.vn và bật đám mây cam của Cloudflare, trình duyệt có thể báo lỗi không khớp chứng chỉ SSL ở tầng biên. Vì thế, với các môi trường thử nghiệm dạng subdomain, nếu không thực sự cần tới nhánh www.lab-cf02 thì bạn chỉ cần dùng một tên miền đơn lab-cf02.localhost.vn là vừa gọn nhẹ vừa đỡ đau đầu chuyện chứng chỉ đa cấp.

Sơ đồ khi thấy trang sai: Kiểm IP origin; Kiểm server_name; Kiểm root và quyền; Đối chiếu access log

Sơ đồ các bước khoanh vùng nguyên nhân khi trình duyệt hiển thị sai trang web mong muốn do đội ngũ localhost.vn biên soạn.

Kết quả thực nghiệm định tuyến Host nội bộ trên LAB-CF-02

Vào lúc 03:31:12 đến 03:31:13 ngày 01/10/2026 (giờ Việt Nam), chúng tôi đã tiến hành kiểm tra cơ chế phân luồng của NGINX 1.24.0 (Ubuntu) bằng một cấu hình và thư mục HTML độc lập, chỉ lắng nghe nội bộ tại địa chỉ loopback 127.0.0.1:8082. Hai tên miền vhost-cf02.test và www.vhost-cf02.test được truyền trực tiếp qua trường Host header mà không cần tạo bản ghi DNS công khai:

Kịch bản thực nghiệm Kết quả ghi nhận thực tế
Truy vấn hai tên miền đã khai báo trong server_name Cả hai đều trả về mã 200 OK, dung lượng HTML đúng 105 byte và trùng khớp mã băm SHA-256
Truy vấn một tên miền lạ không có trong danh sách Khối default_server của cổng thử nghiệm lập tức trả về mã 404 kèm thông điệp unknown host
Truy vấn đúng Host nhưng gõ đường dẫn file không tồn tại Trả về mã lỗi chuẩn 404 Not Found
Hạ quyền file HTML thử nghiệm xuống 000 Trả về mã lỗi 403 Forbidden; đồng thời file error log ghi nhận rõ dòng Permission denied
Khôi phục quyền file HTML về mức chuẩn 644 Lập tức trả về mã 200 OK cùng nội dung HTML nguyên vẹn như ban đầu
Kiểm tra một file cấu hình cố tình viết sai cú pháp bằng nginx -t -c Trả về mã thoát 1 kèm báo lỗi unknown directive; trong khi đó Virtual Host đang chạy vẫn phục vụ mã 200 bình thường

Lưu ý rằng file cấu hình cố tình viết sai để thử nghiệm được đặt tách biệt hoàn toàn bên ngoài các thư mục include đang hoạt động và tuyệt đối không được nạp (reload) vào tiến trình dịch vụ chính. File nhật ký truy cập riêng đã ghi nhận đầy đủ cả 7 lượt request. Việc một Host lạ nhận về mã 404 là do chúng tôi chủ động thiết kế một khối default_server chặn riêng trên cổng 8082 của đợt thực nghiệm này, chứ mặc định NGINX thông thường sẽ chuyển cho khối server đầu tiên xử lý.

Ngay sau khi thu thập đủ số liệu, chúng tôi đã tháo gỡ file cấu hình cùng symlink thử nghiệm, chạy nginx -t kiểm tra và reload dịch vụ thành công; cổng nội bộ 8082 đóng lại hoàn toàn và thư mục tạm được dọn sạch. Đối chiếu toàn bộ 18 file cấu hình và symlink sẵn có trên hệ thống đều giữ nguyên vẹn mã băm SHA-256, phân quyền và chủ sở hữu như trước khi thử nghiệm; hai website WordPress trên máy vẫn trả về mã 200 ổn định suốt quá trình.

Ảnh chụp màn hình đợt thực nghiệm trực tiếp lúc 09:45 ngày 01/10

Giao diện console dưới đây ghi nhận mốc thời gian bắt đầu lúc 09:45:42 (UTC+7) và các sự kiện kiểm tra diễn ra trong khoảng 09:45:43–44 ngày 01/10/2026 (đây là một đợt chạy thực tế mới vào buổi sáng, độc lập với đợt chạy lúc 03:31 rạng sáng ở trên). Kịch bản kiểm tra tự động đã thực thi các truy vấn thật vào NGINX và in bảng tóm tắt kết quả trực tiếp ra màn hình console:

Console LAB-CF-02 hiển thị tóm tắt trực tiếp phép thử virtual host loopback: hai Host 200, lỗi 404 và 403, phục hồi 200 cùng kết quả dọn cấu hình

Ảnh chụp console thực tế ngày 01/10/2026, bắt đầu lúc 09:45:42 giờ Việt Nam (các dòng dấu thời gian bên trong log hiển thị theo giờ chuẩn UTC, tương ứng 09:45:43–44 UTC+7). Vùng hiển thị console được giữ nguyên từng pixel và chỉ gắn thêm thanh logo ở chân ảnh. Bấm vào ảnh để xem kích thước đầy đủ.

Trong đợt chạy lúc 09:45 này trên NGINX 1.24.0 với cổng lắng nghe riêng 127.0.0.1:8082, cả hai tên miền đuôi .test đều trả về mã 200 với đúng 105 byte HTML và mã SHA-256 trùng khớp. Truy vấn tên miền lạ hoặc đường dẫn thiếu đều nhận về mã 404; khi khóa quyền file về 000 thì nhận mã 403 và khi mở lại quyền 644 thì khôi phục ngay mã 200. Sau khi dọn dẹp cấu hình tạm, toàn bộ 18 mục cấu hình gốc của máy chủ đều khớp tuyệt đối với trạng thái ban đầu, và các website WordPress hiện hữu vẫn hoạt động trơn tru (tls_verify=0).

Thực nghiệm tên miền chính và nhánh www công khai trên Internet ngày 02/10

Để không chỉ dừng lại ở môi trường nội bộ loopback, vào ngày 02/10/2026, chúng tôi tiếp tục tạo thêm hai bản ghi A thực tế ở chế độ DNS only trỏ thẳng về IP của máy chủ LAB-CF-02: vhost-cf02.localhost.vn và www.vhost-cf02.localhost.vn. Hai tên miền này hoàn toàn tách biệt với website WordPress đang vận hành, sử dụng thư mục gốc và file cấu hình riêng biệt để đảm bảo không ảnh hưởng đến hệ thống sẵn có.

Quy trình triển khai ngoài thực tế được thực hiện tuần tự và bài bản: xác nhận DNS đã phân giải đúng IP → kiểm tra cả hai tên miền qua giao thức HTTP cổng 80 đều trả về đúng trang HTML → dùng Certbot (chế độ webroot ngay tại thư mục HTML thử nghiệm) để xin cấp chứng chỉ SSL/TLS phủ cả hai tên miền → kiểm tra truy cập HTTPS cho từng tên miền → cuối cùng mới kích hoạt quy tắc chuyển hướng 301. Chi tiết về cách xin cấp và tự động gia hạn chứng chỉ SSL/TLS bạn có thể xem thêm tại hướng dẫn xin và gia hạn chứng chỉ TLS cho tên miền trong cùng chuỗi bài viết.

Trang HTML thật của virtual host riêng trên LAB-CF-02, hiển thị hai tên miền dùng chung thư mục web

Ảnh chụp trình duyệt Chromium thực tế ngày 02/10/2026 lúc 15:15 (giờ Việt Nam) ở độ phân giải màn hình máy tính 1440 px, hiển thị trang HTML được phục vụ trực tiếp từ VPS thật. Phần chân ảnh có ghép thanh logo nhận diện mà không làm thay đổi nội dung hiển thị của trang web.

Hạng mục kiểm tra thực tế ngoài Internet Kết quả ghi nhận ngày 02/10/2026
Truy vấn DNS cho hai tên miền sau khi tạo bản ghi A Cả hai đều phân giải chính xác địa chỉ IPv4 về máy chủ LAB-CF-02
Truy cập HTTP cổng 80 trước khi bật chuyển hướng Cả hai tên miền đều trả về mã 200 OK, cùng nội dung HTML dài 767 byte
Truy cập HTTPS cổng 443 trước khi bật chuyển hướng Cả hai tên miền đều trả về mã 200 OK; trình duyệt Chromium xác thực chứng chỉ TLS 1.3 hợp lệ
Truy cập HTTP (cả tên chính và www) sau khi bật chuyển hướng Trả về mã 301 Moved Permanently điều hướng thẳng về địa chỉ HTTPS của tên miền chính
Truy cập https://www... sau khi bật chuyển hướng Trả về mã 301 chuyển thẳng về https://vhost-cf02.localhost.vn và đích cuối nhận mã 200 OK
Truy cập đường dẫn không tồn tại /missing-proof qua HTTPS Trả về mã lỗi chuẩn 404 Not Found kèm header X-Robots-Tag: noindex
Kiểm tra hiển thị trên khung nhìn di động 390 px Bố cục trang hiển thị gọn gàng, không bị tràn thanh cuộn ngang

Nội dung HTML trả về qua HTTPS của cả hai tên miền trước thời điểm bật redirect có mã băm SHA-256 giống hệt nhau. Toàn bộ các truy vấn này đều đi qua hệ thống phân giải DNS công cộng và kiểm tra chứng chỉ bảo mật nghiêm ngặt, chứng minh trọn vẹn luồng đi từ tên miền ngoài Internet vào đúng máy chủ, đúng Server Block và hoàn tất bắt tay TLS hợp lệ cho cả tên miền chính lẫn nhánh www.

Trang virtual host LAB-CF-02 hiển thị trên màn hình rộng 390 pixel với hai tên miền và nội dung không tràn ngang

Ảnh chụp giao diện trang thực tế trên trình duyệt Chromium với khung nhìn di động rộng 390 px vào ngày 02/10/2026, xác nhận bố cục hiển thị chuẩn xác không bị vỡ khung.

Cấu hình chuyển hướng 301 chuẩn chỉnh sau khi HTTPS đã thông suốt

Trong đợt thực nghiệm ngày 02/10, sau khi xác nhận HTTPS đã hoạt động ngon lành trên cả hai tên miền, chúng tôi áp dụng cấu hình chuyển hướng toàn bộ lưu lượng HTTP (cổng 80) và lưu lượng HTTPS của nhánh www về một mối duy nhất là https://vhost-cf02.localhost.vn. Dưới đây là hai khối server đảm nhận nhiệm vụ điều hướng đó (khối server thứ ba lắng nghe 443 để phục vụ nội dung cho tên miền chính được giữ riêng):

server {
    listen 80;
    server_name vhost-cf02.localhost.vn www.vhost-cf02.localhost.vn;
    return 301 https://vhost-cf02.localhost.vn$request_uri;
}

server {
    listen 443 ssl;
    server_name www.vhost-cf02.localhost.vn;
    ssl_certificate /etc/letsencrypt/live/vhost-cf02.localhost.vn/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/vhost-cf02.localhost.vn/privkey.pem;
    return 301 https://vhost-cf02.localhost.vn$request_uri;
}

Nguyên tắc an toàn trước khi áp dụng đoạn cấu hình trên là phải chắc chắn chứng chỉ SSL đã bao phủ đủ các tên miền và cổng 443 của tên miền chính đã chạy ổn định. Khi áp dụng vào dự án thật của bạn, hãy nhớ thay thế tên miền tương ứng, cập nhật lại khối HTTP cũ để tránh khai báo trùng lặp server_name, rồi chạy sudo nginx -t kiểm tra cú pháp trước khi reload. Biến $request_uri ở cuối dòng return 301 cực kỳ quan trọng vì nó giúp giữ nguyên đường dẫn bài viết và các tham số truy vấn phía sau tên miền khi khách được chuyển hướng.

Nếu chẳng may cấu hình chuyển hướng bị lặp vòng (redirect loop) hoặc trỏ nhầm đích, bạn chỉ việc khôi phục lại file cấu hình sao lưu trước đó, chạy nginx -t rồi reload. Lưu ý nhỏ là các trình duyệt web rất hay lưu cứng mã chuyển hướng 301 vào bộ nhớ đệm, nên sau khi sửa xong bạn hãy dùng cửa sổ ẩn danh mới hoặc kiểm tra bằng lệnh curl -I trên Terminal để thấy ngay kết quả thực tế từ máy chủ. Đặc biệt, tuyệt đối không xóa file chứng chỉ SSL trên đĩa cứng khi trong file cấu hình NGINX đang bật vẫn còn dòng ssl_certificate trỏ tới nó, nếu không NGINX sẽ báo lỗi ngay khi reload!

Thu dọn môi trường sau thực nghiệm và phạm vi kết quả

Vào lúc 15:17 ngày 02/10/2026, ngay sau khi hoàn tất nghiệm thu, chúng tôi đã tháo bỏ file cấu hình và symlink của trang thử nghiệm, chạy nginx -t và reload dịch vụ; toàn bộ các file cấu hình hiện hữu trên máy chủ đều giữ nguyên mã băm, phân quyền và chủ sở hữu. Tiếp đó, chứng chỉ SSL tạm cùng hai bản ghi DNS vhost-cf02 và www.vhost-cf02 cũng được xóa bỏ hoàn toàn. Vì vậy, hai tên miền thử nghiệm trong ảnh chụp hiện không còn tồn tại trên Internet nữa — bạn nhớ sử dụng đúng tên miền và địa chỉ IP của riêng mình khi thực hành nhé.

Các lỗi kinh điển thường gặp và quy trình hoàn tác (Rollback)

Lỗi 403 Forbidden: Báo hiệu NGINX đã đón được khách vào đúng khối server, nhưng lại không có quyền đọc file trong thư mục root hoặc không tìm thấy file index.html như khai báo. Thay vì nhắm mắt gõ lệnh chmod 777 cực kỳ nguy hiểm cho bảo mật, bạn hãy dùng lệnh namei -l /var/www/lab-cf02/index.html để soi quyền truy cập của từng tầng thư mục từ gốc / đi xuống.

Vẫn hiện trang chào mừng mặc định (Welcome to nginx!): Hãy bình tĩnh kiểm tra lại 4 yếu tố: URL gõ trên trình duyệt, giá trị server_name trong file cấu hình, địa chỉ IP mà tên miền đang phân giải tới, và xem bạn đã thực sự chạy lệnh systemctl reload nginx hay chưa. Nếu dùng curl --resolve trên Terminal đã ra đúng trang mới mà mở trình duyệt vẫn thấy trang cũ, thủ phạm 99% nằm ở bộ nhớ đệm DNS hoặc bộ nhớ đệm trình duyệt của bạn chứ không phải lỗi tại file cấu hình NGINX.

Sửa file xong nhưng Reload không thấy có tác dụng: Hãy kiểm tra xem bạn có đang sửa nhầm file ở thư mục khác mà chưa tạo symlink sang /etc/nginx/sites-enabled/ hay không, đồng thời chạy sudo nginx -t và xem log hệ thống qua journalctl -u nginx. Việc bấm lưu file trong trình soạn thảo mới chỉ ghi dữ liệu xuống ổ cứng chứ NGINX chưa hề tự động đọc lại nếu bạn quên reload.

Khi cần rollback (hoàn tác) một Virtual Host mới tạo bị lỗi, thao tác gọn gàng và an toàn nhất là xóa đúng đường dẫn liên kết mềm (symlink) của site đó bên trong thư mục /etc/nginx/sites-enabled/ (vẫn giữ lại file gốc trong sites-available để rảnh tay nghiên cứu lỗi sau), tiếp theo chạy sudo nginx -t rồi sudo systemctl reload nginx. Tuyệt đối không xóa nhầm thư mục chứa mã nguồn website khi bạn chỉ đang xử lý sự cố định tuyến cấu hình.

Tiêu chí nghiệm thu hoàn thành bước này: Tên miền chính trả về đúng trang HTML nhận diện riêng, nhánh www hoạt động đúng như thiết kế (nếu có sử dụng), file access log ghi nhận chuẩn xác lượt truy cập và các đường dẫn không tồn tại trả về mã lỗi 404. Hãy lưu lại kết quả kiểm tra trước khi bước sang chặng cài đặt PHP và cơ sở dữ liệu.

Tài liệu tham khảo và bước tiếp theo

Toàn bộ kiến thức cấu hình trong bài được đối chiếu trực tiếp với tài liệu chính thức của NGINX vào ngày 02/10/2026, bao gồm: NGINX Docs: Server names, NGINX Docs: How nginx processes a request, NGINX Beginner’s Guide và NGINX Docs: Configuring HTTPS servers.

Mời bạn xem lại bức tranh tổng thể tại lộ trình cài đặt WordPress trên VPS từ A đến Z, hoặc ôn lại bài liền trước: Dùng dig hoặc nslookup kiểm tra bản ghi và TTL. Khi lễ tân NGINX đã biết phân phòng chuẩn chỉnh, hãy cùng bước sang Bài 34: Kiểm tra cổng 80/443 và Cloud Firewall để đảm bảo mọi cánh cửa mạng từ ngoài Internet vào VPS đều thông suốt và an toàn.

Tài liệu tham khảo & Kiểm chứng

CẦN KỸ SƯ HỖ TRỢ TRỰC TIẾP? Đang làm theo hướng dẫn nhưng vướng lỗi hệ thống hoặc sợ đụng chạm dữ liệu đang chạy?

Gửi địa chỉ URL qua Zalo để kỹ thuật viên localhost.vn kiểm tra sơ bộ miễn phí trước khi quyết định can thiệp.

Xem bảng dịch vụ
Góc thực chiến localhost.vn

Mọi hướng dẫn đều dựa trên số liệu đo đạc, log thực tế và nguyên tắc "luôn có đường lùi (Snapshot/Backup) trước khi gõ lệnh".

Nguyên tắc biên tập & Minh bạch ↗