PM2 vs Docker khi deploy NodeJS trên VPS: nên chọn cách nào?
Deploy app NodeJS lên VPS nghe đơn giản: copy code, npm install, chạy app, mở Nginx. Nhưng khi hệ thống bắt đầu có traffic, cần auto-restart, rollback, scale, tách môi trường, quản lý log, câu hỏi xuất hiện rất nhanh: dùng PM2 hay Docker?
Đây không chỉ là chuyện “tool nào hot hơn”. Nó là bài toán vận hành: team đang mạnh về gì, app cần ổn định tới đâu, VPS nhỏ hay lớn, có CI/CD không, có nhiều service không. Chọn đúng → triển khai nhanh, dễ debug, ít sự cố. Chọn sai → mỗi lần release là một lần cầu nguyện.
Bài viết này so sánh thực tế 2 hướng phổ biến nhất để deploy NodeJS trên VPS: PM2 trực tiếp trên máy chủ và Docker container hóa ứng dụng.
PM2 là gì? Docker là gì?
PM2
PM2 → process manager cho NodeJS.
Nó giúp:
– chạy app dạng daemon
– auto-restart khi crash
– quản lý nhiều process
– hỗ trợ cluster mode
– xem log, monitor cơ bản
– khởi động cùng hệ thống
Mô hình phổ biến:
– cài NodeJS trực tiếp trên VPS
– pull code/app lên server
– npm install
– chạy bằng PM2
– dùng Nginx reverse proxy
PM2 phù hợp kiểu: “server truyền thống, app chạy trực tiếp trên OS”.
Docker
Docker → đóng gói app + runtime + dependency vào container.
Bạn build image, chạy container trên VPS, thường đi kèm:
– Docker Compose
– Nginx/Caddy
– volume
– network riêng
– CI/CD build image
Mô hình này phù hợp kiểu: “app là một gói độc lập, môi trường chạy nhất quán”.
So sánh theo góc nhìn thực chiến
1. Độ dễ học, dễ triển khai ban đầu
PM2: dễ vào việc hơn
Nếu bạn chỉ có:
– 1 VPS
– 1 app NodeJS
– 1 database riêng
– ít người vận hành
thì PM2 gần như là con đường ngắn nhất.
Luồng thường là:
1. Cài NodeJS
2. Clone source
3. Cài package
4. Chạy pm2 start
5. Cấu hình Nginx
6. Xong
Ưu điểm lớn nhất: ít lớp trừu tượng. App lỗi → xem log ngay trên máy. Thiếu env → sửa trực tiếp. Port sai → sửa config, restart.
Docker: khó hơn lúc đầu
Docker có thêm nhiều khái niệm:
– image
– container
– volume
– network
– build context
– compose
– bind mount
– registry
Người mới dễ gặp lỗi:
– build image chậm
– container chạy nhưng app không listen đúng port
– volume đè file
– permission sai
– DB connection fail do network/container name
Kết luận mục này:
– PM2 → dễ bắt đầu
– Docker → cần đầu tư học ban đầu
2. Quản lý môi trường chạy
PM2: phụ thuộc VPS nhiều hơn
Khi dùng PM2, app chạy trực tiếp trên OS. Nghĩa là môi trường thật sự phụ thuộc vào:
– version NodeJS trên server
– package hệ thống
– quyền user
– thư viện native
– cấu hình máy
Server A chạy được chưa chắc server B chạy được y hệt. Đặc biệt khó chịu với package native như sharp, bcrypt, canvas, headless browser.
Docker: nhất quán cao
Docker giải quyết mạnh nhất ở điểm này:
– dev build image nào
– staging chạy image đó
– production chạy image đó
Cùng image → môi trường gần như giống nhau.
Điều này cực giá trị khi team nhiều người, nhiều môi trường, hoặc hay deploy lại.
Kết luận:
– PM2 → nhanh, nhưng dễ lệ thuộc “tình trạng server”
– Docker → chuẩn hóa tốt, giảm “works on my machine”
3. Hiệu năng và mức tiêu tốn tài nguyên
PM2: nhẹ hơn một chút
PM2 chạy trực tiếp trên host → ít overhead hơn Docker.
Trên VPS nhỏ, ví dụ 1GB RAM, khác biệt này đôi khi đáng kể.
Ngoài ra:
– ít lớp trung gian
– debug CPU/memory trực tiếp hơn
– startup nhanh
Docker: overhead nhỏ, nhưng có
Docker không “nặng khủng khiếp”, nhưng vẫn thêm lớp container runtime, network, volume. Với app NodeJS thông thường, khác biệt hiệu năng thường không phải yếu tố quyết định, trừ khi VPS rất yếu hoặc bạn tối ưu tới từng MB RAM.
Kết luận:
– PM2 → lợi thế nhẹ, đơn giản
– Docker → chấp nhận overhead nhỏ để đổi lấy tính chuẩn hóa
4. Quản lý nhiều app, nhiều service
PM2: ổn với ít service
Nếu VPS chỉ có:
– 1 app API
– 1 app admin
– Nginx
– maybe Redis
PM2 vẫn ổn. Nhưng khi hệ thống tăng dần:
– app backend
– worker queue
– cron service
– websocket service
– Redis
– MinIO
– monitoring stack
thì cách cài trực tiếp lên VPS bắt đầu rối:
– port chồng chéo
– dependency hệ thống xung đột
– khó rollback từng phần
– khó di chuyển sang máy khác
Docker: tỏa sáng ở hệ nhiều thành phần
Docker Compose giúp mô tả hạ tầng bằng code:
– service nào chạy
– port nào expose
– env nào dùng
– volume nào mount
– network nào kết nối
Khi cần move sang VPS mới:
– cài Docker
– copy docker-compose.yml
– pull image
– chạy lại
Rõ ràng, lặp lại được, dễ audit hơn.
Kết luận:
– PM2 → tốt cho app đơn/ít thành phần
– Docker → tốt cho hệ thống nhiều service
5. Scale và zero-downtime
PM2: cluster mode khá tiện
PM2 có cluster mode, cho phép tận dụng nhiều CPU core.
Bạn có thể chạy nhiều instance NodeJS phía sau Nginx khá nhanh.
PM2 cũng hỗ trợ reload tương đối mượt, phù hợp cho:
– API nhỏ
– app SSR vừa phải
– hệ thống nội bộ
Docker: scale tốt hơn khi đi xa
Nếu hiện tại chỉ có 1 VPS, Docker Compose là đủ. Nhưng nếu sau này bạn muốn tiến lên:
– nhiều VPS
– rolling update
– orchestration
– swarm/k8s
– CI/CD bài bản
thì Docker là nền tảng hợp logic hơn.
PM2 scale tốt ở mức process trong 1 máy. Docker scale tốt ở mức service/container, dễ mở rộng kiến trúc.
Kết luận:
– PM2 → scale dọc nhanh trong 1 VPS
– Docker → scale ngang, mở rộng tương lai tốt hơn
6. Logging, debug, vận hành hằng ngày
PM2: debug trực diện
PM2 mạnh ở trải nghiệm vận hành nhanh:
– pm2 logs
– pm2 status
– pm2 monit
Lỗi app → thấy ngay.
SSH vào máy → kiểm tra nhanh.
Với team nhỏ, đây là lợi thế lớn.
Docker: cần kỷ luật hơn
Docker log tốt, nhưng tư duy khác:
– log qua stdout/stderr
– xem bằng docker logs
– rotate log cần cấu hình
– inspect container/network cần hiểu tool
Nếu build chuẩn ngay từ đầu thì rất sạch. Nhưng nếu làm nửa vời, debug có thể khó hơn PM2 vì phải đi qua thêm một lớp container.
Kết luận:
– PM2 → thân thiện khi debug nhanh
– Docker → tốt nếu bạn có quy chuẩn logging rõ ràng
7. Bảo mật và cô lập
PM2: ít cô lập hơn
App chạy trực tiếp trên host → nếu cấu hình kém, rủi ro ảnh hưởng hệ thống cao hơn.
Bạn phải tự quản chặt:
– user chạy app
– permission thư mục
– firewall
– package hệ thống
Docker: cô lập tốt hơn, nhưng không tự động an toàn
Container giúp tách biệt app khỏi host tốt hơn. Nhưng Docker không tự động bảo mật nếu bạn:
– chạy container bằng root
– mount quá nhiều thư mục host
– expose port bừa bãi
– dùng image không rõ nguồn gốc
Nói ngắn:
– PM2 → ít lớp bảo vệ hơn
– Docker → cô lập tốt hơn nếu dùng đúng cách
Khi nào nên chọn PM2?
Chọn PM2 nếu bạn thuộc các tình huống sau:
– chỉ có 1 app NodeJS
– cần deploy nhanh, ít phức tạp
– VPS tài nguyên thấp
– team nhỏ, ít DevOps
– muốn debug trực tiếp, đơn giản
– chưa có nhu cầu chuẩn hóa môi trường mạnh
Ví dụ điển hình:
– landing page có API
– CMS nội bộ
– SaaS giai đoạn MVP
– backend nhỏ cho mobile/web
Từ khóa: nhanh, gọn, dễ sửa.
Khi nào nên chọn Docker?
Chọn Docker nếu bạn cần:
– môi trường chạy nhất quán
– nhiều service chạy cùng nhau
– CI/CD rõ ràng
– dễ migrate sang server mới
– dễ onboard team
– chuẩn bị scale kiến trúc về sau
Ví dụ điển hình:
– hệ thống có API + worker + Redis + Nginx
– nhiều môi trường dev/staging/prod
– team nhiều người
– app thường xuyên deploy
– cần rollback bằng image/tag
Từ khóa: chuẩn hóa, tái lập, mở rộng.
Lời khuyên thực tế: đừng chọn theo “trend”
Nhiều team chọn Docker vì “chuyên nghiệp hơn”, nhưng thực tế lại chưa có quy trình build, chưa biết quản lý volume, chưa hiểu networking → deploy chậm hơn, lỗi nhiều hơn.
Ngược lại, có team bám PM2 quá lâu dù hệ thống đã có 5-7 service → server trở thành “mớ cấu hình thủ công”, rất khó bàn giao.
Cách chọn hợp lý:
– App nhỏ, 1 VPS, cần ra nhanh → dùng PM2
– App đang lớn dần, nhiều thành phần, cần nhất quán → dùng Docker
– Chưa chắc → bắt đầu PM2, nhưng viết app theo hướng dễ container hóa sau này
Kết luận
Không có đáp án tuyệt đối “PM2 tốt hơn Docker” hay ngược lại.
Có bối cảnh phù hợp hơn.
– PM2 → thắng ở sự đơn giản, tốc độ triển khai, dễ debug, hợp app nhỏ-vừa
– Docker → thắng ở tính nhất quán, khả năng đóng gói, quản lý nhiều service, sẵn sàng mở rộng
Nếu bạn đang deploy 1 app NodeJS lên 1 VPS, muốn ổn định nhanh, ít học thêm → PM2 là lựa chọn thực dụng nhất.
Nếu bạn đang xây hệ thống nghiêm túc hơn, muốn môi trường chuẩn hóa, dễ CI/CD, dễ mở rộng → Docker đáng để đầu tư.
Chọn đúng không phải để “xịn hơn”.
Chọn đúng để ít lỗi hơn, deploy tự tin hơn, vận hành nhẹ đầu hơn.