Checklist deploy NodeJS bằng Docker trên VPS: nhanh, gọn, ít lỗi nhất
Deploy NodeJS lên VPS nghe đơn giản: git pull, docker build, docker run, xong. Thực tế: dính port, thiếu biến môi trường, quyền file sai, restart fail, SSL lỗi, log khó đọc, disk đầy sau vài lần build. Kết quả: app “chạy máy em” nhưng chết trên server.
Bài này không chỉ liệt kê lệnh. Mục tiêu: đưa bạn một checklist thực chiến để deploy nhanh, gọn, ít lỗi, đủ tốt cho đa số side project, SaaS nhỏ, API nội bộ, landing page NodeJS. Trọng tâm: Docker + VPS, ưu tiên sự ổn định, dễ lặp lại, dễ debug.
1. Tư duy đúng trước khi deploy
Checklist tốt bắt đầu từ nguyên tắc đúng:
– Một app = một container chính
– Config tách khỏi image → dùng .env, secret, biến môi trường
– Build reproducible → cùng source phải ra cùng kết quả
– Container stateless → data cần giữ phải tách volume/DB ngoài
– Reverse proxy đứng trước app → Nginx/Caddy xử lý domain, SSL
– Restart tự động → VPS reboot vẫn lên lại
– Log tập trung stdout/stderr → dễ docker logs
Nếu bạn bỏ qua các nguyên tắc này, deploy ban đầu có thể nhanh, nhưng sửa lỗi về sau sẽ rất tốn.
2. Checklist chuẩn bị VPS
Trước khi đụng tới Docker, kiểm tra nền tảng:
Hệ điều hành
– Ubuntu LTS phổ biến nhất
– RAM tối thiểu:
– 1GB → app nhỏ, ít traffic
– 2GB → thoải mái hơn cho Node + Docker + reverse proxy
– Disk:
– 20GB đủ cho app nhỏ
– nhớ tính thêm image cũ, log, backup
Tạo user deploy riêng
Không nên deploy bằng root hằng ngày.
– Tạo user riêng, ví dụ: deploy
– Thêm quyền sudo
– Cấu hình SSH key
– Tắt login password nếu được
Cập nhật hệ thống
Checklist:
– apt update && apt upgrade -y
– kiểm tra timezone
– cài curl, git, ufw
Firewall
Chỉ mở port cần thiết:
– 22 → SSH
– 80 → HTTP
– 443 → HTTPS
– Không mở public port app nội bộ nếu đã có reverse proxy
Sai lầm phổ biến: mở luôn 3000, 4000, 5000 ra Internet. Không cần trong đa số case.
3. Checklist Docker tối giản nhưng đúng
Cài Docker + Docker Compose
Hiện nay thường dùng Docker Engine + plugin compose.
Checklist:
– Docker cài từ nguồn chính thức
– user deploy có quyền chạy Docker
– kiểm tra:
– docker --version
– docker compose version
Bật tự khởi động
– Docker service phải enable
– VPS reboot → Docker tự lên → container tự restart
Dọn rác định kỳ
Docker dùng lâu sẽ phình disk.
Checklist:
– xóa image/container không dùng
– kiểm tra bằng:
– docker system df
– dọn bằng:
– docker system prune
Cẩn thận: lệnh prune có thể xóa resource không dùng. Chỉ chạy khi hiểu rõ.
4. Checklist Dockerfile cho NodeJS ít lỗi
Dockerfile là nơi lỗi xuất hiện nhiều nhất. Mục tiêu: nhẹ, cache tốt, ổn định.
Nguyên tắc
– dùng base image rõ version, ví dụ node:20-alpine
– copy package*.json trước → tận dụng cache
– cài dependency trước khi copy toàn bộ source
– production → NODE_ENV=production
– tránh nhét .env vào image
– nếu app build frontend/TypeScript → cân nhắc multi-stage build
Mẫu tư duy Dockerfile
Checklist:
– WORKDIR rõ ràng
– COPY package.json/package-lock.json
– RUN npm ci thay vì npm install
– COPY . .
– RUN npm run build nếu có
– EXPOSE đúng cổng app
– CMD rõ ràng
Vì sao npm ci tốt hơn?
– lockfile chuẩn → build reproducible
– nhanh hơn trong CI/CD
– ít “hên xui” dependency
.dockerignore bắt buộc có
Nếu thiếu, bạn dễ copy cả đống file rác lên image.
Nên ignore:
– node_modules
– .git
– .env
– logs
– dist nếu build lại trong image
– file local không cần thiết
Kết quả: build nhanh hơn, image gọn hơn, ít leak dữ liệu hơn.
5. Checklist cấu hình app NodeJS để hợp Docker
Nhiều app lỗi không phải vì Docker, mà vì code chưa “container-friendly”.
App phải bind 0.0.0.0
Sai phổ biến:
– app listen localhost hoặc 127.0.0.1
– container vẫn chạy
– bên ngoài không truy cập được
Fix:
– app listen 0.0.0.0
Port phải lấy từ biến môi trường
Ví dụ tư duy:
– process.env.PORT || 3000
Không hard-code cứng nếu bạn muốn linh hoạt mapping.
Biến môi trường
Checklist tối thiểu:
– NODE_ENV=production
– PORT
– DATABASE_URL
– JWT_SECRET
– REDIS_URL nếu có
– API keys khác
Nguyên tắc:
– Không commit .env thật
– .env.example → để tài liệu hóa
Healthcheck
App nên có endpoint kiểu:
– /health
– /ping
Dùng để:
– test deploy nhanh
– kiểm tra reverse proxy
– tích hợp monitoring sau này
6. Checklist docker-compose cho deploy gọn nhất
Với 1–3 service, docker compose gần như là lựa chọn cân bằng nhất.
Nên đưa gì vào compose?
– app NodeJS
– reverse proxy nếu muốn gom chung
– Redis/Postgres nếu bạn chấp nhận chạy cùng VPS
Nên cấu hình gì?
– restart: unless-stopped → server reboot vẫn lên
– env_file: .env hoặc environment
– mapping port tối thiểu
– volume nếu cần persistent data
– network nội bộ giữa các service
Sai lầm phổ biến
– mount source code production không cần thiết
– map quá nhiều port public
– thiếu restart policy
– để DB không có volume → restart/container recreate → mất dữ liệu
Nếu mục tiêu là ít lỗi, hãy giữ compose ngắn, rõ, ít magic.
7. Checklist reverse proxy + SSL
Chạy Node trực tiếp trên port 80/443 không phải cách tối ưu. Reverse proxy giải quyết:
– SSL/TLS
– domain/subdomain
– gzip/brotli
– header chuẩn
– rate limit/basic security
– routing nhiều app trên cùng VPS
Chọn gì?
– Nginx → phổ biến, tài liệu nhiều
– Caddy → setup SSL cực nhanh, ít cấu hình hơn
Checklist domain
– trỏ A record về IP VPS
– kiểm tra DNS đã propagate
– reverse proxy trỏ đúng container/port nội bộ
Checklist SSL
– dùng Let’s Encrypt
– auto renew
– test:
– truy cập https://domain
– không loop redirect
– không mixed content nếu có frontend
Sai phổ biến:
– app không trust proxy
– redirect HTTP→HTTPS bị lặp
– cấu hình upstream sai port
8. Checklist quy trình deploy nhanh, ít lỗi
Đây là flow thực chiến, đủ gọn:
Bước 1: Kéo code
– git pull
– hoặc upload artifact/build context sạch
Bước 2: Kiểm tra biến môi trường
– .env đủ chưa?
– secret đúng chưa?
– DB URL connect được chưa?
Bước 3: Build image
– docker compose build
– nếu lỗi dependency → xem lại lockfile, Node version, native packages
Bước 4: Chạy container
– docker compose up -d
Bước 5: Kiểm tra log
– docker compose logs -f app
Đừng bỏ qua bước này. Nhiều lỗi chỉ hiện sau khi container start:
– migrate fail
– thiếu env
– port conflict
– DB timeout
Bước 6: Test từ trong ra ngoài
Thứ tự debug đúng:
1. container có chạy không
2. app có listen đúng port không
3. curl nội bộ có ra không
4. reverse proxy có route đúng không
5. domain + SSL có ổn không
Debug theo lớp → nhanh tìm lỗi hơn rất nhiều.
9. Checklist backup, log, monitoring tối thiểu
Deploy xong chưa phải xong.
Backup
Nếu VPS có DB/volume quan trọng:
– backup DB định kỳ
– backup file upload nếu có
– thử restore ít nhất 1 lần
Không có restore test → backup gần như vô nghĩa.
Log
Checklist:
– app log ra stdout/stderr
– không ghi log vô hạn ra file trong container
– có rotation nếu dùng log file ở host
Monitoring tối thiểu
Ít nhất nên biết:
– app còn chạy không
– RAM/CPU có bị ngốn bất thường không
– disk còn bao nhiêu
– SSL sắp hết hạn chưa
Tối giản cũng được: Uptime Kuma, Netdata, hoặc monitor từ ngoài bằng cron + alert.
10. Checklist lỗi phổ biến nhất
Đây là nhóm lỗi gặp lặp đi lặp lại:
App chạy local, chết trên VPS
Nguyên nhân thường là:
– thiếu env
– khác Node version
– app bind sai host
– DB/firewall chặn kết nối
Container chạy nhưng không truy cập được
Thường do:
– listen 127.0.0.1
– map sai port
– reverse proxy trỏ sai upstream
– firewall chưa mở 80/443
Build quá chậm
Thường do:
– thiếu .dockerignore
– copy toàn bộ source quá sớm
– dùng npm install thay npm ci
VPS đầy disk
Thường do:
– image cũ không xóa
– log phình
– volume rác
– build cache quá nhiều
Reboot server xong app không lên
Thường do:
– thiếu restart: unless-stopped
– Docker service chưa enable
– app phụ thuộc DB nhưng start race condition
Kết luận
Checklist deploy tốt không làm bạn “ngầu” hơn, nhưng giúp bạn ít downtime hơn, ít hoảng hơn, ít sửa lỗi lặt vặt hơn. Với NodeJS trên VPS, công thức hiệu quả nhất cho đa số trường hợp là:
– VPS sạch
– Dockerfile gọn
– docker-compose rõ ràng
– reverse proxy + SSL
– env chuẩn
– log/backup cơ bản
– restart policy đầy đủ
Nếu muốn triển khai nhanh mà vẫn chắc tay, hãy nhớ một nguyên tắc: đừng tối ưu hóa quá sớm, hãy chuẩn hóa sớm. Một setup đơn giản nhưng lặp lại được luôn tốt hơn một setup “xịn” nhưng mỗi lần deploy là một lần cầu may.
Chỉ cần bạn bám đúng checklist trên, phần lớn lỗi deploy NodeJS bằng Docker trên VPS sẽ biến từ “sự cố khó hiểu” thành “vấn đề có thể đoán trước và xử lý trong vài phút”.