0

Bài 2 Làm chủ Supervisor cho Node.js: Thực chiến viết file cấu hình .conf cho ứng dụng Express/NestJS

Chào anh em đã quay lại với series làm chủ Supervisor! Ở bài học trước, chúng ta đã phân tích lý do tại sao các ứng dụng Node.js trên production rất cần một trình quản lý tiến trình cấp hệ thống như Supervisor để đảm bảo tính sẵn sàng (high availability) [cite: 19].

Trong bài học thứ hai này, chúng ta sẽ chuyển từ lý thuyết sang thực hành: viết một file cấu hình .conf chuẩn chỉnh để chạy một ứng dụng Node.js (ví dụ: NestJS hoặc Express) trên môi trường Ubuntu Production.

1. Chuẩn bị ứng dụng Node.js trên Server

Giả sử ứng dụng NestJS của bạn đã được build sẵn và đặt tại thư mục:

/var/www/my-node-app

Và để khởi động ứng dụng ở môi trường production, bạn thường chạy câu lệnh:

node dist/main.js
# Hoặc sử dụng npm run start:prod (nhưng chạy trực tiếp file node sẽ tối ưu đường dẫn hơn cho Supervisor)

Trước khi cấu hình Supervisor, hãy đảm bảo rằng bạn đã xác định chính xác đường dẫn tuyệt đối của câu lệnh node trên hệ thống của bạn bằng lệnh:

which node

Kết quả thường sẽ trả về dạng /usr/bin/node hoặc qua trình quản lý phiên bản như nvm (tuy nhiên trên production, khuyến nghị cài node trực tiếp toàn hệ thống để Supervisor dễ dàng nhận diện).

2. Viết file cấu hình .conf cho Node.js App

Anh em truy cập vào thư mục chứa file cấu hình của Supervisor và tạo một file mới cho project Node.js:

sudo nano /etc/supervisor/conf.d/my-node-app.conf

Sau đó, dán nội dung mẫu tối ưu sau đây vào file (nhớ thay đổi đường dẫn /var/www/my-node-app và user cho khớp với server của anh em nhé):

[program:my-node-app]
process_name=%(program_name)s_%(process_num)02d
command=/usr/bin/node /var/www/my-node-app/dist/main.js
directory=/var/www/my-node-app
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true
user=www-data
numprocs=1
redirect_stderr=true
stdout_logfile=/var/www/my-node-app/logs/supervisor.log
environment=NODE_ENV="production",PORT="3000"
stopwaitsecs=10

🔍 Giải phẫu chi tiết từng tham số dành riêng cho Node.js:

  • [program:my-node-app]: Tên định danh tiến trình ứng dụng Node.js trên Supervisor.
  • command=/usr/bin/node ...: Đường dẫn tuyệt đối đến trình biên dịch Node.js kết hợp với file entry point (dist/main.js đối với NestJS hoặc server.js đối với Express). Lưu ý tuyệt đối không dùng lệnh npm start hay yarn start trong command, vì npm/yarn sẽ đóng vai trò là process trung gian, khiến Supervisor khó kiểm soát chính xác tín hiệu tắt/bật của tiến trình Node.js thực tế.
  • directory=/var/www/my-node-app: Thư mục làm việc gốc (working directory) của ứng dụng. Giúp ứng dụng đọc đúng các file cấu hình tương đối (như .env) khi khởi động.
  • user=www-data: Chạy ứng dụng dưới quyền của user hệ thống, tránh chạy bằng root gây lỗ hổng bảo mật nghiêm trọng nếu ứng dụng bị tấn công RCE (Remote Code Execution).
  • environment=NODE_ENV="production",PORT="3000": Truyền các biến môi trường trực tiếp vào tiến trình con thông qua Supervisor một cách cực kỳ gọn gàng mà không phụ thuộc hoàn toàn vào file .env nếu cần ghi đè nhanh.
  • numprocs=1: Với Node.js (vốn chạy đơn luồng trên một CPU core), nếu bạn muốn tận dụng đa nhân CPU, bạn có thể tăng numprocs lên tương ứng với số core hoặc dùng module cluster của Node. Tuy nhiên, cấu hình numprocs chạy nhiều tiến trình độc lập trên các PORT khác nhau kết hợp với Nginx làm Load Balancer là một cách tiếp cận cực kỳ phổ biến.

3. Kích hoạt và Vận hành tiến trình Node.js

Sau khi lưu file cấu hình lại, chúng ta thực hiện các bước quen thuộc để nạp và khởi chạy ứng dụng:

  • Bước 1: Nạp lại cấu hình Supervisor
    sudo supervisorctl reread
    
  • Bước 2: Cập nhật tiến trình mới
    sudo supervisorctl update
    
  • Bước 3: Kiểm tra trạng thái ứng dụng
    sudo supervisorctl status
    

Nếu mọi thứ thiết lập chính xác, bạn sẽ thấy my-node-app:my-node-app_00 chuyển sang trạng thái RUNNING màu xanh.

💡 Bộ lệnh quản lý hàng ngày cho Node.js App:

  • Khởi động lại ứng dụng khi deploy code mới:
    sudo supervisorctl restart my-node-app:*
    
  • Xem log thời gian thực để debug lỗi Crash:
    tail -f /var/www/my-node-app/logs/supervisor.log
    

Tóm tắt Bài 2

  • Chúng ta đã biết cách viết file cấu hình .conf tối ưu cho ứng dụng Node.js (NestJS/Express).
  • Nắm được nguyên tắc vàng: Luôn gọi trực tiếp file thực thi node, tránh dùng npm start trong file cấu hình của Supervisor.
  • Truyền biến môi trường trực tiếp và quản lý thư mục làm việc (directory) gọn gàng.
  • Hẹn gặp lại anh em ở Bài 3: Chúng ta sẽ bàn về Cluster Mode, Zero-downtime Deployment cho Node.js với Supervisor và cách kết hợp Nginx Reverse Proxy để chịu tải cao!

All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí