Cấu hình SSL miễn phí cho Next.js trên VPS bằng Let’s Encrypt

10/05/2026 · P T P · Chung

Cách cấu hình SSL miễn phí cho website Next.js chạy trên VPS với Let’s Encrypt

Website không có HTTPS → trình duyệt cảnh báo, người dùng mất niềm tin, SEO giảm, API dễ lỗi khi gọi từ frontend. Với ứng dụng Next.js chạy trên VPS, cấu hình SSL không khó nếu dùng Let’s Encrypt + Nginx + Certbot. Chi phí: . Hiệu quả: domain có ổ khóa xanh, tự động gia hạn, bảo mật tốt hơn.

Bài viết này hướng dẫn cấu hình SSL miễn phí cho website Next.js deploy trên VPS Ubuntu, chạy bằng Node.js/PM2, reverse proxy qua Nginx.


Mô hình triển khai phổ biến

Kiến trúc thường dùng:

Next.js app chạy nội bộ tại localhost:3000
Nginx nhận req từ internet qua port 80/443
Let’s Encrypt cấp SSL cert cho domain
Certbot tự động cấu hình HTTPS cho Nginx
PM2 giữ app luôn chạy

Luồng req:

User → https://domain.com → Nginx:443 → localhost:3000 → Next.js

Next.js không cần tự xử lý SSL. Nginx làm TLS termination → nhẹ, chuẩn, dễ bảo trì.


Điều kiện trước khi cấu hình SSL

Trước khi chạy Certbot, cần đảm bảo các điểm sau.

1. VPS đã trỏ domain đúng IP

Trong DNS provider, tạo bản ghi:

A     @      YOUR_VPS_IP
A     www    YOUR_VPS_IP

Ví dụ:

example.com      → 123.123.123.123
www.example.com  → 123.123.123.123

Kiểm tra:

ping example.com
dig example.com

Nếu domain chưa trỏ đúng IP → Let’s Encrypt không xác minh được → cấp SSL thất bại.

2. VPS mở port 80 và 443

Let’s Encrypt cần truy cập HTTP port 80 để xác minh domain. HTTPS dùng port 443.

Nếu dùng UFW:

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

Kết quả nên có:

80/tcp  ALLOW
443/tcp ALLOW
22/tcp  ALLOW

3. Next.js app đã chạy ổn

Ví dụ app chạy bằng PM2:

npm install
npm run build
pm2 start npm --name "next-app" -- start
pm2 save
pm2 startup

Kiểm tra local:

curl http://localhost:3000

Nếu có HTML trả về → app OK.


Cài Nginx trên VPS

Với Ubuntu/Debian:

sudo apt update
sudo apt install nginx -y

Kiểm tra:

sudo systemctl status nginx

Nếu active → OK.

Mở trình duyệt:

http://YOUR_VPS_IP

Thấy trang mặc định Nginx → web server hoạt động.


Cấu hình Nginx reverse proxy cho Next.js

Tạo file config cho domain:

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

Nội dung ban đầu, chưa SSL:

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

server_name example.com www.example.com;

location / { proxy_pass http://localhost:3000; proxy_http_version 1.1;

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_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } }

Giải thích nhanh:

server_name → domain Nginx nhận req
proxy_pass → chuyển req vào Next.js
X-Forwarded-Proto → app biết req gốc là HTTP/HTTPS
Upgrade + Connection → hỗ trợ websocket, hot reload, realtime nếu có

Kích hoạt site:

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

Xóa default nếu cần:

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

Test config:

sudo nginx -t

Reload:

sudo systemctl reload nginx

Mở:

http://example.com

Nếu thấy website Next.js → sẵn sàng cấp SSL.


Cài Certbot và plugin Nginx

Certbot là tool chính thức để xin/gia hạn cert Let’s Encrypt.

Ubuntu:

sudo apt install certbot python3-certbot-nginx -y

Kiểm tra:

certbot --version

Cấp SSL miễn phí với Let’s Encrypt

Chạy lệnh:

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

Certbot sẽ hỏi email, điều khoản, redirect HTTPS. Nên chọn redirect toàn bộ HTTP → HTTPS.

Quy trình:

1. Certbot đọc Nginx config.
2. Let’s Encrypt xác minh domain qua port 80.
3. Certbot tải cert về VPS.
4. Certbot tự sửa Nginx config.
5. Nginx reload.
6. Website có HTTPS.

Sau khi thành công, sẽ thấy dạng:

Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/example.com/fullchain.pem
Key is saved at: /etc/letsencrypt/live/example.com/privkey.pem

Mở:

https://example.com

Nếu hiện ổ khóa → xong.


Nginx config sau khi có SSL

Certbot thường tự thêm block HTTPS. Config sẽ gần giống:

server {
    server_name example.com www.example.com;

location / { proxy_pass http://localhost:3000; proxy_http_version 1.1;

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_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; }

listen [::]:443 ssl ipv6only=on; listen 443 ssl;

ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; }

server { if ($host = www.example.com) { return 301 https://$host$request_uri; }

if ($host = example.com) { return 301 https://$host$request_uri; }

listen 80; listen [::]:80;

server_name example.com www.example.com; return 404; }

Có thể tối ưu redirect domain chính. Ví dụ muốn www → non-www:

server {
    listen 443 ssl;
    server_name www.example.com;

ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

return 301 https://example.com$request_uri; }

Mục tiêu: chỉ giữ một canonical domain → SEO gọn hơn.


Kiểm tra tự động gia hạn SSL

Let’s Encrypt cert có hạn 90 ngày. Certbot tự tạo timer gia hạn.

Kiểm tra:

systemctl list-timers | grep certbot

Test renew:

sudo certbot renew --dry-run

Nếu output không lỗi → auto-renew OK.

Cert thường được gia hạn khi còn dưới 30 ngày. Không cần cron thủ công nếu systemd timer đã có.


Lỗi thường gặp và cách xử lý

Domain chưa trỏ đúng IP

Lỗi thường gặp:

unauthorized
connection refused
timeout during connect

Nguyên nhân:

– DNS chưa cập nhật
– Trỏ sai IP
– Proxy/CDN đang che IP
– Port 80 bị chặn

Fix:

dig example.com
sudo ufw status
sudo systemctl status nginx

Chờ DNS propagation nếu mới chỉnh.

Nginx config lỗi

Kiểm tra:

sudo nginx -t

Nếu lỗi syntax → sửa file trong:

/etc/nginx/sites-available/example.com

Reload sau khi sửa:

sudo systemctl reload nginx

Next.js không phản hồi sau proxy

Kiểm tra app:

pm2 status
curl http://localhost:3000

Nếu app chết:

pm2 restart next-app
pm2 logs next-app

Nếu app chạy port khác, sửa:

proxy_pass http://localhost:YOUR_PORT;

Mixed content

HTTPS site nhưng gọi asset/API bằng HTTP → trình duyệt chặn.

Fix:

– Đổi API URL sang https://
– Dùng biến môi trường đúng:

NEXT_PUBLIC_API_URL=https://api.example.com

Rebuild app:

npm run build
pm2 restart next-app

Tăng bảo mật SSL thêm một bước

Sau khi SSL hoạt động, có thể thêm security headers trong Nginx:

add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header X-XSS-Protection "1; mode=block" always;

HSTS chỉ bật khi chắc chắn website luôn dùng HTTPS:

add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

Cảnh báo: HSTS khiến browser ép dùng HTTPS lâu dài. Nếu cert/config lỗi → user có thể không truy cập được bằng HTTP fallback.

Test SSL:

https://www.ssllabs.com/ssltest/

Mục tiêu: grade A/A+.


Checklist triển khai nhanh

– Domain A record → VPS IP
– Port 80/443 mở
– Next.js chạy tại localhost:3000
– Nginx reverse proxy OK qua HTTP
– Certbot installed
– Chạy:

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

– Test:

sudo certbot renew --dry-run

– Kiểm tra browser:

https://example.com

Kết luận

Cấu hình SSL miễn phí cho Next.js trên VPS không cần phức tạp. Cách ổn định nhất: để Next.js chạy nội bộ, dùng Nginx làm reverse proxy, dùng Let’s Encrypt/Certbot cấp HTTPS. Mô hình này dễ deploy, dễ debug, hỗ trợ auto-renew, phù hợp từ website cá nhân đến production app.

Nếu làm đúng thứ tự — DNS → Nginx → proxy → Certbot → renew test — quá trình thường chỉ mất 10-15 phút. Quan trọng nhất: domain phải trỏ đúng VPS, port 80/443 mở, Next.js app chạy ổn trước khi xin cert. Khi SSL đã hoạt động, hãy kiểm tra mixed content, auto-renew, security headers để website vừa an toàn vừa chuyên nghiệp.

#bang #hinh #mien #next #tren
Chia sẻ:
← Trước
Next.js trên VPS hay sập? 7 lỗi thường gặp và cách xử lý nhanh

Bài viết tương tự

Bình luận

Chưa có bình luận. Hãy là người đầu tiên!