- PM2 là process manager chuẩn vàng cho Node.js production: auto-restart khi crash, cluster mode tận dụng multi-core, log rotation tự động.
- Cài 30 giây bằng npm. Start app: pm2 start "npm run start" --name myapp. Khởi động cùng OS: pm2 startup + pm2 save.
- Cluster mode chia traffic ra N worker (= số CPU core), giúp Node tận dụng full CPU thay vì 1 core.
- pm2-logrotate plugin rotate log mỗi ngày, giữ 7 ngày, max 50MB/file, gzip cũ.
- Bài này hướng dẫn full: install, start, cluster, log, monit, ecosystem.config.js, zero-downtime reload, debug khi app crash loop.
Node.js single-threaded, một app crash là dừng hoàn toàn. Trên VPS production, bạn không thể SSH vào restart mỗi lần memory leak hoặc unhandled promise. PM2 giải quyết bài toán này: theo dõi app, auto-restart khi crash, multiplex traffic qua nhiều worker, rotate log để disk không full. Đây là tool số 1 mà dev Node nên cài trên mỗi VPS production.
Bài này hướng dẫn từ A đến Z: cài PM2, start app đơn, mở cluster mode, cấu hình log rotation, viết ecosystem.config.js cho multi-app, zero-downtime reload khi deploy, debug khi app rơi vào crash loop. Tất cả test trên Cloud VPS 50 với Node.js 22 LTS và Ubuntu 24.04.
PM2 là gì và tại sao dùng?
PM2 (Process Manager 2) là daemon viết bằng Node.js do KeyMetrics phát triển từ 2013. Nó wrap một hoặc nhiều Node app, làm:
- Auto-restart khi crash, kèm exponential backoff để tránh loop CPU 100 phần trăm.
- Cluster mode: chạy N worker, load balance traffic qua chúng (built-in của Node http server).
- Log management: capture stdout/stderr ra file, rotate hằng ngày.
- Health monitoring: CPU, RAM, uptime mỗi process.
- Khởi động cùng OS: tạo systemd unit tự động.
- Zero-downtime reload: cập nhật code mới không drop request.
Alternative: systemd unit riêng cho mỗi app (verbose hơn), Forever (đã cũ), Nodemon (chỉ dev), Docker (overkill cho app nhỏ). PM2 cân bằng tốt nhất cho dev solo và team nhỏ.
Bước 1: Cài PM2
sudo npm install -g pm2
pm2 --version
which pm2
Nếu chưa có Node, cài qua nodesource hoặc nvm:
curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
sudo apt install -y nodejs
Bước 2: Start app đơn giản
cd /var/www/myapp
pm2 start "npm run start" --name myapp
pm2 status
Output bảng status: pid, status (online), restart count, CPU, mem. App đã chạy background, console của bạn rảnh để làm việc khác.
Test crash auto-restart:
kill -9 $(pm2 pid myapp)
pm2 status
Sau 1-2 giây, PM2 đã restart app. Restart count tăng lên 1.
Bước 3: Khởi động cùng OS (systemd integration)
pm2 startup
# Copy lệnh PM2 in ra, paste và chạy (cần sudo)
pm2 save
Lệnh đầu sinh ra systemd unit file. Lệnh sau lưu state hiện tại của PM2 (danh sách app đang chạy). Sau reboot VPS, systemd start PM2, PM2 đọc state đã save và start lại các app. Hoàn toàn tự động, không cần can thiệp.
Bước 4: Cluster mode tận dụng multi-core
pm2 start "npm run start" --name myapp -i max
# Hoặc số worker cụ thể
pm2 start "npm run start" --name myapp -i 4
Cờ -i max sinh N worker = số CPU core. PM2 dùng Node.js cluster module built-in: master process bind port, fork N child, dùng SO_REUSEPORT chia traffic. App của bạn không cần thay đổi code, miễn là listen trên 0.0.0.0 (hoặc default).
Trên Cloud VPS 50 có 2 core, cluster mode tăng throughput từ ~5000 req/s lên ~9500 req/s cho Express endpoint trả JSON ngắn. Gấp đôi gần như tuyến tính.
Bước 5: Log management và rotate
PM2 tự capture stdout, stderr vào ~/.pm2/logs/{app-name}-out.log và -error.log. Xem realtime:
pm2 logs myapp
pm2 logs myapp --lines 200
pm2 logs --err
Log mặc định không rotate, sau vài tuần có thể 1-2GB. Cài plugin pm2-logrotate:
pm2 install pm2-logrotate
pm2 set pm2-logrotate:max_size 50M
pm2 set pm2-logrotate:retain 7
pm2 set pm2-logrotate:compress true
pm2 set pm2-logrotate:rotateInterval '0 0 * * *'
Cấu hình trên: rotate mỗi ngày 0 giờ, giữ 7 file gần nhất, max 50MB mỗi file, compress file cũ với gzip. Disk usage ổn định không tăng theo thời gian.
Bước 6: ecosystem.config.js cho multi-app
Khi chạy 5-10 app trên cùng VPS, viết command pm2 start dài dòng. Thay bằng file config:
module.exports = {
apps: [
{
name: "api",
script: "npm",
args: "run start",
cwd: "/var/www/api",
instances: 2,
exec_mode: "cluster",
env: { NODE_ENV: "production", PORT: 4000 },
max_memory_restart: "500M",
error_file: "/var/log/pm2/api-err.log",
out_file: "/var/log/pm2/api-out.log",
},
{
name: "web",
script: "node_modules/.bin/next",
args: "start -p 3000",
cwd: "/var/www/web",
instances: 1,
exec_mode: "fork",
env: { NODE_ENV: "production" },
},
{
name: "worker",
script: "dist/worker.js",
cwd: "/var/www/worker",
instances: 1,
cron_restart: "0 4 * * *",
},
],
};
Start tất cả:
pm2 start ecosystem.config.js
pm2 save
File này commit vào git repo, mỗi deploy chỉ cần pull và pm2 reload ecosystem.config.js.
Bước 7: Zero-downtime reload
cd /var/www/api
git pull
npm install
npm run build
pm2 reload api
Lệnh reload (khác với restart) hoạt động theo rolling: PM2 start worker mới, gửi SIGINT cho worker cũ, đợi nó drain connection rồi kill. User không thấy 502 vì luôn có ít nhất 1 worker phục vụ.
Lưu ý: zero-downtime chỉ work khi cluster mode (instances >= 2). Fork mode bị downtime ngắn 1-3 giây.
Bước 8: max_memory_restart - bảo hiểm memory leak
Node app dễ memory leak (closures, event listener không cleanup, large object trong closure). Đặt max_memory_restart để PM2 tự restart khi vượt ngưỡng:
pm2 start "npm run start" --name myapp
--max-memory-restart 500M
--restart-delay 5000
Vượt 500MB, PM2 graceful restart. Delay 5 giây giữa các restart để tránh CPU spike. Tính năng này đã cứu nhiều app production trong khi dev chưa fix được nguyên nhân leak.
Bước 9: Monitor real-time
pm2 monit
pm2 status
pm2 info myapp
pm2 monit hiển thị TUI dashboard với CPU, RAM, log realtime của từng app. Đẹp và đủ thông tin cho 90 phần trăm debug daily.
Bước 10: Tích hợp với Caddy/Nginx
PM2 chỉ chạy app. Phía trước cần reverse proxy:
api.your-domain.com {
reverse_proxy localhost:4000
encode gzip
}
app.your-domain.com {
reverse_proxy localhost:3000
encode gzip
}
Caddy nhận HTTPS, forward về PM2 app trên port nội bộ. User cảm thấy seamless.
Debug khi app crash loop
Restart count tăng nhanh là dấu hiệu loop crash. Các bước debug:
pm2 logs myapp --err --lines 100xem stack trace.- Tạm stop để tránh CPU 100:
pm2 stop myapp. - Chạy app trực tiếp (không qua PM2):
node dist/index.jsđể xem lỗi raw. - Đa số lỗi: missing env var, port đã bị bind, database không connect được, dependency thiếu sau deploy.
- Sửa, test,
pm2 restart myapp.
PM2 Plus (paid): có đáng không?
PM2 Plus là SaaS thêm dashboard web đẹp, alert email/Slack, custom metric. Giá từ 12 USD/tháng. Đáng khi:
- Quản lý 10+ app trên nhiều VPS, cần view tập trung.
- Cần alert khi app crash hoặc memory cao mà không muốn tự build.
- Team không có DevOps dedicated, cần UI cho non-tech user.
Dev solo có thể thay bằng combo: pm2 monit + Telegram bot script kiểm tra restart count, gửi alert khi tăng bất thường. Tiết kiệm 12 USD/tháng.
Lệnh PM2 cheat sheet
pm2 listhoặcpm2 status: xem app đang chạy.pm2 logs [name]: xem log realtime.pm2 restart [name]: restart cứng (downtime ngắn).pm2 reload [name]: reload mềm (zero-downtime, cluster mode).pm2 stop [name]: dừng app.pm2 delete [name]: xóa app khỏi PM2.pm2 save: lưu state để khôi phục sau reboot.pm2 startup: tạo systemd unit.pm2 update: update PM2 binary, restart daemon.pm2 flush: clear toàn bộ log.
So sánh PM2 với systemd
| Tiêu chí | PM2 | systemd unit |
|---|---|---|
| Setup mỗi app | 1 lệnh | Viết unit file, daemon-reload |
| Cluster mode | Built-in | Cần script wrapper |
| Log rotation | Plugin sẵn | journald hoặc logrotate riêng |
| Zero-downtime reload | Có | Khó, cần dual-port |
| Memory threshold restart | 1 cờ | Cần script + cron |
| Multi-app management | Đơn giản | Mỗi app 1 unit file |
PM2 cho Node.js, systemd cho Python/Go/Rust binary. Có thể kết hợp: systemd start PM2 daemon (đã tự động qua pm2 startup), PM2 quản các Node app.
FAQ
PM2 có chạy được app Python, Go không?
Có. PM2 chạy bất kỳ executable nào: pm2 start app.py --interpreter python3, pm2 start ./my-go-binary. Nhưng tính năng cluster mode chỉ work với Node.js. Cho Python/Go production, systemd hoặc supervisord phổ biến hơn.
Khi reboot VPS, PM2 có tự start không?
Có nếu bạn đã chạy pm2 startup và pm2 save. systemd start PM2 daemon, PM2 đọc dump file (~/.pm2/dump.pm2) và resurrect app đã save. Kiểm tra sau reboot: pm2 status.
PM2 cluster mode có thay được Nginx upstream multi-worker không?
Có cho load balance trong cùng VPS. Nginx upstream phù hợp khi load balance giữa nhiều VPS hoặc cần routing logic phức tạp. PM2 cluster đủ tốt cho single VPS multi-core scenario.
PM2 có an toàn để chạy production thật không?
Có. PM2 đang được dùng trên hàng triệu server toàn cầu, bao gồm Microsoft, IBM, NASA. Cộng đồng lớn, GitHub 41k+ star, update đều. Cài đúng cluster + max_memory_restart + log rotate là yên tâm.
Khi nào nên dùng Docker thay vì PM2?
Khi cần isolation mạnh (mỗi app trong container riêng), khi deploy nhiều VPS qua orchestrator (Kubernetes, Nomad), hoặc khi app phụ thuộc nhiều version Node khác nhau. Dev solo single VPS thường thì PM2 đủ và nhẹ hơn.
Cloud VPS đa core tận dụng tốt nhất với PM2 cluster mode
Cloud VPS TND sẵn AlmaLinux 9, Ubuntu 22/24, Debian 12/13. SSD CEPH, snapshot 1-click, backup hằng ngày, network 200Mbps trong nước. CPU AMD EPYC nhiều core giúp PM2 cluster scale gần tuyến tính, mỗi worker phục vụ tốt traffic Việt Nam dưới 15ms latency.
Xem 8 cấu hình Cloud VPS →


