Hướng Dẫn Chạy Node.js Trên VPS Ubuntu Với PM2 2026

Hướng dẫn triển khai ứng dụng Node.js trên VPS Ubuntu với PM2: cài Node.js, chạy app, quản lý process, tự khởi động sau reboot, log và cập nhật phiên bản an toàn.

Nếu bạn có API, website SSR hoặc ứng dụng backend Node.js, chạy trực tiếp bằng `node app.js` chỉ phù hợp khi thử nghiệm. Khi đưa lên VPS, bạn cần một process manager để ứng dụng tiếp tục chạy sau khi thoát SSH, tự khởi động lại khi gặp lỗi và phục hồi sau reboot. Bài này hướng dẫn quy trình thực tế với Node.js và PM2 trên Ubuntu, tập trung vào cách triển khai dễ kiểm tra và không làm rối cấu trúc server.

Điểm quan trọng Hãy lựa chọn dịch vụ dựa trên nhu cầu sử dụng thực tế và theo dõi tài nguyên thường xuyên để có hiệu quả tốt nhất.

1. Khi nào nên dùng PM2 trên VPS?

PM2 là process manager cho ứng dụng Node.js. Nó giúp bạn quản lý tiến trình, xem trạng thái, đọc log, restart app và thiết lập cơ chế khởi động lại sau reboot.

Mô hình cơ bản:

Client → Nginx hoặc reverse proxy → Node.js → PM2 → VPS Ubuntu

Nếu ứng dụng chỉ chạy thử trong vài phút, node app.js có thể đủ. Với production, PM2 hữu ích khi cần một quy trình quản lý process rõ ràng.

2. Kiểm tra VPS trước khi cài

Đăng nhập SSH và kiểm tra hệ điều hành:

cat /etc/os-release
uname -m
free -h
df -h

Nên bảo đảm VPS còn đủ RAM và dung lượng cho ứng dụng, dependency và log. Đừng chọn tài nguyên chỉ dựa trên số lượng file JavaScript; workload API, SSR, worker và WebSocket có thể rất khác nhau.

3. Cài Node.js theo phiên bản ứng dụng yêu cầu

Trước tiên kiểm tra project có file .nvmrc, package.json hoặc tài liệu chỉ rõ phiên bản Node.js hay không.

Sau khi cài Node.js bằng phương pháp phù hợp với môi trường của bạn, kiểm tra:

node -v
npm -v

Không nên tự động nâng Node.js trên production chỉ vì có phiên bản mới. Hãy kiểm tra compatibility của framework và dependency trước.

4. Đưa source code lên VPS

Một cấu trúc đơn giản:

/var/www/my-node-app/
├── package.json
├── package-lock.json
├── src/
└── .env

Nếu dùng user triển khai riêng, có thể đặt source trong home của user hoặc một thư mục /var/www có owner phù hợp.

Không commit .env, private key hoặc secret vào repository công khai.

5. Cài dependency

Đi vào thư mục ứng dụng:

cd /var/www/my-node-app
npm ci

npm ci phù hợp khi project có lockfile và bạn muốn cài đúng dependency đã khóa. Với project không có lockfile, dùng quy trình package manager tương ứng.

Nếu ứng dụng có bước build:

npm run build

Kiểm tra trước bằng cách chạy foreground:

npm start

Nếu app listen ở 127.0.0.1:3000, hãy mở terminal khác và kiểm tra:

curl -I http://127.0.0.1:3000

Chỉ chuyển sang PM2 sau khi ứng dụng chạy ổn ở foreground.

6. Cài PM2

Có thể cài PM2 global:

sudo npm install -g pm2

Kiểm tra:

pm2 -v

7. Chạy Node.js bằng PM2

Nếu entry point là app.js:

cd /var/www/my-node-app
pm2 start app.js --name my-node-app

Kiểm tra:

pm2 status

Nếu ứng dụng dùng script trong package.json:

pm2 start npm --name my-node-app -- start

Cách thứ hai hữu ích khi project có command khởi động riêng như npm start.

8. Kiểm tra process và log

Xem danh sách app:

pm2 list

Xem chi tiết:

pm2 show my-node-app

Xem log realtime:

pm2 logs my-node-app

Chỉ xem một số dòng gần nhất:

pm2 logs my-node-app --lines 100

Nếu app tự restart liên tục, đừng chỉ restart tiếp. Hãy đọc log để tìm lỗi dependency, biến môi trường, port hoặc exception.

9. Thiết lập tự khởi động sau reboot

PM2 có thể tạo startup configuration:

pm2 startup

Lệnh sẽ in ra một command cần chạy với quyền phù hợp. Hãy chạy đúng command mà PM2 cung cấp, sau đó lưu process list:

pm2 save

Kiểm tra lại sau khi reboot:

sudo reboot

Sau khi SSH lại:

pm2 status

Không nên coi pm2 save là backup source code. Nó chỉ lưu danh sách process/config để PM2 phục hồi.

10. Đặt biến môi trường cho ứng dụng

Ví dụ app cần:

NODE_ENV=production
PORT=3000
DATABASE_URL=...

Không nên hard-code secret trong source. Bạn có thể quản lý environment bằng cơ chế phù hợp với deployment của mình.

Nếu thay đổi biến môi trường, cần reload/restart process để app nhận giá trị mới:

pm2 restart my-node-app

11. Chạy nhiều ứng dụng Node.js trên một VPS

PM2 cho phép đặt tên riêng:

pm2 start app.js --name api
pm2 start server.js --name frontend
pm2 start worker.js --name worker

Sau đó:

pm2 status

Tuy nhiên, nhiều process không có nghĩa VPS có thể chạy vô hạn workload. Hãy theo dõi RAM, CPU và số kết nối thực tế.

12. Dùng ecosystem file để quản lý deployment

Khi có nhiều thiết lập, tạo ecosystem.config.js:

module.exports = {
  apps: [{
    name: 'my-node-app',
    script: './app.js',
    instances: 1,
    exec_mode: 'fork',
    env: {
      NODE_ENV: 'production',
      PORT: 3000
    }
  }]
};

Khởi động:

pm2 start ecosystem.config.js

Đây là cách dễ đọc hơn khi project có nhiều tham số.

13. Khi nào nên dùng cluster mode?

Nếu ứng dụng CPU-bound hoặc cần tận dụng nhiều core, PM2 có cluster mode. Nhưng không nên bật cluster chỉ vì VPS có nhiều vCPU.

Trước khi scale process, hãy kiểm tra:

  • ứng dụng có state local không;
  • session có lưu trong memory không;
  • WebSocket có yêu cầu sticky session không;
  • database có chịu được số connection tăng không;
  • workload có thực sự bị giới hạn bởi một process hay không.

Scale process mà không kiểm tra dependency có thể làm hệ thống khó ổn định hơn.

14. Đưa Node.js ra Internet bằng Nginx

Thông thường không cần mở port 3000 public. Có thể để Node.js listen trên localhost và dùng Nginx làm reverse proxy.

Mô hình:

Internet → 443 → Nginx → 127.0.0.1:3000 → Node.js

Ví dụ phần proxy trong server block:

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

Sau khi sửa, kiểm tra:

sudo nginx -t
sudo systemctl reload nginx

15. Cập nhật ứng dụng Node.js an toàn

Một quy trình đơn giản:

  1. backup hoặc bảo đảm có thể rollback;
  2. lấy source mới;
  3. kiểm tra dependency;
  4. chạy test/build;
  5. restart PM2;
  6. kiểm tra health endpoint và log.

Ví dụ:

git pull
npm ci
npm run build
pm2 restart my-node-app
pm2 logs my-node-app --lines 100

Không nên git pull trực tiếp vào production nếu quy trình deployment của bạn chưa kiểm soát migration và thay đổi cấu hình.

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

App không start

Kiểm tra:

pm2 logs my-node-app --lines 200
pm2 show my-node-app

Port đã được sử dụng

Kiểm tra:

sudo ss -ltnp | grep ':3000'

App chạy nhưng Nginx trả 502

Kiểm tra app:

curl -I http://127.0.0.1:3000
pm2 status

Sau đó xem error log Nginx.

App restart liên tục

Xem log và kiểm tra memory:

pm2 logs my-node-app --lines 200
free -h

Có thể ứng dụng crash do config, dependency hoặc bị OOM. Không nên kết luận nguyên nhân chỉ từ việc process đã restart.

17. Checklist production

  • Node.js version phù hợp project.
  • Dependency được khóa bằng lockfile.
  • Secret không nằm trong repository public.
  • App chạy bằng user phù hợp, không cần root.
  • PM2 quản lý process.
  • PM2 startup đã cấu hình nếu cần.
  • Node.js không mở public port nếu không cần.
  • Nginx reverse proxy đã kiểm tra bằng nginx -t.
  • Có log và cách xử lý khi app crash.
  • Có backup và quy trình rollback.
  • CPU/RAM/disk được theo dõi.

18. Kết luận

Chạy Node.js trên VPS không chỉ là cài Node rồi giữ một terminal SSH mở. Với PM2, bạn có thể quản lý process, log, restart và khởi động lại ứng dụng sau reboot theo một quy trình rõ ràng. Khi kết hợp Nginx reverse proxy, Node.js có thể chạy phía sau cổng web công khai thay vì mở trực tiếp port ứng dụng.

Điểm quan trọng nhất là triển khai theo từng lớp: kiểm tra app ở foreground, đưa vào PM2, cấu hình startup, đặt environment an toàn, sau đó mới kết nối reverse proxy và theo dõi tài nguyên.

Kết luận

Nếu chưa chắc cấu hình hoặc loại dịch vụ nào phù hợp, hãy gửi nhu cầu thực tế để đội ngũ hỗ trợ tư vấn trước khi mua.

Chưa biết nên chọn gói nào?

Xem bảng giá VPS hoặc liên hệ đội ngũ hỗ trợ để chọn cấu hình phù hợp.

Xem bảng giá VPS →