Host nhiều website cùng 1 VPS bằng NGINX server_name

Tài liệu » Quản trị VPS - Server » Host nhiều website cùng 1 VPS bằng NGINX server_name

Vì sao cần Host nhiều website trên 1 VPS bằng NGINX server_name ngay?

Bạn đang đau đầu vì chi phí thuê nhiều VPS cho từng website?
* 💰 Tiết kiệm chi phí: Giảm đáng kể hóa đơn hàng tháng.
* 🚀 Quản lý tập trung: Dễ dàng cập nhật và bảo trì.
* ⚡ Tối ưu tài nguyên: Sử dụng hiệu quả sức mạnh VPS.
* 🌐 Linh hoạt mở rộng: Thêm website mới nhanh chóng.
* ✅ Đơn giản hóa cấu hình: Chỉ cần quản lý một server.

Hiểu về Virtual Host và server_name trong NGINX

Tóm gọn: NGINX sử dụng server_name để xác định website nào sẽ được phục vụ dựa trên tên miền mà người dùng truy cập.

Virtual Host (hay còn gọi là Name-based Virtual Host) cho phép một máy chủ web duy nhất (ở đây là NGINX trên VPS của bạn) phục vụ nhiều tên miền khác nhau. Khi người dùng gõ một địa chỉ web vào trình duyệt, trình duyệt sẽ gửi yêu cầu HTTP kèm theo tên miền. NGINX sẽ đọc yêu cầu này và dựa vào chỉ thị server_name trong cấu hình để quyết định sẽ sử dụng block cấu hình server nào để xử lý yêu cầu đó.

Cấu hình cơ bản của một server block

Mỗi website bạn muốn host sẽ cần một server block riêng trong file cấu hình NGINX.

server {
    listen 80;
    listen [::]:80;

    server_name example.com www.example.com;

    root /var/www/example.com/html;
    index index.html index.htm;

    location / {
        try_files $uri $uri/ =404;
    }
}
  • listen 80;: Chỉ định NGINX lắng nghe trên cổng 80 (HTTP).
  • listen [::]:80;: Chỉ định NGINX lắng nghe trên cổng 80 cho địa chỉ IPv6.
  • server_name example.com www.example.com;: Đây là phần quan trọng nhất. Nó cho NGINX biết rằng server block này sẽ xử lý các yêu cầu đến tên miền example.com và tên miền phụ www.example.com. Bạn có thể liệt kê nhiều tên miền, phân tách bằng dấu cách.
  • root /var/www/example.com/html;: Thư mục chứa file tĩnh của website.
  • index index.html index.htm;: Các file mặc định sẽ được tìm kiếm khi truy cập vào thư mục gốc.
  • location / { ... }: Cấu hình cho các yêu cầu đến mọi đường dẫn. try_files là một chỉ thị hữu ích để tìm kiếm file và trả về 404 nếu không tìm thấy.

Cách NGINX chọn server block phù hợp

Khi một yêu cầu HTTP đến máy chủ, NGINX sẽ duyệt qua tất cả các server block đang hoạt động. Nó sẽ chọn server block đầu tiên khớp với:

  1. Địa chỉ IP và Port: Yêu cầu phải đến đúng địa chỉ IP và cổng mà server block đang lắng nghe.
  2. server_name: Tên miền trong yêu cầu phải khớp với một trong các tên miền được liệt kê trong chỉ thị server_name của server block. NGINX có một quy tắc ưu tiên:
    • Tên miền chính xác (ví dụ: example.com).
    • Tên miền wildcard (ví dụ: *.example.com).
    • Tên miền regex (ví dụ: ~^www\d*\.example\.com$).
    • Tên miền mặc định (chỉ thị default_server).

💡 Mẹo: Luôn định nghĩa một server block mặc định để bắt tất cả các yêu cầu không khớp với bất kỳ server_name nào khác. Điều này giúp tránh các lỗi không mong muốn và có thể được dùng để hiển thị trang lỗi hoặc chuyển hướng.

server {
    listen 80 default_server;
    listen [::]:80 default_server;

    server_name _; # Tên miền không xác định hoặc không khớp

    return 444; # Đóng kết nối mà không trả về thông tin gì
}

Chuẩn bị môi trường VPS và Cài đặt NGINX

Tóm gọn: Đảm bảo VPS của bạn sẵn sàng và NGINX được cài đặt đúng cách.

Trước khi cấu hình host nhiều website, bạn cần có một VPS hoạt động và cài đặt NGINX. Bài viết này giả định bạn đang sử dụng một hệ điều hành dựa trên Debian/Ubuntu.

Cập nhật hệ thống và cài đặt NGINX

Đảm bảo hệ thống của bạn được cập nhật và cài đặt NGINX.

sudo apt update
sudo apt upgrade -y
sudo apt install nginx -y
  • sudo apt update: Tải danh sách các gói phần mềm mới nhất từ kho lưu trữ.
  • sudo apt upgrade -y: Cập nhật các gói đã cài đặt lên phiên bản mới nhất.
  • sudo apt install nginx -y: Cài đặt máy chủ web NGINX.

Sau khi cài đặt, NGINX sẽ tự động khởi động. Bạn có thể kiểm tra trạng thái bằng lệnh:

sudo systemctl status nginx

Output mẫu:

● nginx.service - A high performance web server and a reverse proxy server
     Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
     Active: active (running) since Mon 2023-10-27 10:00:00 UTC; 1 day ago
       Docs: man:nginx(8)
   Main PID: 1234 (nginx)
      Tasks: 2 (limit: 1100)
     Memory: 5.5M
        CPU: 250ms
     CGroup: /system.slice/nginx.service
             ├─1234 /usr/sbin/nginx -g daemon on; master_process>
             └─1235 /usr/sbin/nginx -g daemon on; master_process>

Cấu hình Firewall (UFW)

Nếu bạn sử dụng UFW (Uncomplicated Firewall), hãy cho phép truy cập HTTP và HTTPS.

sudo ufw allow 'Nginx Full'
sudo ufw enable
sudo ufw status
  • sudo ufw allow 'Nginx Full': Cho phép cả cổng 80 (HTTP) và 443 (HTTPS).
  • sudo ufw enable: Kích hoạt tường lửa.
  • sudo ufw status: Kiểm tra trạng thái tường lửa và các quy tắc đã áp dụng.

⚠️ Cảnh báo: Nếu bạn chưa cài đặt UFW, hãy cân nhắc cài đặt và cấu hình nó để bảo mật VPS của bạn.

Tạo cấu hình Virtual Host cho từng website

Tóm gọn: Mỗi website sẽ có một thư mục riêng và một file cấu hình NGINX tương ứng.

Để host nhiều website, chúng ta sẽ tạo một thư mục cho nội dung của mỗi website và một file cấu hình NGINX riêng cho từng website đó.

Bước 1: Tạo thư mục chứa file website

Giả sử bạn muốn host hai website: site1.comsite2.com.

# Tạo thư mục cho site1.com
sudo mkdir -p /var/www/site1.com/html
sudo chown -R $USER:$USER /var/www/site1.com/html
sudo chmod -R 755 /var/www/site1.com/html

# Tạo file index.html mẫu cho site1.com
echo "<html><body><h1>Welcome to site1.com!</h1></body></html>" | sudo tee /var/www/site1.com/html/index.html

# Tạo thư mục cho site2.com
sudo mkdir -p /var/www/site2.com/html
sudo chown -R $USER:$USER /var/www/site2.com/html
sudo chmod -R 755 /var/www/site2.com/html

# Tạo file index.html mẫu cho site2.com
echo "<html><body><h1>Welcome to site2.com!</h1></body></html>" | sudo tee /var/www/site2.com/html/index.html
  • sudo mkdir -p: Tạo thư mục và các thư mục cha nếu chưa tồn tại.
  • sudo chown -R $USER:$USER: Gán quyền sở hữu thư mục cho người dùng hiện tại để dễ dàng chỉnh sửa file.
  • sudo chmod -R 755: Cấp quyền đọc và thực thi cho tất cả mọi người, quyền ghi chỉ cho chủ sở hữu.
  • echo ... | sudo tee ...: Tạo nội dung file index.html và ghi vào file.

Bước 2: Tạo file cấu hình NGINX cho từng website

NGINX thường lưu các file cấu hình cho từng site trong thư mục /etc/nginx/sites-available/. Sau đó, chúng ta sẽ tạo một symbolic link đến thư mục /etc/nginx/sites-enabled/ để kích hoạt cấu hình.

File cấu hình cho site1.com:

Tạo file /etc/nginx/sites-available/site1.com:

sudo nano /etc/nginx/sites-available/site1.com

Dán nội dung sau vào file:

server {
    listen 80;
    listen [::]:80;

    server_name site1.com www.site1.com;

    root /var/www/site1.com/html;
    index index.html index.htm;

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

Lưu và thoát (Ctrl+X, Y, Enter trong nano).

File cấu hình cho site2.com:

Tạo file /etc/nginx/sites-available/site2.com:

sudo nano /etc/nginx/sites-available/site2.com

Dán nội dung sau vào file:

server {
    listen 80;
    listen [::]:80;

    server_name site2.com www.site2.com;

    root /var/www/site2.com/html;
    index index.html index.htm;

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

Lưu và thoát.

Bước 3: Kích hoạt cấu hình

Tạo symbolic link từ sites-available sang sites-enabled.

sudo ln -s /etc/nginx/sites-available/site1.com /etc/nginx/sites-enabled/
sudo ln -s /etc/nginx/sites-available/site2.com /etc/nginx/sites-enabled/
  • sudo ln -s: Tạo một symbolic link (liên kết tượng trưng).

Bước 4: Kiểm tra cấu hình và khởi động lại NGINX

Trước khi khởi động lại NGINX, luôn kiểm tra cú pháp cấu hình.

sudo nginx -t

Output mẫu nếu cấu hình đúng:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Nếu không có lỗi, hãy tải lại cấu hình NGINX.

sudo systemctl reload nginx

💡 Mẹo: Nếu bạn muốn xóa một website, chỉ cần xóa symbolic link trong /etc/nginx/sites-enabled/ và tải lại NGINX. Ví dụ: sudo rm /etc/nginx/sites-enabled/site1.com.

Cấu hình DNS cho các tên miền

Tóm gọn: Các tên miền của bạn cần trỏ về địa chỉ IP của VPS.

Để NGINX có thể nhận diện và phục vụ đúng website, bạn cần cấu hình bản ghi DNS cho mỗi tên miền để chúng trỏ về địa chỉ IP công cộng của VPS.

Bước 1: Lấy địa chỉ IP của VPS

Bạn có thể tìm địa chỉ IP công cộng của VPS từ bảng điều khiển của nhà cung cấp dịch vụ hosting. Hoặc sử dụng lệnh sau trên VPS (nếu có nhiều IP, hãy chắc chắn bạn chọn đúng IP công cộng):

ip addr show eth0 | grep inet | awk '{ print $2; }' | sed 's/\/.*$//'
  • Thay eth0 bằng tên interface mạng của bạn nếu cần (thường là ens hoặc eth).

Bước 2: Cập nhật bản ghi DNS tại nhà cung cấp tên miền

Truy cập vào trang quản lý tên miền của bạn (nơi bạn đã đăng ký tên miền site1.comsite2.com). Tạo hoặc chỉnh sửa các bản ghi sau:

  • Đối với site1.com:
    • Bản ghi A cho site1.com trỏ đến IP của VPS.
    • Bản ghi A cho www.site1.com trỏ đến IP của VPS.
  • Đối với site2.com:
    • Bản ghi A cho site2.com trỏ đến IP của VPS.
    • Bản ghi A cho www.site2.com trỏ đến IP của VPS.

Ví dụ về cách cấu hình trên bảng điều khiển DNS (giao diện có thể khác nhau tùy nhà cung cấp):

LoạiTên miền / HostGiá trị / IP AddressTTL (Giây)
Asite1.comYOUR_VPS_IP3600
Awww.site1.comYOUR_VPS_IP3600
Asite2.comYOUR_VPS_IP3600
Awww.site2.comYOUR_VPS_IP3600
  • Thay thế YOUR_VPS_IP bằng địa chỉ IP thực tế của VPS.
  • TTL (Time To Live) xác định thời gian các máy chủ DNS cache bản ghi. Giá trị thấp hơn giúp thay đổi DNS cập nhật nhanh hơn, nhưng có thể tăng tải cho máy chủ DNS.

⚠️ Cảnh báo: Thời gian cập nhật DNS có thể mất từ vài phút đến 48 giờ tùy thuộc vào nhà cung cấp DNS và cài đặt TTL. Bạn có thể sử dụng các công cụ như dnschecker.org để theo dõi quá trình cập nhật.

Cấu hình SSL/TLS với Let’s Encrypt và Certbot

Tóm gọn: Bảo mật website của bạn với chứng chỉ SSL miễn phí từ Let’s Encrypt.

Để website của bạn hoạt động qua HTTPS, bạn cần cài đặt chứng chỉ SSL. Certbot là một công cụ tuyệt vời giúp tự động hóa quá trình này với Let’s Encrypt.

Bước 1: Cài đặt Certbot và plugin NGINX

sudo apt install certbot python3-certbot-nginx -y
  • certbot: Công cụ chính để lấy và quản lý chứng chỉ.
  • python3-certbot-nginx: Plugin giúp Certbot tự động sửa đổi file cấu hình NGINX của bạn.

Bước 2: Lấy chứng chỉ SSL cho các tên miền

Chạy Certbot và chỉ định tất cả các tên miền bạn muốn bảo mật.

sudo certbot --nginx -d site1.com -d www.site1.com -d site2.com -d www.site2.com
  • --nginx: Yêu cầu Certbot sử dụng plugin NGINX.
  • -d domain.com: Chỉ định tên miền cần lấy chứng chỉ. Lặp lại cho tất cả các tên miền.

Certbot sẽ hỏi bạn một số câu hỏi, ví dụ như email để nhận thông báo gia hạn, và liệu bạn có muốn chuyển hướng HTTP sang HTTPS hay không.

  • Enter email address: Nhập địa chỉ email của bạn.
  • Agree to the terms of service: Đồng ý với các điều khoản.
  • Would you like to share your email: Chọn có hoặc không.
  • Redirect HTTP traffic to HTTPS: Chọn tùy chọn này (thường là số 2) để tự động chuyển hướng người dùng từ HTTP sang HTTPS.

Sau khi hoàn tất, Certbot sẽ tự động cập nhật các file cấu hình NGINX của bạn để sử dụng chứng chỉ SSL và bật tính năng chuyển hướng.

Bước 3: Kiểm tra tự động gia hạn

Chứng chỉ Let’s Encrypt có thời hạn 90 ngày. Certbot thường tự động thiết lập một cron job hoặc systemd timer để gia hạn chứng chỉ trước khi hết hạn.

Bạn có thể kiểm tra xem việc gia hạn có hoạt động không bằng lệnh sau:

sudo certbot renew --dry-run
  • --dry-run: Chạy thử nghiệm gia hạn mà không thực sự thay đổi chứng chỉ.

Output mẫu nếu thành công:

Saving debug log to /var/log/letsencrypt/letsencrypt.log

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Congratulations, all simulated renewals succeeded:
  /etc/letsencrypt/live/site1.com/fullchain.pem (success)
  /etc/letsencrypt/live/site2.com/fullchain.pem (success)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

💡 Mẹo: Nếu bạn thêm tên miền mới sau này, hãy chạy lại lệnh sudo certbot --nginx -d newdomain.com để lấy chứng chỉ cho tên miền đó.

Quản lý nhiều website với Docker (Tùy chọn nâng cao)

Tóm gọn: Sử dụng Docker để đóng gói và quản lý từng website, NGINX đóng vai trò reverse proxy.

Đối với các dự án phức tạp hơn hoặc khi bạn muốn có sự cô lập tốt hơn giữa các website, Docker là một giải pháp mạnh mẽ. Trong mô hình này, NGINX sẽ không lưu trữ trực tiếp file website mà hoạt động như một reverse proxy, chuyển tiếp yêu cầu đến các container Docker chứa từng ứng dụng web.

Cấu hình NGINX làm Reverse Proxy

Đây là một ví dụ về file cấu hình NGINX khi đóng vai trò reverse proxy cho hai ứng dụng web chạy trong Docker container.

# /etc/nginx/sites-available/my_docker_apps

server {
    listen 80;
    listen [::]:80;

    server_name app1.example.com;

    location / {
        proxy_pass http://localhost:3000; # Địa chỉ ứng dụng 1 trong Docker
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

server {
    listen 80;
    listen [::]:80;

    server_name app2.example.com;

    location / {
        proxy_pass http://localhost:3001; # Địa chỉ ứng dụng 2 trong Docker
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}
  • proxy_pass http://localhost:3000;: Chỉ thị quan trọng nhất. Nó yêu cầu NGINX chuyển tiếp yêu cầu đến địa chỉ và cổng của ứng dụng web bên trong Docker container.
  • Các chỉ thị proxy_set_header: Truyền thông tin cần thiết từ NGINX đến ứng dụng backend, giúp ứng dụng biết được thông tin gốc của yêu cầu.

Ví dụ Docker Compose

Bạn có thể sử dụng Docker Compose để định nghĩa và chạy các ứng dụng của mình.

# docker-compose.yml
version: '3.8'

services:
  app1:
    image: your_app1_image # Thay bằng image của bạn
    ports:
      - "3000:3000" # Mapping port 3000 của host tới port 3000 của container

  app2:
    image: your_app2_image # Thay bằng image của bạn
    ports:
      - "3001:3001" # Mapping port 3001 của host tới port 3001 của container

  nginx:
    image: nginx:latest
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/conf.d/default.conf # File cấu hình NGINX
      - ./certs:/etc/letsencrypt # Volume chứa chứng chỉ SSL
    depends_on:
      - app1
      - app2

Sau khi cấu hình file docker-compose.yml và file NGINX tương ứng, bạn có thể chạy các container bằng lệnh:

docker-compose up -d

💡 Mẹo: Khi sử dụng Docker, bạn có thể chạy NGINX ngay trong một container riêng, quản lý bởi Docker Compose. Điều này giúp toàn bộ môi trường ứng dụng của bạn được đóng gói và dễ dàng triển khai.

Pitfalls & Lỗi thường gặp

Tóm gọn: Cẩn thận với các lỗi cấu hình DNS, cú pháp NGINX và quyền truy cập file.

1. Lỗi DNS chưa cập nhật

  • Vấn đề: Sau khi cấu hình NGINX và DNS, bạn truy cập vào tên miền nhưng lại thấy trang mặc định của NGINX hoặc lỗi “This site can’t be reached”.
  • Nguyên nhân: Bản ghi DNS chưa được cập nhật hoàn toàn trên toàn cầu.
  • Cách khắc phục:
    • Chờ đợi (có thể mất vài giờ).
    • Kiểm tra lại bản ghi DNS tại nhà cung cấp tên miền.
    • Sử dụng ping yourdomain.com hoặc nslookup yourdomain.com để xem IP mà DNS đang trả về. Đảm bảo nó khớp với IP VPS.

2. Lỗi cú pháp NGINX

  • Vấn đề: Sau khi chỉnh sửa file cấu hình và chạy sudo systemctl reload nginx, bạn nhận được thông báo lỗi.
  • Nguyên nhân: Cú pháp trong file cấu hình NGINX bị sai (thiếu dấu chấm phẩy, dấu ngoặc nhọn không khớp…).
  • Cách khắc phục: Chạy sudo nginx -t để kiểm tra cú pháp. Lệnh này sẽ chỉ ra dòng và file chứa lỗi. Sửa lỗi và chạy lại reload.

3. Quyền truy cập thư mục website

  • Vấn đề: Website hiển thị lỗi 403 Forbidden.
  • Nguyên nhân: Người dùng NGINX (thường là www-data) không có quyền đọc các file trong thư mục website.
  • Cách khắc phục: Đảm bảo người dùng www-data có quyền đọc và thực thi thư mục.
    bash
    sudo chown -R www-data:www-data /var/www/yourdomain.com/html
    sudo chmod -R 755 /var/www/yourdomain.com/html

    • chown: Thay đổi chủ sở hữu.
    • chmod 755: Cấp quyền đọc/thực thi cho mọi người, ghi cho chủ sở hữu.

4. Nhiều server block lắng nghe cùng Port và IP

  • Vấn đề: NGINX không khởi động hoặc chỉ phục vụ một trong các website.
  • Nguyên nhân: Có hai hoặc nhiều server block định nghĩa listen 80; mà không có server_name rõ ràng hoặc không có default_server được chỉ định đúng cách.
  • Cách khắc phục:
    • Đảm bảo mỗi server block có server_name duy nhất.
    • Chỉ định một server block là default_server cho cổng 80 để xử lý các yêu cầu không khớp.

Key Takeaways

  • NGINX server_name cho phép bạn host nhiều website trên cùng một địa chỉ IP và port.
  • Mỗi website cần một thư mục chứa nội dung riêng và một server block NGINX tương ứng.
  • Cấu hình DNS là bắt buộc để tên miền trỏ về đúng địa chỉ IP của VPS.
  • Sử dụng Certbot để dễ dàng cài đặt SSL/TLS miễn phí với Let’s Encrypt.
  • Luôn kiểm tra cú pháp NGINX (nginx -t) trước khi reload và theo dõi log để gỡ lỗi.

FAQ

### Tôi có thể host bao nhiêu website trên 1 VPS?

Số lượng website phụ thuộc vào tài nguyên VPS (CPU, RAM) và mức độ “nặng” của từng website. Không có giới hạn cứng, nhưng hãy theo dõi hiệu suất VPS.

### IP của VPS thay đổi thì sao?

Nếu IP của VPS thay đổi, bạn cần cập nhật lại bản ghi DNS A cho tất cả các tên miền của mình tại nhà cung cấp tên miền.

### Làm thế nào để cấu hình NGINX cho tên miền không có www (ví dụ: site.com thay vì www.site.com)?

Trong server_name, bạn chỉ cần liệt kê tên miền mong muốn: server_name site.com;. Nếu muốn chuyển hướng từ www sang tên miền chính hoặc ngược lại, bạn cần thêm một server block khác để xử lý việc chuyển hướng.

### Tôi có cần cài đặt NGINX cho mỗi website không?

Không, bạn chỉ cần cài đặt NGINX một lần trên VPS. Sau đó, bạn tạo các file cấu hình server block cho từng website trong /etc/nginx/sites-available/.

### Làm thế nào để phân biệt các server block nếu chúng cùng IP và Port?

NGINX sử dụng chỉ thị server_name để phân biệt. Khi một yêu cầu đến, NGINX sẽ tìm server block có server_name khớp nhất với tên miền trong yêu cầu.

### Tôi có thể host cả website HTTP và HTTPS trên cùng 1 VPS không?

Có. Bạn sẽ có các server block lắng nghe trên cổng 80 (HTTP) và các server block khác lắng nghe trên cổng 443 (HTTPS) với cấu hình SSL được thêm vào. Certbot thường tự động xử lý việc này.

Cần VPS chạy NGINX host nhiều website?

Bạn muốn tiết kiệm chi phí và quản lý hiệu quả nhiều tên miền? Host nhiều website trên 1 VPS bằng NGINX server_name là giải pháp tối ưu.

Tại vsis.net, chúng tôi cung cấp các gói VPS cấu hình mạnh mẽ, sẵn sàng cho mọi nhu cầu của bạn, từ website cá nhân đến các dự án kinh doanh.

Trải nghiệm VPS tại vsis.net/vps ngay hôm nay!

Lên đầu trang