Cấu Hình Virtual Host Nginx Để Phục Vụ Đa Miền
Giới Thiệu
Virtual Host, hay còn gọi là Server Block trong Nginx, là một tính năng mạnh mẽ cho phép bạn chạy nhiều trang web khác nhau trên cùng một máy chủ vật lý hoặc máy chủ ảo, sử dụng chung một địa chỉ IP. Điều này cực kỳ hữu ích để tối ưu hóa việc sử dụng tài nguyên máy chủ, giảm chi phí và đơn giản hóa việc quản lý nhiều dự án web.
Trong hướng dẫn này, chúng ta sẽ đi qua các bước cụ thể để cấu hình Nginx Server Block, cho phép máy chủ của bạn phục vụ các trang web khác nhau dựa trên tên miền được yêu cầu.
📋 Thời gian: 20-30 phút | Độ khó: Cơ bản
Yêu Cầu
Để thực hiện hướng dẫn này, bạn cần có:
- Một máy chủ Linux (ưu tiên Ubuntu hoặc CentOS) đã cài đặt Nginx.
- Quyền truy cập root hoặc người dùng có quyền
sudo. - Ít nhất một hoặc nhiều tên miền đã được trỏ bản ghi A (hoặc AAAA cho IPv6) về địa chỉ IP công cộng của máy chủ của bạn. (Trong ví dụ này, chúng ta sẽ sử dụng
domain1.comvàdomain2.com). - Trình soạn thảo văn bản như
nanohoặcvim.
Các Bước Thực Hiện
Bước 1: Tạo Thư Mục Website
Đầu tiên, chúng ta cần tạo các thư mục riêng biệt để lưu trữ tệp tin của từng trang web. Việc này giúp tổ chức và quản lý code của bạn một cách rõ ràng.
Chúng ta sẽ tạo thư mục cho domain1.com và domain2.com trong /var/www/.
sudo mkdir -p /var/www/domain1.com/html
sudo mkdir -p /var/www/domain2.com/html
Tiếp theo, chúng ta cần gán quyền sở hữu cho người dùng hiện tại để dễ dàng chỉnh sửa các tệp tin mà không cần sudo mỗi lần. Thay $USER bằng tên người dùng hiện tại của bạn.
sudo chown -R $USER:$USER /var/www/domain1.com/html
sudo chown -R $USER:$USER /var/www/domain2.com/html
Cuối cùng, thiết lập quyền đọc, ghi, và thực thi phù hợp để Nginx có thể phục vụ nội dung.
sudo chmod -R 755 /var/www/domain1.com
sudo chmod -R 755 /var/www/domain2.com
Bước 2: Tạo Trang HTML Mẫu
Để kiểm tra cấu hình Virtual Host của chúng ta hoạt động đúng, hãy tạo một tệp index.html đơn giản cho mỗi tên miền.
Tạo index.html cho domain1.com:
echo "`<h1>`Chào mừng đến với Domain 1!</h1><p>Đây là trang web của domain1.com.</p>" | sudo tee /var/www/domain1.com/html/index.html
Tạo index.html cho domain2.com:
echo "`<h1>`Chào mừng đến với Domain 2!</h1><p>Đây là trang web của domain2.com.</p>" | sudo tee /var/www/domain2.com/html/index.html
Bước 3: Cấu Hình Server Block (Virtual Host) cho Nginx
Nginx sử dụng khái niệm "Server Block" thay vì "Virtual Host". Các tệp cấu hình Server Block thường được lưu trữ trong thư mục /etc/nginx/sites-available/ và được kích hoạt bằng cách tạo liên kết tượng trưng (symlink) đến thư mục /etc/nginx/sites-enabled/.
Tạo tệp cấu hình cho domain1.com:
sudo nano /etc/nginx/sites-available/domain1.com.conf
Dán nội dung sau vào tệp:
# /etc/nginx/sites-available/domain1.com.conf
server {
listen 80; # Lắng nghe trên cổng HTTP mặc định
listen [::]:80; # Lắng nghe trên IPv6
root /var/www/domain1.com/html; # Đường dẫn gốc của trang web
index index.html index.htm index.nginx-debian.html; # Các tệp index mặc định
server_name domain1.com www.domain1.com; # Tên miền mà server block này sẽ phục vụ
location / {
try_files $uri $uri/ =404; # Cố gắng tìm tệp hoặc thư mục, nếu không thì trả về 404
}
# Cấu hình logging riêng cho domain này (tùy chọn)
access_log /var/log/nginx/domain1.com_access.log;
error_log /var/log/nginx/domain1.com_error.log;
}
Lưu và đóng tệp (Ctrl+X, Y, Enter với nano).
Tạo tệp cấu hình cho domain2.com:
sudo nano /etc/nginx/sites-available/domain2.com.conf
Dán nội dung sau vào tệp:
# /etc/nginx/sites-available/domain2.com.conf
server {
listen 80;
listen [::]:80;
root /var/www/domain2.com/html;
index index.html index.htm index.nginx-debian.html;
server_name domain2.com www.domain2.com;
location / {
try_files $uri $uri/ =404;
}
access_log /var/log/nginx/domain2.com_access.log;
error_log /var/log/nginx/domain2.com_error.log;
}
Lưu và đóng tệp.
Kích hoạt Server Block:
Bây giờ, hãy tạo liên kết tượng trưng từ các tệp cấu hình trong sites-available đến sites-enabled để Nginx có thể nhận diện chúng.
sudo ln -s /etc/nginx/sites-available/domain1.com.conf /etc/nginx/sites-enabled/
sudo ln -s /etc/nginx/sites-available/domain2.com.conf /etc/nginx/sites-enabled/
💡 Mẹo: Nginx thường có một tệp cấu hình mặc định (default) trong sites-enabled. Nếu bạn không có ý định sử dụng nó cho trang web mặc định hoặc nó gây xung đột, bạn nên xóa liên kết tượng trưng của nó:
sudo rm /etc/nginx/sites-enabled/default
Bước 4: Kiểm Tra Cấu Hình và Khởi Động Lại Nginx
Sau khi tạo và kích hoạt các Server Block, bạn cần kiểm tra cú pháp cấu hình Nginx để đảm bảo không có lỗi.
sudo nginx -t
✅ Nếu mọi thứ đều đúng, bạn sẽ thấy thông báo tương tự như:
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
Nếu có lỗi, hãy xem lại các tệp cấu hình của bạn.
Cuối cùng, khởi động lại Nginx để áp dụng các thay đổi:
sudo systemctl restart nginx
Bước 5: Cấu Hình Firewall (UFW)
Nếu bạn đang sử dụng UFW (Uncomplicated Firewall) trên Ubuntu, bạn cần đảm bảo rằng cổng 80 (HTTP) và/hoặc cổng 443 (HTTPS) được mở để cho phép truy cập web.
sudo ufw allow 'Nginx HTTP' # Cho phép truy cập HTTP
# Nếu bạn có kế hoạch dùng HTTPS sau này, bạn có thể cho phép Nginx Full hoặc HTTPS
# sudo ufw allow 'Nginx HTTPS'
# sudo ufw allow 'Nginx Full' # Cho phép cả HTTP và HTTPS
sudo ufw enable # Kích hoạt UFW nếu nó chưa được kích hoạt
sudo ufw status # Kiểm tra trạng thái firewall
Sau khi hoàn thành các bước này, bạn có thể truy cập http://domain1.com và http://domain2.com từ trình duyệt web của mình. Mỗi tên miền sẽ hiển thị trang HTML mẫu tương ứng mà bạn đã tạo.
Troubleshooting
-
⚠️ Lỗi
nginx: [emerg] a duplicate listen 80: Lỗi này thường xảy ra khi có nhiều Server Block cố gắng lắng nghe trên cùng một cổng (ví dụ: 80) mà không có tên miền cụ thể hoặc có một Server Block mặc định vẫn đang hoạt động.- Cách xử lý: Đảm bảo bạn đã xóa hoặc vô hiệu hóa tệp cấu hình
defaulttrong/etc/nginx/sites-enabled/nếu nó gây xung đột. Kiểm tra tất cả các Server Block của bạn để đảm bảoserver_namelà duy nhất cho mỗi Server Block lắng nghe trên cổng 80.
- Cách xử lý: Đảm bảo bạn đã xóa hoặc vô hiệu hóa tệp cấu hình
-
⚠️ Lỗi 403 Forbidden: Điều này thường chỉ ra rằng Nginx không có quyền đọc các tệp tin hoặc thư mục của trang web.
- Cách xử lý: Kiểm tra lại quyền sở hữu và quyền truy cập của thư mục
/var/www/domainX.com/html. Đảm bảo rằng người dùng Nginx (thường làwww-datatrên Ubuntu hoặcnginxtrên CentOS) có quyền đọc và thực thi trên các thư mục, và quyền đọc trên các tệp tin. Bạn có thể thử:sudo chown -R www-data:www-data /var/www/domain1.com
sudo chmod -R 755 /var/www/domain1.com
- Cách xử lý: Kiểm tra lại quyền sở hữu và quyền truy cập của thư mục
-
⚠️ Lỗi 404 Not Found: Có thể do đường dẫn
roottrong Server Block sai hoặc tệpindex.htmlkhông tồn tại trong thư mục gốc của trang web.- Cách xử lý: Kiểm tra lại đường dẫn
roottrong tệp.confcủa bạn và đảm bảo nó trỏ đúng đến thư mục chứa tệpindex.html. Xác nhận rằng tệpindex.htmlthực sự tồn tại ở đó.
- Cách xử lý: Kiểm tra lại đường dẫn
-
⚠️ Trang web không tải hoặc hiển thị trang mặc định của Nginx:
- Cách xử lý: Kiểm tra trạng thái Nginx (
sudo systemctl status nginx). Đảm bảo nó đang chạy. Kiểm tra lại cấu hình DNS của tên miền để chắc chắn nó trỏ đúng IP máy chủ. Kiểm tra firewall (UFW) để đảm bảo cổng 80 được mở.
- Cách xử lý: Kiểm tra trạng thái Nginx (
Kết Luận
Việc cấu hình Virtual Host (Server Block) trên Nginx là một kỹ năng cơ bản nhưng vô cùng quan trọng đối với bất kỳ quản trị viên hệ thống hoặc nhà phát triển web nào. Bằng cách làm theo các bước trong hướng dẫn này, bạn đã có thể cấu hình Nginx để phục vụ nhiều trang web trên một máy chủ duy nhất, tối ưu hóa tài nguyên và quản lý dự án hiệu quả hơn.
Best practices (Thực hành tốt nhất):
- Sử dụng HTTPS: Luôn cấu hình SSL/TLS (ví dụ: với Let's Encrypt) cho tất cả các trang web để bảo mật thông tin liên lạc.
- Cấu hình Logging riêng: Thiết lập
access_logvàerror_logriêng biệt cho mỗi Server Block để dễ dàng theo dõi và gỡ lỗi. - Tổ chức thư mục: Duy trì cấu trúc thư mục rõ ràng và nhất quán cho các tệp trang web của bạn.
- Tối ưu hóa hiệu suất: Cân nhắc các cấu hình Nginx nâng cao như caching, nén Gzip, và FastCGI (cho PHP) để cải thiện tốc độ tải trang.
- Kiểm tra cấu hình định kỳ: Luôn chạy
sudo nginx -tsau mỗi thay đổi cấu hình để tránh lỗi cú pháp.