Quay lại

Cách sử dụng PM2 kết hợp với Nginx trên Ubuntu Chuyên mục Bài Viết Hay    2023-09-03    1.3k Lượt xem    117 Lượt thích    comment-3 Created with Sketch Beta. 0 Bình luận

Cách sử dụng PM2 kết hợp với Nginx trên Ubuntu

Bạn đã xây dựng xong website hoặc api của mình. Bây giờ muốn cung cấp cho cả thế giới sử dụng thì phải làm sao? Mình sẽ hướng dẫn bạn sử dụng PM2 để quản lý Node.js process và NGINX làm reverse proxy để cấu hình sử dụng domain cho VPS của mình. Cuối cùng là dùng Certbot để bật https làm website của mình luôn xanh.

Điều kiện tiên quyết để bắt đầu:

  • Project Node (ví dụ Express).
  • Linux server (ví dụ Ubuntu VPS).
  • Một tên miền (tuỳ chọn): không có tên miền thì dùng IP trực tiếp vậy thì mình sẽ không cần đến NGINX. Thời buổi này kiếm một tên miền miễn phí để thử chắc cũng không khó nhỉ

Kế hoạch là mình sẽ tạo một domain s2sontech.com nhé.

Chuẩn bị server và mã nguồn

Đầu tiên cần ssh vào server, sau đó tạo thư mục để chứa source. Sẵn tiện cd vào đó luôn.

mkdir -p /var/www/s2sontech.com
cd /var/www/s2sontech.com

Kéo source từ Github của bạn về thư mục này.

Cài thư viện sau đó chạy thử được không đã. Do VPS của mình đã có website khác sử dụng port mặc định (3000) nên mình chuyển sang port 3001.

npm install
PORT=3001 npm start

Nếu chạy thành công bạn có thể tạo một đường ssh mới và thử xem website của mình chạy ngon lành chưa nha.

curl localhost:3001

Tới bước này thì nếu server bạn có mở port 3001 thì có thể dùng public IP cùng port 3001 để truy cập website rồi. Ai lại làm cái website cùi bắp vậy bạn nhỉ . 

Cấu hình PM2

Nếu như host được Node chạy đơn giản như ở trên thì lại cần PM2 làm gì nhỉ? Mình có thể liệt kê một vài lý do sau:

  • Đầu tiên là tính năng auto restart. Nếu như project Node đang chạy lại quăng một exception thì sao nhỉ? Kết quả là process Node ấy sẽ bị crash là không thể tiếp tục nhận request nữa. Với PM2, process của bạn sẽ tự động chạy lại khi crash xảy ra.
  • PM2 cũng sẽ giúp bạn quản lý và truy xuất access log và error log khi cần.
  • Nếu server của bạn host nhiều website Node cùng lúc thì PM2 cũng sẽ hỗ trợ bạn quản lý, bật tắt, cập nhật các website này tiện lợi.
  • Node chỉ sử dụng một thread để xử lý tất cả các request đến. Thật là phí nếu bạn có con CPU 36 core mà chỉ dùng một thread . PM2 cũng hỗ trợ bạn load-balancing nhiều process node để sử dụng tối đa số core của server.

Quảng cáo vậy đủ rồi. PM2 có trả cho mình xu nào tiền quảng cáo đâu .

PM2 là một Node package nên cài khá dễ.

1.Cài đặt

npm install pm2 -g

Quản lý ứng dụng trong PM2

Nếu bạn chưa stop process npm start thì giờ là lúc rồi nhé. Mình sẽ thay bằng PM2. Nghía vào package.json bạn sẽ thấy npm start sẽ chạy node ./bin/www nên sẽ start PM2 như sau.

PORT=3001 pm2 start ./bin/www --name s2sontech.com:3001
  • PORT=3001: Tương tự như lúc chạy npm start mình đổi port 3001 để không đụng với website khác đang chạy port 3000 trên server của mình. Nếu bạn không có website nào đang chạy ở port 3000 thì không cần đổi port.
  • --name (index): Mình báo cho PM2 đặt tên process mình là s2sontech.com:3001 để cho mình nhớ là process này dành cho s2sontech.com:3001 và chạy trên port 3001. Tuỳ bạn muốn đặt tên gì miễn bạn thấy tiện và dễ quản lý là được.

Giờ đây bạn có thể xem danh sách các process PM2 đang quản lý bằng lệnh.

pm2 status

Bạn có thể xem chi tiết process vừa tạo trên PM2, ví dụ trong trường hợp này bạn có 1 process với id  là 3.

pm2 show 3

Bạn có thể thấy được đường dẫn của error log và out log để xem khi cần.

Bạn có thể tham khảo thêm các lệnh căn bản để quản lý app.

pm2 monit # giao diện tương tác trên console để theo dõi các app
pm2 logs [<id>] # nếu không truyền id PM2 sẽ hiển thị log của tất cả app. Nếu có id thì hiển thị log của app id đó thôi
pm2 stop [all/<id>] # ngừng tất cả app đang chạy hoặc theo id
pm2 restart [all/<id>] # khởi động lại tất cả app đang chạy hoặc theo id
pm2 reload [all/<id>] # tương tự pm2 restart và PM2 bảo đảm restart lần lượt từng process để giảm thời gian ngừng hệ thống
pm2 delete [all/<id>] # xoá app khỏi danh sách PM2 quản lý

Cluster mode

Để tận dụng tối đa CPU của server bạn có thể thông báo cho PM2 biết để tạo ra nhiều process bằng đúng với số lượng core CPU của server bằng tham số -i max. Hoặc thay max bằng con số mà bạn muốn cluster của mình có bao nhiêu process.

PORT=3001 pm2 start ./bin/www -i max --name s2sontech.com:3001

Kết quả khi pm2 status bạn sẽ thấy trạng thái mode đã được chuyển qua là Cluster

Log rotate

Khi thực thi ứng dụng của bạn, PM2 sẽ ghi log ra hai tập tin error log và out log. Nếu ứng dụng của bạn chạy liên tục nhiều ngày hoặc tần suất ghi log của bạn nhiều, thì hai tập tin này sẽ lớn rất nhanh và chiếm hết ổ cứng trong máy của bạn.

Để giải quyết vấn đề trên, bạn có thể sử dụng pm2-logrotate để tự động cắt log mỗi khi kích thước tập tin log đủ 10MB và sẽ duy trì tối đa 30 tập tin. Dĩ nhiên bạn có thể tuỳ ý cấu hình theo hướng dẫn ở https://github.com/keymetrics/pm2-logrotate#configure. Cài đặt chỉ đơn giản bằng một lệnh.

pm2 install pm2-logrotate

Cấu hình tự chạy PM2 khi khởi động hệ điều hành

Để bảo đảm PM2 tự chạy khi khởi động lại hệ điều hành (do lỗi, bảo trì hoặc nâng cấp hệ thống, …). Bạn có thể tạo startup script với trạng thái là các ứng dụng đang chạy trong PM2.

pm2 startup

Sau đó áp dụng script này để tự kích hoạt các ứng dụng trên mỗi khi khởi động lại hệ thống bằng lệnh.

pm2 save

Phần PM2 như vậy là ổn để các bạn có thể chạy liên tục website của mình và tự động chạy lại website khi có lỗi, chạy nhiều website trên nhiều process để tận dụng tối đa số lõi CPU của hệ thống, quản lý log và không để log chiếm hết dung lượng ổ cứng, cuối cùng là bảo đảm PM2 tự động chạy lại khi khởi động lại hiệu hành.

Cấu hình NGINX

Xong phần PM2 ở trên, ta đã có một website Node luôn chạy ở port 3001 của máy chủ. Bây giờ làm sao cấu hình domain cho website này? NGINX sẽ đóng vai trò làm reverse proxy nhận request từ port 80 (http) hoặc port 443 (https) kèm thông tin domain để chuyển request về port tương ứng của localhost. Cụ thể ở đây khi người dùng truy cập vào domain s2sontech.com (mặc định sẽ là port 80) mình sẽ cấu hình NGINX để chuyển request về port 3001 mà ta đã dựng ở trên.

Trước hết bạn cần phải trỏ domain về IP của máy chủ. Tuỳ vào hướng dẫn của dịch vụ cung cấp tên miền, bạn cần tạo một A Record của trong domain trỏ tới IP của máy chủ. Thông thường thời gian để DNS ghi nhận domain của bạn từ 15 phút đến 24 tiếng. Để kiểm tra bạn có thể dùng lệnh ping để bảo đảm domain được phân giải về đúng IP.

ping s2sontech.com

Trong lúc chờ đợi, ta bắt tay vào cài NGINX.

sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys $key
sudo apt-get update
sudo apt-get install nginx

Sau đó mình tiến hành mở port 80 và 443 để có thể kết nối từ bên ngoài. Nếu máy chủ của bạn không dùng ufw thì bỏ qua bước này nhé. Nếu bạn dùng VPS, mình cũng cần kiểm tra xem website quản lý VPS đã mở port 80 và 443 hay chưa. Nếu chưa thì nhớ mở ra.

sudo ufw allow 'Nginx Full'

Để bảo đảm NGINX đã chạy ổn định. Bạn kiểm tra trạng thái của NGINX đã active chưa.

systemctl status nginx

Đồng thời thủ sẵn những lệnh sau khi cần.

sudo systemctl stop nginx # tắt NGINX
sudo systemctl start nginx # bật NGINX
sudo systemctl restart nginx # khởi động lại NGINX
sudo systemctl reload nginx # nếu bạn chỉ thay đổi cấu hình của NGINX thì chỉ cần reload để tránh làm rớt các kết nối hiện tại vào NGINX
sudo systemctl disable nginx # không tự kích hoạt NGINX khi khởi động hệ thống
sudo systemctl enable nginx # tự kích hoạt NGINX khi khởi động hệ thống

Các cấu hình của NGINX mặc định được lưu ở thư mục /etc/nginx. Trong nội dung bài viết này mình sẽ quan tâm đến hai thư mục là sites-available và sites-enabled. Cụ thể mình sẽ viết các tập tin cấu hình ở sites-available và khi nào muốn kích hoạt cấu hình đó ta sẽ symlink tập tin cấu hình vào thư mục sites-enabled.

Mình sẽ tạo tập tin cấu hình /etc/nginx/sites-available/s2sontech.com với nội dung sau. Cụ thể là sẽ chuyển các request từ port 80 đi từ domain s2sontech.com về localhost:3001.

server {
  listen 80;
  server_name s2sontech.com;
  location / {
    proxy_pass http://localhost:3001;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection 'upgrade';
    proxy_set_header Host $host;
    proxy_cache_bypass $http_upgrade;
   }
}

Tiếp theo là symlink vào thư mục sites-enabled để NGINX sử dụng cấu hình này.

sudo ln -s /etc/nginx/sites-available/s2sontech.com /etc/nginx/sites-enabled

Kiểm tra có lỗi cú pháp nào không?

nginx -t

Nếu mỗi thứ ổn thì reload lại NGINX để cập nhật cấu hình.

sudo systemctl reload nginx

Mọi thứ tốt đẹp các bạn có thể mở trình duyệt để vào trang http://s2sontech.com/ tận hưởng kết quả.

Sử dụng Certbot để cấu hình https

Thời buổi này mà website còn dùng http, mở trên trình duyệt hiện chữ Not Secure thì quê quá. Let's Encrypt lại còn miễn phí nữa chứ.

Thêm nữa Certbot làm việc cấu hình https cho website dễ hơn rất nhiều. Thậm chí còn dễ hơn việc bạn bỏ tiền ra mua Https certificate rồi cấu hình vào máy chủ.

Vào https://certbot.eff.org/ bạn sẽ thấy tuỳ chọn Software và System. Mình sẽ chọn tương ứng NGINX và Ubuntu. Bạn sẽ thấy hướng dẫn cài đặt Certbot. Cụ thể là các lệnh sau.

sudo apt-get update
sudo apt-get install software-properties-common
sudo add-apt-repository universe
sudo add-apt-repository ppa:certbot/certbot
sudo apt-get update

sudo apt-get install certbot python3-certbot-nginx

Sau khi cài đặt xong chạy lệnh bên dưới để sử dụng Certbot.

sudo certbot --nginx

Certbot sẽ tự đọc cấu hình NGINX và liệt kê các domain cần kích hoạt https. Mình sẽ chọn domain s2sontech.com

Tiếp theo Certbot sẽ tự động tạo certificate từ Let’s Encrypt và tự challenge để chứng minh quyền sở hữu của bạn. Cài đặt certificate vào hệ thống. Sau đó bạn được chọn hai tuỳ chọn:

  1. No redirect: website của bạn sẽ tồn tại song song http và https cùng lúc. Người dùng vào cái nào cũng được.
  2. Redirect: chuyển tất cả các request http về https.
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for sample-api.khanh.website
Waiting for verification...
Cleaning up challenges
Deploying Certificate to VirtualHost /etc/nginx/sites-enabled/sample-api.khanh.website

Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: No redirect - Make no further changes to the webserver configuration.
2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for
new sites, or if you're confident your site works on HTTPS. You can undo this
change by editing your web server's configuration.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate number [1-2] then [enter] (press 'c' to cancel):

Nếu bạn tự tin code mình sẽ ổn thì nên chọn số 2.

Thế là xong. Bây giờ bạn có thể vào trang https://s2sontech.com với https xanh.

Nếu kỹ bạn có thể xem lại Certbot đã làm gì với cấu hình NGINX của bạn.

server {
  server_name s2sontech.com;
  location / {
    proxy_pass http://localhost:3001;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection 'upgrade';
    proxy_set_header Host $host;
    proxy_cache_bypass $http_upgrade;
   }

    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/s2sontech.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/s2sontech.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}
server {
    if ($host = s2sontech.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot
  listen 80;
  server_name s2sontech.com;
  return 404; # managed by Certbot
}

Mình đã hướng dẫn các bạn sử dụng PM2 để quản lý website Node của mình. Sử dụng NGINX làm reverse proxy để chuyển request từ domain vào port của localhost. Cuối cùng là sử dụng Certbot để cấu hình https bảo đảm website luôn xanh. Chúc các bạn host thành công.

 
 
 
 
 
 

Bình luận (0)

Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough

Bài viết liên quan

Learning English Everyday