Cài đặt và tối ưu Nginx làm reverse proxy trên Ubuntu 24.04

SSH vào VPS Ubuntu 24.04 mới tinh, bạn cài một app Node.js chạy port 3000, một WordPress chạy PHP-FPM port 9000, và một API Python chạy port 5000. Làm sao để cả ba đều phục vụ qua port 80/443 với domain riêng, mà không xung đột? Câu trả lời là Nginx reverse proxy. Bài này hướng dẫn bạn cài đặt, cấu hình, và tối ưu Nginx làm reverse proxy trên Ubuntu 24.04, từ thiết lập location cơ bản đến tuning worker cho hàng nghìn kết nối đồng thời.
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 dùng root). Nếu chưa có, bạn có thể thuê VPS NVMe full root để làm theo bài này.
- Domain trỏ về IP VPS (record A). Giả sử dùng
api.example.comvàblog.example.com. - Port 80 và 443 mở trên firewall. Bài dùng ufw.
- Cơ bản về SSH và command line.
Bước 1, Cài đặt Nginx
Ubuntu 24.04 repo có Nginx 1.24 hoặc 1.26 (tùy thời điểm). Cài bản stable mới nhất:
sudo apt update
sudo apt install nginx -y
Kiểm tra version và trạng thái:
nginx -v
sudo systemctl status nginx
Output mong đợi: active (running). Nếu chưa chạy, start manual:
sudo systemctl enable --now nginx
Mở port cần thiết trên ufw:
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw reload
Kiểm tra với browser hoặc curl: curl -I http://<IP_VPS>, thấy HTTP/1.1 200 OK là Nginx chạy.
Bước 2, Cấu hình reverse proxy cơ bản cho một ứng dụng
Giả sử bạn có app Node.js chạy ở 127.0.0.1:3000. Tạo một server block proxy domain api.example.com về backend đó.
Tạo file cấu hình mới:
sudo nano /etc/nginx/sites-available/api.example.com
Nội dung:
server {
listen 80;
server_name api.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;
}
}
proxy_passTrỏ request đến backend, có thể là TCP (127.0.0.1:3000) hoặc Unix socket (unix:/run/app.sock).
proxy_set_headerTruyền thông tin gốc của client (IP thật, scheme) vào backend. App của bạn sẽ đọc header X-Real-IP thay vì IP của Nginx.
Enable site và kiểm tra config:
sudo ln -s /etc/nginx/sites-available/api.example.com /etc/nginx/sites-enabled/
sudo nginx -t
Nếu output test is successful, reload Nginx:
sudo systemctl reload nginx
Verify: curl -H "Host: api.example.com" http://localhost, output phải trả về từ app backend.
Bước 3, Reverse proxy nhiều upstream và WebSocket
Khi bạn cần load balance giữa nhiều backend instance, dùng khối upstream. Ví dụ 3 app server cùng port 3000 trên các IP khác nhau:
upstream backend_api {
least_conn;
server 127.0.0.1:3000 weight=3;
server 10.0.0.2:3000;
server 10.0.0.3:3000 backup;
}
server {
listen 80;
server_name api.example.com;
location / {
proxy_pass http://backend_api;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# ... các header khác
}
}
proxy_http_version 1.1 + Upgrade/Connection là bắt buộc nếu backend dùng WebSocket. Nếu không, WebSocket sẽ fail với lỗi WebSocket is closed before the connection is established.
Nếu chỉ một backend nhưng cần WebSocket (vd socket.io), vẫn thêm 3 dòng trên.
Bước 4, Buffer, timeout, và caching
Mặc định Nginx buffer response từ backend trước khi gửi về client. Với file lớn hoặc streaming, bạn cần tinh chỉnh. Thêm vào trong http block hoặc server/location:
proxy_buffering on;
proxy_buffer_size 4k;
proxy_buffers 8 16k;
proxy_busy_buffers_size 32k;
Timeout tránh backend treo làm Nginx treo theo:
proxy_connect_timeout 10s;
proxy_send_timeout 30s;
proxy_read_timeout 60s;
Với nội dung tĩnh (ảnh, CSS, JS) có thể cache ngay tại Nginx:
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=static_cache:10m max_size=1g inactive=60m use_temp_path=off;
location /static/ {
proxy_pass http://backend_app;
proxy_cache static_cache;
proxy_cache_valid 200 302 60m;
proxy_cache_valid 404 1m;
add_header X-Cache-Status $upstream_cache_status;
}
Header X-Cache-Status giúp debug: HIT = cache, MISS = fetch từ backend. Kiểm tra bằng curl -I https://api.example.com/static/style.css | grep X-Cache.
Bước 5, HTTPS với Let's Encrypt (Certbot)
Dùng Certbot tự động cấp và renew SSL:
sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d api.example.com -d blog.example.com
Certbot tự sửa file cấu hình Nginx, thêm listen 443 ssl và redirect HTTP → HTTPS. Kiểm tra sau khi chạy:
sudo nginx -t
curl -I https://api.example.com
Output trả về HTTP/2 200 (Nginx mặc định hỗ trợ HTTP/2 khi có SSL).
Renew tự động: Certbot tạo systemd timer, sudo systemctl status certbot.timer.
Bước 6, Tối ưu worker và keepalive cho traffic cao
Với VPS NVMe có nhiều core, mặc định Nginx chỉ dùng 1 worker. Tăng lên, sửa /etc/nginx/nginx.conf:
worker_processes auto;
worker_rlimit_nofile 65535;
events {
worker_connections 4096;
use epoll;
multi_accept on;
}
http {
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
keepalive_requests 1000;
# ... phần còn lại
}
worker_processes auto= số core CPU.worker_connections 4096= mỗi worker xử lý tối đa 4096 kết nối đồng thời. Với 4 core, total ~16384 kết nối.epolllà event loop hiệu quả nhất trên Linux.keepalive_requests 1000= tái sử dụng kết nối keepalive cho nhiều request.
Kiểm tra lại config và reload:
sudo nginx -t && sudo systemctl reload nginx
Dùng ss -s và top để xem số kết nối và tải worker.
Xử lý lỗi thường gặp
502 Bad Gateway
Nginx không kết nối được backend. Kiểm tra:
curl http://127.0.0.1:3000 # backend chạy không?
sudo journalctl -u nginx -n 20 --no-pager
Nguyên nhân thường: backend crash, sai port, hoặc firewall chặn loopback.
upstream sent too big header
Backend gửi header quá lớn. Thêm trong server hoặc http:
proxy_buffer_size 8k;
proxy_buffers 8 32k;
WebSocket liên tục disconnect
Thiếu proxy_http_version 1.1 và header Upgrade. Verify lại cấu hình vùng location có WebSocket.
Câu hỏi thường gặp
Reverse proxy có ảnh hưởng hiệu năng không?
Nginx reverse proxy thêm vài microsecond latency, nhưng bù lại tận dụng được kernel zero-copy, keepalive, và caching. Với hầu hết ứng dụng, overhead không đáng kể.
Có thể dùng Nginx làm reverse proxy cho nhiều domain cùng lúc?
Có. Mỗi domain một file server block riêng trong /etc/nginx/sites-available/, mỗi block trỏ về backend khác nhau. Enable tất cả, Nginx phân giải dựa trên header Host.
Làm sao để log request từ reverse proxy?
Thêm trong server block:
access_log /var/log/nginx/api_access.log;
error_log /var/log/nginx/api_error.log;
Xem log realtime: tail -f /var/log/nginx/api_access.log.
Nên dùng Nginx hay Caddy cho reverse proxy?
Caddy tự động xử lý HTTPS và cấu hình đơn giản hơn, nhưng Nginx linh hoạt hơn về tuning và có hệ sinh thái module lớn. Nếu cần tối ưu traffic cao, Nginx là lựa chọn hàng đầu.
Cấu hình trên có áp dụng cho VPS Windows được không?
Nginx có bản Windows, nhưng production trên Linux vẫn ổn định và hiệu năng tốt hơn. Nếu cần VPS Windows, bạn nên dùng IIS với ARR module làm reverse proxy.
Mất bao lâu để hoàn tất cấu hình cơ bản?
Khoảng 15-30 phút nếu đã có VPS và domain sẵn. Thời gian chính là debug nếu gặp lỗi.
Bài viết liên quan
- Tối ưu Nginx cho traffic cao, worker, gzip, buffer, cache
- Dùng WireGuard VPN trên VPS trong 10 phút
- Cấu hình ufw firewall cơ bản trên Ubuntu VPS
- Reverse proxy với HTTPS tự động bằng Caddy


