Linux

Cài đặt Nginx làm reverse proxy trên VPS chi tiết 2026

SSH vào VPS Ubuntu 24.04 mới, việc đầu tiên sau khi cài ứng dụng là đưa Nginx lên làm lớp trung gian. Nginx reverse proxy giúp bạn đưa nhiều ứng dụng chạy trên nhiều cổng khác nhau về cùng một địa chỉ IP và cổng 80/443, kèm theo đó là SSL, cân bằng tải, giới hạn tốc độ mà ứng dụng gốc không tự làm được. Bài này hướng dẫn từng bước cấu hình cho ứng dụng Node.js hoặc Docker trên VPS chạy Ubuntu 24.04 LTS.

Tóm tắt nhanh

  • Nginx reverse proxy hoạt động qua chỉ thị proxy_pass trong file server block, trỏ về localhost:PORT của ứng dụng.
  • Kiến trúc chuẩn: Nginx lắng nghe 80/443, ứng dụng chỉ lắng nghe trên 127.0.0.1, không expose ra ngoài.
  • Dùng snap install certbot hoặc bản apt để cấp SSL Let's Encrypt tự động gia hạn.
  • Lệnh nginx -tsystemctl reload nginx là bước bắt buộc sau mỗi lần sửa cấu hình.

Yêu cầu trước khi bắt đầu

  • Một VPS chạy Ubuntu 24.04 LTS với user sudo không phải root. Nếu dùng bản VPS Linux khác như Debian 12 thì lệnh apt tương tự.
  • Một tên miền (domain) trỏ A record về IP của VPS, ví dụ app.example.com. Nếu chưa có, xem bài cách cấu hình DNS record.
  • Ứng dụng backend đã chạy trên một cổng cụ thể, ví dụ Node.js trên 3000, hoặc container Docker map cổng 8080.
  • Mở cổng 80 và 443 trên firewall trước khi bật Nginx, tránh trường hợp cài xong không truy cập được từ ngoài.

Vì sao nên dùng Nginx làm reverse proxy

Nginx làm reverse proxy nghĩa là nó đứng trước ứng dụng của bạn, nhận toàn bộ request từ client rồi chuyển tiếp (proxy) về backend. Backend chỉ thấy kết nối từ Nginx, không thấy request gốc từ internet. Lợi ích rõ ràng nhất là bạn không phải mở nhiều cổng trên firewall, chỉ cần 80 và 443 là đủ cho bao nhiêu ứng dụng cũng được.

Với một VPS Linux có IP riêng, bạn có thể chạy cùng lúc một blog WordPress trên cổng 8080, một API Node.js trên 3000, một instance n8n trên 5678. Nginx sẽ dựa vào tên miền (server_name) để route về đúng ứng dụng. Ngoài ra Nginx còn xử lý luôn phần SSL termination, giảm tải cho backend vì không phải tự xử lý HTTPS mà chỉ nhận HTTP nội bộ.

Bước 1 - Cài đặt Nginx

Cài Nginx trên Ubuntu 24.04 bằng apt. Bản trong kho Ubuntu 24.04 là Nginx 1.24, đã đủ ổn định cho production.

sudo apt update
sudo apt install nginx -y

Sau khi cài, kiểm tra service đã chạy chưa:

sudo systemctl status nginx

Output mong đợi có dòng active (running). Nếu chưa chạy, khởi động và bật tự khởi động cùng hệ thống:

sudo systemctl enable --now nginx

Kiểm tra nhanh bằng cách truy cập IP VPS trên trình duyệt, bạn sẽ thấy trang welcome mặc định của Nginx. Nếu không thấy, kiểm tra firewall ở bước tiếp theo.

Bước 2 - Mở cổng 80 và 443 trên firewall

Ubuntu 24.04 dùng ufw. Nếu chưa bật thì bật và cho phép SSH, HTTP, HTTPS. Thứ tự này quan trọng, làm sai có thể khóa mất kết nối SSH nếu bạn đang dùng ufw mà chưa allow SSH.

sudo ufw allow OpenSSH
sudo ufw allow 'Nginx Full'
sudo ufw enable

Lệnh 'Nginx Full' mở cả cổng 80 và 443. Kiểm tra trạng thái:

sudo ufw status

Output phải có cả OpenSSHNginx Full ở trạng thái ALLOW. Nếu bạn dùng bản VPS có sẵn firewalld (AlmaLinux, Rocky) thì lệnh sẽ khác, dùng firewall-cmd thay cho ufw.

Bước 3 - Tạo cấu hình reverse proxy cho từng domain

Thay vì sửa file /etc/nginx/nginx.conf, tạo riêng một file trong /etc/nginx/sites-available/ cho mỗi ứng dụng. Cách này dễ quản lý khi sau này có thêm domain mới.

Tạo file cấu hình cho domain app.example.com:

sudo nano /etc/nginx/sites-available/app.example.com

Nội dung cơ bản nhất cho một reverse proxy:

server {
    listen 80;
    server_name app.example.com;

    location / {
        proxy_pass http://127.0.0.1:3000;
        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;
    }
}

Giải thích từng dòng:

  • proxy_pass http://127.0.0.1:3000: chuyển request về ứng dụng chạy trên cổng 3000. Nếu backend là Docker map cổng 8080 thì sửa thành http://127.0.0.1:8080.
  • proxy_set_header Host $host: giữ nguyên tên miền gốc khi chuyển tiếp, ứng dụng backend biết client gọi bằng domain nào.
  • proxy_set_header X-Real-IP $remote_addr: ghi IP thật của client, không phải IP của Nginx.
  • proxy_set_header X-Forwarded-For: chuỗi IP client qua các proxy trung gian.
  • proxy_set_header X-Forwarded-Proto $scheme: cho backend biết request gốc là HTTP hay HTTPS.

Kích hoạt site bằng cách tạo symlink vào sites-enabled:

sudo ln -s /etc/nginx/sites-available/app.example.com /etc/nginx/sites-enabled/

Xóa file mặc định để tránh conflict:

sudo rm /etc/nginx/sites-enabled/default

Kiểm tra cú pháp cấu hình trước khi reload:

sudo nginx -t

Output mong đợi là hai dòng syntax is oktest is successful. Nếu có lỗi, đọc kỹ dòng báo lỗi, thường là thiếu dấu chấm phẩy hoặc sai đường dẫn file. Reload Nginx để áp dụng:

sudo systemctl reload nginx

Lúc này truy cập http://app.example.com sẽ thấy ứng dụng của bạn, miễn là DNS đã trỏ đúng. Kiểm tra bằng curl từ chính VPS:

curl -I http://app.example.com

Output có mã 200 OK và header Server: nginx là thành công.

Bước 4 - Thêm cấu hình cho WebSocket và header đặc biệt

Nếu ứng dụng của bạn dùng WebSocket (chat, realtime notification, n8n), Nginx cần thêm vài dòng để upgrade giao thức. Thiếu bước này WebSocket sẽ không kết nối được, lỗi thường thấy là client cứ retry mãi.

location / {
    proxy_pass http://127.0.0.1:3000;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    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;
}

Dòng proxy_http_version 1.1 chuyển sang HTTP/1.1 vì WebSocket không hoạt động trên HTTP/1.0 mặc định của Nginx proxy. Hai dòng UpgradeConnection là tín hiệu báo Nginx giữ kết nối để nâng cấp lên WebSocket. Với các ứng dụng upload file lớn, thêm dòng này vào trong server:

client_max_body_size 50M;

Mặc định Nginx giới hạn body request 1MB, nếu app của bạn nhận upload ảnh hoặc file thì sẽ gặp lỗi 413 Request Entity Too Large. Đặt giá trị phù hợp với nhu cầu thực tế.

Bước 5 - Cấu hình HTTPS với Let's Encrypt

HTTP trần không an toàn cho production, nhất là khi ứng dụng có form đăng nhập. Cài Certbot để cấp SSL miễn phí từ Let's Encrypt. Trên Ubuntu 24.04, bản apt đã đủ dùng, không cần snap.

sudo apt install certbot python3-certbot-nginx -y

Chạy lệnh cấp chứng chỉ cho domain:

sudo certbot --nginx -d app.example.com

Certbot sẽ tự dò cấu hình Nginx, cấp chứng chỉ và sửa file config để bật HTTPS, đồng thời thêm cấu hình redirect HTTP sang HTTPS. Làm theo hướng dẫn trên màn hình, chọn 2 (redirect) khi được hỏi để tự động chuyển hướng.

Kiểm tra chứng chỉ đã được cấp:

sudo certbot certificates

Output hiện domain và ngày hết hạn. Certbot trên Ubuntu 24.04 tự cài timer gia hạn, kiểm tra bằng lệnh:

sudo systemctl list-timers | grep certbot

Truy cập https://app.example.com và kiểm tra ổ khóa trên trình duyệt là xong. Nếu cần cấp SSL wildcard cho nhiều subdomain, xem bài tự động cấp SSL wildcard với acme.sh.

Bước 6 - Chạy nhiều ứng dụng trên cùng một VPS

Điểm mạnh của reverse proxy là gom nhiều ứng dụng về một VPS. Giả sử bạn có thêm một instance n8n chạy trên cổng 5678, tạo thêm file cấu hình tương tự với domain khác:

sudo nano /etc/nginx/sites-available/n8n.example.com
server {
    listen 80;
    server_name n8n.example.com;

    location / {
        proxy_pass http://127.0.0.1:5678;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        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;
    }
}

Kích hoạt và reload như bước 3. Với nhiều ứng dụng, bạn có thể chạy Docker và để Nginx proxy sang các container. Xem thêm bài chạy nhiều site trên 1 VPS với Docker và Nginx proxy để biết cách kết hợp.

Xử lý lỗi thường gặp

Lỗi 502 Bad Gateway. Nginx không kết nối được backend. Kiểm tra ứng dụng đang chạy trên đúng cổng chưa:

ss -tlnp | grep :3000

Nếu không thấy output nghĩa là backend chưa chạy hoặc chạy trên cổng khác. Kiểm tra log lỗi Nginx để biết chi tiết:

sudo tail -f /var/log/nginx/error.log

Lỗi 404 khi truy cập domain nhưng IP lại vào được trang welcome. Thường do server block chưa được kích hoạt, hoặc file default vẫn còn trong sites-enabled. Kiểm tra:

ls -la /etc/nginx/sites-enabled/

WebSocket không kết nối. Thiếu hai dòng UpgradeConnection như đã nói ở bước 4. Kiểm tra log Nginx:

sudo journalctl -u nginx -f

Lỗi 413 Request Entity Too Large. Upload file bị chặn. Thêm client_max_body_size vào trong block server hoặc location rồi reload Nginx.

Câu hỏi thường gặp

Reverse proxy và load balancer khác nhau thế nào?

Reverse proxy chuyển request từ client đến một backend cụ thể dựa trên domain hoặc đường dẫn. Load balancer là một dạng reverse proxy nhưng phân phối request đến nhiều backend giống nhau để chia tải. Nginx làm được cả hai, khi bạn khai báo nhiều server trong upstream thì nó hoạt động như load balancer.

Có cần mở cổng ứng dụng trên firewall khi đã dùng Nginx không?

Không. Khi đã có Nginx reverse proxy, ứng dụng backend chỉ cần lắng nghe trên 127.0.0.1 (loopback), không cần mở cổng ra ngoài. Chỉ mở cổng 80 và 443 cho Nginx. Đây là cách an toàn nhất, backend không bị lộ trực tiếp với internet.

Nginx reverse proxy có làm chậm ứng dụng không?

Không đáng kể. Nginx xử lý hàng nghìn kết nối đồng thời với mức tiêu thụ bộ nhớ rất thấp, thường dưới 10-20MB RAM cho một server block cơ bản. Phần lớn thời gian xử lý vẫn nằm ở backend của bạn, chứ không phải ở lớp proxy.

Làm sao để biết Nginx đang chạy hay không?

Dùng lệnh sudo systemctl status nginx để xem trạng thái service. Nếu muốn kiểm tra nhanh xem Nginx có đang lắng nghe cổng 80 không, dùng ss -tlnp | grep :80. Output có dòng LISTEN và tên tiến trình nginx là đang chạy.

Có thể dùng Nginx reverse proxy cho nhiều domain trên một VPS 2GB RAM không?

Được. Nginx rất nhẹ, mỗi server block chỉ tốn vài MB RAM. Với VPS 2GB, bạn có thể chạy thoải mái 5-6 ứng dụng backend nhỏ phía sau Nginx, miễn là tổng RAM của các backend không vượt quá dung lượng máy. Xem thêm bài tối ưu Nginx cho VPS RAM thấp nếu cần.

Bài viết liên quan

Lưu ý: Bài viết mang tính tham khảo, tổng hợp kiến thức chung. Mỗi hệ thống, hạ tầng và nhu cầu có đặc thù riêng, nên kiểm thử trong môi trường an toàn và tham vấn kỹ sư trước khi triển khai thực tế.