Triển khai Next.js trên VPS Ubuntu chuẩn production từ A-Z

10/05/2026 · P T P · Chung

Triển khai Next.js trên VPS Ubuntu: Quy trình chuẩn, dễ áp dụng cho dự án thật

Triển khai Next.js lên VPS Ubuntu nghe đơn giản: git pull, npm run build, npm start. Nhưng dự án thật hiếm khi chỉ vậy. Bạn cần Node đúng phiên bản, process manager, reverse proxy, SSL, env, log, deploy lại không downtime, rollback khi lỗi.

Bài viết này đưa ra quy trình thực chiến: đủ chuẩn cho production, dễ áp dụng cho team nhỏ, startup, freelance project, SaaS MVP.


1. Kiến trúc triển khai đề xuất

Mô hình phổ biến:

User → Domain → Nginx → Next.js app → DB/API

Trong đó:

Ubuntu VPS: server chính.
Nginx: reverse proxy, xử lý domain, SSL, gzip, cache cơ bản.
Next.js app: chạy qua Node.js.
PM2: giữ app sống, tự restart khi crash.
Git: lấy source code.
Certbot: cấp SSL miễn phí từ Let’s Encrypt.

Ưu điểm:

– Dễ cài.
– Dễ debug.
– Không phụ thuộc nền tảng cloud đắt tiền.
– Phù hợp dự án thật: landing, dashboard, app nội bộ, e-commerce nhỏ, SaaS MVP.


2. Chuẩn bị VPS Ubuntu

Nên chọn:

– Ubuntu 22.04 LTS hoặc 24.04 LTS.
– RAM tối thiểu 1GB; khuyến nghị 2GB+.
– CPU 1 core trở lên.
– SSD.
– Quyền SSH root hoặc user sudo.

Đăng nhập:

ssh root@YOUR_SERVER_IP

Cập nhật hệ thống:

apt update && apt upgrade -y

Cài công cụ cơ bản:

apt install -y curl git ufw nginx

Tạo user deploy, tránh chạy app bằng root:

adduser deploy
usermod -aG sudo deploy

Chuyển sang user:

su - deploy

3. Cài Node.js đúng cách

Không nên dùng Node.js mặc định từ apt vì thường cũ. Dùng nvm linh hoạt hơn.

Cài nvm:

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash

Reload shell:

source ~/.bashrc

Cài Node LTS:

nvm install --lts
nvm use --lts
node -v
npm -v

Nếu dự án dùng phiên bản cụ thể, tạo file .nvmrc:

20

Sau đó:

nvm install
nvm use

Điểm quan trọng: local, CI, VPS nên dùng cùng version Node → giảm lỗi build.


4. Clone source code lên server

Tạo thư mục app:

mkdir -p ~/apps
cd ~/apps

Clone repo:

git clone [email protected]:your-org/your-next-app.git
cd your-next-app

Nếu dùng GitHub private repo, cần cấu hình SSH key:

ssh-keygen -t ed25519 -C "deploy@server"
cat ~/.ssh/id_ed25519.pub

Copy public key vào GitHub → Deploy keys hoặc SSH keys.

Test:

ssh -T [email protected]

5. Cấu hình biến môi trường

Next.js thường dùng .env.production.

Ví dụ:

nano .env.production

Nội dung mẫu:

NODE_ENV=production
NEXT_PUBLIC_SITE_URL=https://example.com
DATABASE_URL=postgresql://user:password@host:5432/db
NEXTAUTH_SECRET=your-secret
NEXTAUTH_URL=https://example.com

Lưu ý:

– Biến bắt đầu bằng NEXT_PUBLIC_ sẽ lộ ra client.
– Secret, token, DB URL không được dùng prefix này.
– Không commit .env.production lên Git.

Nên có file mẫu:

.env.example

Giúp người khác biết cần cấu hình gì.


6. Cài dependency, build Next.js

Cài package:

npm install

Nếu dự án dùng lockfile, nên dùng:

npm ci

Build:

npm run build

Chạy thử:

npm start

Mặc định Next.js chạy port 3000.

Kiểm tra:

curl http://localhost:3000

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


7. Chạy app bằng PM2

Cài PM2 global:

npm install -g pm2

Start app:

pm2 start npm --name "next-app" -- start

Kiểm tra:

pm2 status
pm2 logs next-app

Lưu process list:

pm2 save

Tự chạy lại sau reboot:

pm2 startup

PM2 sẽ in ra một command. Copy command đó, chạy lại.

Ví dụ:

sudo env PATH=$PATH:/home/deploy/.nvm/versions/node/v20.x.x/bin pm2 startup systemd -u deploy --hp /home/deploy

Sau đó:

pm2 save

Từ giờ server reboot → app tự bật lại.


8. Cấu hình Nginx reverse proxy

Tạo config:

sudo nano /etc/nginx/sites-available/next-app

Nội dung:

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

location / { proxy_pass http://localhost: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;

proxy_cache_bypass $http_upgrade; } }

Enable site:

sudo ln -s /etc/nginx/sites-available/next-app /etc/nginx/sites-enabled/

Test config:

sudo nginx -t

Reload:

sudo systemctl reload nginx

Trỏ DNS:

A    example.com        YOUR_SERVER_IP
A    www.example.com    YOUR_SERVER_IP

Sau DNS cập nhật, mở:

http://example.com

9. Cài SSL HTTPS bằng Certbot

Cài Certbot:

sudo apt install -y certbot python3-certbot-nginx

Cấp SSL:

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

Chọn redirect HTTP → HTTPS nếu được hỏi.

Test gia hạn:

sudo certbot renew --dry-run

Sau bước này:

https://example.com → Nginx → localhost:3000

Production app nên luôn dùng HTTPS, nhất là khi có auth, cookie, payment, admin dashboard.


10. Firewall cơ bản

Bật UFW:

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

Không mở port 3000 ra internet nếu không cần. Next.js chỉ nên nghe local qua Nginx.

Nếu app đang expose public port:

example.com:3000

→ không nên. Dùng reverse proxy thay thế.


11. Quy trình deploy mỗi lần cập nhật code

Một flow đơn giản:

cd ~/apps/your-next-app
git pull origin main
npm ci
npm run build
pm2 restart next-app

Có thể tạo script:

nano deploy.sh

Nội dung:

#!/bin/bash
set -e

cd ~/apps/your-next-app

git pull origin main npm ci npm run build pm2 restart next-app pm2 save

Cấp quyền:

chmod +x deploy.sh

Chạy:

./deploy.sh

set -e giúp script dừng nếu có lỗi. Tránh restart app khi build fail.


12. Tối ưu cho dự án thật

Dùng standalone output

Trong next.config.js:

module.exports = {
  output: 'standalone',
}

Build xong, Next.js tạo bundle gọn hơn. Phù hợp deploy production, Docker, CI/CD.

Bật cache static qua Nginx

Có thể cache file _next/static:

location /_next/static/ {
    proxy_pass http://localhost:3000;
    expires 1y;
    add_header Cache-Control "public, immutable";
}

Static assets có hash → cache dài an toàn.

Log rõ ràng

Xem log app:

pm2 logs next-app

Log Nginx:

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

Log là nơi đầu tiên cần xem khi:

– Trang trắng.
– 502 Bad Gateway.
– Build lỗi.
– Auth redirect sai.
– API trả 500.

Kiểm soát memory

VPS nhỏ dễ hết RAM khi build. Kiểm tra:

free -h
htop

Nếu RAM 1GB, nên tạo swap:

sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile

Lưu vĩnh viễn:

echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

13. Lỗi thường gặp

502 Bad Gateway

Nguyên nhân thường gặp:

– App chưa chạy.
– Sai port.
– PM2 crash.
– Nginx proxy sai.

Kiểm tra:

pm2 status
pm2 logs next-app
curl http://localhost:3000
sudo nginx -t

Environment variable không nhận

Sau khi sửa .env.production, cần build lại:

npm run build
pm2 restart next-app

Biến NEXT_PUBLIC_ được bake vào bundle lúc build.

Domain redirect sai khi dùng NextAuth

Kiểm tra:

NEXTAUTH_URL=https://example.com

Sai URL → callback lỗi, login loop, cookie sai domain.

Build trên server quá chậm

Giải pháp:

– Tăng RAM/swap.
– Build ở CI rồi upload artifact.
– Dùng Docker image build sẵn.
– Dùng server mạnh hơn.


14. Checklist production nhanh

Trước khi bàn giao:

Domain trỏ đúng IP.
HTTPS hoạt động.
Nginx reverse proxy ổn.
PM2 auto restart sau reboot.
.env.production đầy đủ.
Port 3000 không public.
Log kiểm tra được.
Deploy scriptset -e.
Backup DB nếu có dữ liệu thật.
Monitoring tối thiểu: uptime check.

Có thể dùng UptimeRobot, Better Stack, Grafana Cloud hoặc cron đơn giản để ping endpoint health.


Kết luận

Triển khai Next.js trên VPS Ubuntu không khó nếu đi đúng quy trình: Node LTS → build production → PM2 → Nginx → SSL → firewall → deploy script. Đây là stack gọn, rẻ, dễ kiểm soát, đủ tốt cho nhiều dự án thật.

Khi app lớn hơn, bạn có thể nâng cấp dần: CI/CD, Docker, blue-green deploy, load balancer, object storage, managed database. Nhưng nền tảng vẫn vậy: server rõ ràng, config rõ ràng, log rõ ràng, rollback được.

Bắt đầu đơn giản. Chuẩn hóa sớm. Production sẽ bớt đau.

#khai #next #tren #trien #ubuntu
Chia sẻ:
← Trước
Cấu hình SSL miễn phí cho Next.js trên VPS bằng Let’s Encrypt

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!