Hướng dẫn deploy Node.js app lên VPS Linux Ubuntu
Lời mở đầu
Với sự phát triển của ngành phần mềm hiện nay, việc chạy ứng dụng Node.js trên máy chủ ảo Ubuntu là một lựa chọn tối ưu cho các nhà phát triển. Nhờ vào tính ổn định và hiệu quả của hệ thống Ubuntu, ứng dụng của bạn sẽ luôn hoạt động mượt mà và sẵn sàng phục vụ người dùng. Vì thế trong bài viết này chúng ta sẽ tìm hiểu cách deploy Node.js app lên VPS Linux Ubuntu
Tại sao deploy Node.js app trên VPS Linux Ubuntu?
Trước tiên chúng ta hãy nói về ưu điểm của VPS:
- Tính linh hoạt: Dễ dàng cấu hình và điều chỉnh theo nhu cầu của ứng dụng.
- Khả năng tùy chỉnh cao: Cung cấp quyền kiểm soát chi tiết đối với môi trường triển khai.
- Khả năng mở rộng: Có thể nâng cấp tài nguyên khi nhu cầu sử dụng tăng cao.
Và lợi ích của việc sử dụng Linux Ubuntu đó là hệ thống ổn định đảm bảo hoạt động trơn tru, bảo mật cao giảm thiểu nguy cơ bị tấn công và xâm nhập và cộng đồng hỗ trợ lớn cung cấp nhiều tài nguyên hướng dẫn.
Mục tiêu bài viết
Bài viết này sẽ hướng dẫn các bạn từng bước triển khai ứng dụng Node.js lên VPS chạy hệ điều hành Linux Ubuntu. Các bạn sẽ học cách cài đặt môi trường Node.js, cấu hình máy chủ VPS, và triển khai ứng dụng của mình sao cho hoạt động một cách hiệu quả và bảo mật.
Chuẩn bị trước khi deploy Node.js app
Để bắt đầu vào deploy Node.js app lên VPS Linux Ubuntu thì các bạn cần chuẩn bị những thứ dưới đây:
- VPS chạy hệ điều hành Linux Ubuntu: Khuyến khích cài đặt Ubuntu bản từ 18.04 trở lên. Nếu chưa có VPS các bạn có thể đăng ký tại inet.vn và nhập mã LAHOTECHCP để được giảm giá khi đăng ký.
- Tên miền (domain): Tên miền đã trỏ đến IP của VPS. Nếu bạn nào chưa có tên miền có thể đăng ký tại inet.vn.
- Ứng dụng Node.js: Đã được upload lên các dịch vụ lưu trữ mã nguồn như Github.
- Công cụ SSH: Dùng để kết nối với VPS từ xa. Ở đây mình sử dụng MobaXterm.
Sau khi chuẩn bị xong những thứ trên chúng ta bắt đầu thôi.
Cài đặt Nginx cho VPS Ubuntu
Cài đặt Nginx
Vì Nginx có sẵn trong gói cài đặt của Ubuntu nên chúng ta có thể dễ dàng cài đặt bằng cách sử dụng apt
. Trước tiên để đảm bảo các bản cập nhật và gói phần mềm mới nhất chúng ta cần cập nhật cơ sở dữ liệu của các gói phần mềm bằng cách chạy lệnh dưới đây:
sudo apt update
Tiếp theo cài đặt nginx
, trong lúc cài đặt các bạn cần phải bấm Y
(Yes) để xác nhận cho apt
cài thêm các gói thư viện cần thiết cho nginx
:
sudo apt install nginx
Thiết lập tường lửa (Firewall)
Trước khi chúng ta thiết lập service Nginx, cần phải thiết lập tường lửa để cho phép truy cập vào nó. Nginx nó sẽ tự đăng ký một service với ufw
khi cài đặt. Vì thế chúng ta có thể thiết lập tường lửa để cho phép truy cập vào service Nginx dễ dàng hơn.
Liệt kê tất cả các configuration của ứng dụng mà ufw có thể thiết lập:
sudo ufw app list
Nó sẽ in ra tất cả danh sách các profiles của ứng dụng mà chúng ta có thể thiết lập Firewall:
Available applications: Nginx Full Nginx HTTP Nginx HTTPS OpenSSH
Trong danh sách trên có 3 profile cho Nginx:
- Nginx Full: Đây là profile mở cả 2 port 80 và 443 (TLS/SSL encrypted traffic)
- Nginx HTTP: Profile này chỉ mở cổng 80
- Nginx HTTPS: Profile này chỉ mở cổng 443
Vì chúng ta chưa cài đặt SSL cho Nginx, nên chúng ta sẽ mở port 80 để thử nghiệm xem service Nginx có hoạt động như mong muốn hay không.
Chúng ta sẽ mở cổng 80 bằng lệnh sau:
sudo ufw allow 'Nginx HTTP'
Rules updated Rules updated (v6)
Sau đó kiểm tra lại status bằng lệnh:
sudo ufw status
Nếu bạn nào không hiện output như dưới đây thì hãy xuống dưới sang bước kế tiếp. Còn bạn nào có output như dưới đây thì là do chưa enable ufw
, các bạn enable bằng lệnh sau:
sudo ufw enable
Nếu nó hỏi Command may disrupt existing ssh connections. Proceed with operation (y|n)?
các bạn bấm y
để xác nhận nhé.
Bây giờ chúng ta sẽ kiểm tra lại status và kết quả hiện ra như sau:
Status: active To Action From -- ------ ---- Nginx HTTP ALLOW Anywhere Nginx HTTP (v6) ALLOW Anywhere (v6)
Sau khi thiết lập tường lửa bây giờ chúng ta có thể kiểm tra web server đã hoạt động hay chưa
Một lưu ý quan trọng là chúng ta cần phải cho ufw allow cả OpenSSH vì lúc chúng ta enable ufw lên thì nó sẽ không tự động add rule OpenSSH vào nên không kết nối tới VPS bằng SSH được. Nếu quên bước này thì trong lần kết nối tiếp theo tới VPS sẽ không được.Chạy lệnh: sudo ufw allow 'OpenSSH' sau đó kiểm tra lại status ufw
Kiểm tra Web Server
Khi quá trình cài đặt xong thì Ubuntu sẽ start Nginx lên và web server đã hoạt động. Kiểm tra systemd
xem để chắc chắn rằng service đã và đang hoạt động
systemctl status nginx
● nginx.service - A high performance web server and a reverse proxy server Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled) Active: active (running) since Sun 2024-03-03 09:17:37 UTC; 28min ago Docs: man:nginx(8) Process: 11020 ExecStartPre=/usr/sbin/nginx -t -q -g daemon on; master_process on; (code=exited, status=0/SUCCESS) Process: 11021 ExecStart=/usr/sbin/nginx -g daemon on; master_process on; (code=exited, status=0/SUCCESS) Main PID: 11127 (nginx) Tasks: 3 (limit: 2237) Memory: 4.6M CPU: 67ms CGroup: /system.slice/nginx.service ├─11127 "nginx: master process /usr/sbin/nginx -g daemon on; master_process on;" ├─11130 "nginx: worker process" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" └─11131 "nginx: worker process" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" Mar 03 09:17:37 lahocore systemd[1]: Starting A high performance web server and a reverse proxy server... Mar 03 09:17:37 lahocore systemd[1]: Started A high performance web server and a reverse proxy server.
Output ở trên các bạn sẽ kiểm tra thấy dòng Active: active (running)
nghĩa là service Nginx đã hoạt động.
Bây giờ mở trình duyệt lên và truy cập tới địa chỉ IP VPS của các bạn. Nếu các bạn không nhớ thì có thể chạy lên sau:
ip addr show eth0 | grep inet | awk '{ print $2; }' | sed 's/\/.*$//'
Sau khi có được IP của máy chủ VPS thì truy cập trên trình duyệt như sau http://ip_vps_server
và kết quả như hình dưới đây
Thiết lập Server Blocks
Ở bước này, chúng ta sẽ config tên miền cho web server. Hãy đảm bảo rằng tên miền của các bạn đã trỏ về IP của VPS.
Trong thư mục /etc/nginx/sites-available/
tạo một fiel mới với tên là tên miền của các bạn. Ví dụ tên miền của mình là example.com
thì sẽ tạo file là /etc/nginx/sites-available/example.com
. Chúng ta sẽ tạo bằng lệnh sau:
sudo nano /etc/nginx/sites-available/example.com
Chỉnh sửa nội dung như dưới đây:
server { listen 80; listen [::]:80; server_name example.com www.example.com; location / { try_files $uri $uri/ =404; } }
Bấm Ctrl + X -> Y sau đó bấm Enter để lưu lại file.
Tiếp theo, kích hoạt file này bằng cách liên kết nó tới thư mục sites-enabled
của nginx, nơi mà nó sẽ đọc trong khi khởi động:
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
Để tránh tình trạng vấn đề bộ nhớ hash bucket có thể phát sinh khi thêm các server names bổ sung, cần config giá trị biến server_names_hash_bucket_size
trong file /etc/nginx/nginx.conf
. Mở file nginx.conf lên:
sudo nano /etc/nginx/nginx.conf
Tìm đến dòng có server_names_hash_bucket_size
sau đó xoá kí tự #
để uncomment dòng này:
... http { ... server_names_hash_bucket_size 64; ... } ...
Sau đó bấm Ctrl + X -> Y -> Enter để lưu lại file.
Tiếp theo chạy lệnh dưới đây để kiểm tra xem không có cú pháp nào lỗi trong các file cấu hình Nginx:
sudo nginx -t
Nếu như hiện như dưới đây thì không có vấn đề gì
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful
Sau đó thì restart lại Nginx
sudo systemctl restart nginx
Cấu hình SSL/TLS cho web server Nginx bằng Let's Encrypt
Cài đặt Certbot
Đầu tiên để sử dụng Let's Encrypt để nhận một chứng chỉ SSL là cài đặt Certbot trên máy chủ của chúng ta.
sudo snap install --classic certbot
Khi cài đặt thành công sẽ in ra phiên bản của Certbot
certbot 2.9.0 from Certbot Project (certbot-eff✓) installed
Sau đó tạo một liên kết tượng trưng (symbolic link) tới tệp thực thi certbot (/snap/bin/certbot
) mà chúng ta vừa cài đặt từ thư mục /usr/bin/
. Bước này đảm bảo rằng lệnh certbot
có thể chạy đúng trên máy chủ của chúng ta. Để làm điều này, chúng ta sẽ chạy lệnh ln
sau đây. Lệnh này chứa flag -s
để tạo một liên kết tượng trưng (symbolic link) hoặc liên kết mềm, không phải là một liên kết cứng:
sudo ln -s /snap/bin/certbot /usr/bin/certbot
Kiểm tra lại cấu hình Nginx
Chạy lệnh dưới đây. Nếu không có lỗi nào được tìm thấy, nó sẽ xuất ra một thông báo "syntax is ok"
và "test is successful"
xác nhận rằng cấu hình là hợp lệ.
sudo nginx -t
Nếu có lỗi, hãy mở lại tệp khối máy chủ đã cấu hình ở phần server block và kiểm tra xem có bất kỳ lỗi chính tả hoặc ký tự nào bị thiếu không. Khi cú pháp của tệp cấu hình là chính xác, hãy tải lại Nginx để tải cấu hình mới.
sudo systemctl reload nginx
Cho phép kết nối HTTPS thông qua Firewall
Kiểm tra cấu hình hiện tại của ufw
:
sudo ufw status
Chúng ta sẽ thấy output như dưới đây, nghĩa là chỉ có lưu lượng HTTP được phép tới web server:
Status: active To Action From -- ------ ---- Nginx HTTP ALLOW Anywhere OpenSSH ALLOW Anywhere Nginx HTTP (v6) ALLOW Anywhere (v6) OpenSSH (v6) ALLOW Anywhere (v6)
Bây giờ để cho phép lưu lượng HTTPS, chúng ta cần phải cho phép cả profile Nginx Full và xóa quyền cho phép không cần thiết của profile Nginx HTTP. Chúng ta sẽ thực hiện như dưới đây:
sudo ufw allow 'Nginx Full' sudo ufw delete allow 'Nginx HTTP'
Sau đó kiểm tra lại status của ufw
:
sudo ufw status
Chúng ta sẽ có output như dưới đây:
Status: active To Action From -- ------ ---- OpenSSH ALLOW Anywhere Nginx Full ALLOW Anywhere OpenSSH (v6) ALLOW Anywhere (v6) Nginx Full (v6) ALLOW Anywhere (v6)
Cài đặt SSL Certificate
Certbot cung cấp nhiều cách để đạt được chứng chỉ SSL thông qua các plugin. Plugin Nginx sẽ tự động config lại Nginx và tải lại config khi cần thiết. Để sử dụng plugin này, chúng ta có thể chạy lệnh sau:
sudo certbot --nginx -d example.com -d example.com
certbot
là lệnh để tương tác với Certbot.--nginx
chỉ định rằng chúng ta đang sử dụng plugin Nginx để tự động cấu hình lại Nginx.-d example.com
được sử dụng để chỉ định tên miền của chúng ta muốn đạt được chứng chỉ SSL cho nó. Có thể thêm nhiều tên miền bằng cách thêm thêm flag-d other_domain
Khi lần đầu tiên chạy Certbot, chúng ta sẽ được yêu cầu nhập địa chỉ email và đồng ý với các điều khoản dịch vụ. Sau khi làm điều này, Certbot sẽ giao tiếp với máy chủ Let’s Encrypt để yêu cầu một chứng chỉ cho tên miền của chúng ta. Nếu thành công, sẽ nhận được output sau đây:
Successfully received certificate. Certificate is saved at: /etc/letsencrypt/live/example.com/fullchain.pem Key is saved at: /etc/letsencrypt/live/example.com/privkey.pem This certificate expires on 2024-06-11. These files will be updated when the certificate renews. Certbot has set up a scheduled task to automatically renew this certificate in the background. Deploying certificate Successfully deployed certificate for example.com to /etc/nginx/sites-enabled/example.com Congratulations! You have successfully enabled HTTPS on https://example.com We were unable to subscribe you the EFF mailing list because your e-mail address appears to be invalid. You can try again later by visiting https://act.eff.org. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - If you like Certbot, please consider supporting our work by: * Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate * Donating to EFF: https://eff.org/donate-le
Kiểm tra Certbot tự động làm mới chứng chỉ
Chứng chỉ của Let’s Encrypt chỉ có hiệu lực trong 90 ngày. Điều này nhằm khuyến khích người dùng tự động hóa quá trình làm mới chứng chỉ của họ. Gói certbot mà chúng ta đã cài đặt sẽ xử lý điều này bằng cách thêm một tập lệnh làm mới vào /etc/cron.d
. Tập lệnh này sẽ chạy hai lần mỗi ngày và sẽ tự động làm mới bất kỳ chứng chỉ nào gần hết hạn trong vòng 30 ngày.
Để kiểm tra quá trình này, chúng ta có thể thực hiện một thử nghiệm "dry run" với certbot:
sudo certbot renew --dry-run
Lệnh này sẽ mô phỏng quá trình làm mới chứng chỉ mà không thực sự làm mới chúng. Điều này giúp chúng ta đảm bảo rằng quá trình làm mới được cấu hình đúng và sẵn sàng hoạt động khi chứng chỉ của chúng ta cần được làm mới.
Deploy Node.js app lên VPS Linux Ubuntu
Bây giờ chúng ta sẽ bắt đầu vào phần chính của bài viết này đó là deploy ứng dụng Node.js lên VPS Linux Ubuntu. Ở đây mình sẽ deploy một ứng dụng Node.js + Express.js đã có sẵn của mình ở trên Github, Chúng ta sẽ clone repo đó về và deploy.
Cài đặt Node.js bằng Node Version Manager
Các bạn chạy lần lượt các lệnh sau,
Chạy lệnh dưới đây để cài đặt nvm
trước
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bash
Tiếp theo kích hoạt nvm
chạy lệnh:
source ~/.bashrc
Bây giờ liệt kê các phiên bản của Node.js có sẵn để cài đặt thông qua nvm
:
nvm list-remote
... v19.9.0 v20.0.0 v20.1.0 v20.2.0 v20.3.0 v20.3.1 v20.4.0 v20.5.0 v20.5.1 v20.6.0 v20.6.1 v20.7.0 v20.8.0 v20.8.1 v20.9.0 (LTS: Iron) v20.10.0 (LTS: Iron) v20.11.0 (LTS: Iron) v20.11.1 (Latest LTS: Iron) v21.0.0 v21.1.0 v21.2.0 v21.3.0 v21.4.0 v21.5.0 v21.6.0 v21.6.1 v21.6.2 v21.7.0 v21.7.1
Chúng ta có thể cài đặt một phiên bản của Node bằng cách nhập bất kỳ phiên bản phát hành nào được liệt kê như ở trên. Ở đây mình sẽ cài phiên bản v20.11.1 (Latest LTS: Iron), chạy lệnh sau:
nvm install v20.11.1
Chúng ta có thể xem các phiên bản Node.js bạn đã cài đặt bằng cách chạy lệnh:
nvm list
-> v20.11.1 default -> v20.11.1 iojs -> N/A (default) unstable -> N/A (default) node -> stable (-> v20.11.1) (default) stable -> 20.11 (-> v20.11.1) (default) lts/* -> lts/iron (-> v20.11.1) lts/argon -> v4.9.1 (-> N/A) lts/boron -> v6.17.1 (-> N/A) lts/carbon -> v8.17.0 (-> N/A) lts/dubnium -> v10.24.1 (-> N/A) lts/erbium -> v12.22.12 (-> N/A) lts/fermium -> v14.21.3 (-> N/A) lts/gallium -> v16.20.2 (-> N/A) lts/hydrogen -> v18.19.1 (-> N/A) lts/iron -> v20.11.1
Các bạn có thể chuyển đổi giữa các phiên bản Node.js bằng lệnh:
nvm use v20.11.1
Thay v20.11.1
bằng phiên bản bạn muốn sử dụng.
Kiểm tra Git
Nếu các bạn clone project từ về bằng git thì chúng ta sẽ kiểm tra trước đã có sẵn git trên con VPS của mình chưa bằng cách chạy lệnh:
git --version
Nếu output ra version của Git thì bây giờ chúng ta sẽ sang bước tiếp theo. Nếu chưa thì các bạn cài Git bằng lệnh sau:
sudo apt install git-all
Clone ứng dụng Node.js
Đầu tiên mình sẽ chuyển tới thư mục home
cd /home
Sau đó sẽ clone project trên Github về:
git clone github_repo_url
Khi lần đầu tiên chạy git clone thì chúng ta sẽ được hỏi username và password (token) account Github. Các bạn hãy nhập user và password (token) account Github của các bạn để tiếp tục.
Sau khi clone project về, chúng ta sẽ di chuyển vào thư mục của project và cài đặt các dependencies:
cd myapp npm install
Sau đó chúng ta sẽ chạy thử xem project của chúng ta đã run lên được chưa. Đây là nội dung file index.js của mình:
const express = require('express') const app = express() const port = 3000 app.get('/', (req, res) => { res.send('Hello World!') }) app.listen(port, () => { console.log(`App is listening on: http://localhost:${port}`) })
Chạy lệnh dưới đây để khởi chạy app:
node index.js
Các bạn sẽ thấy output như sau:
App is listening on: http://localhost:3000
Cài đặt PM2
Tiếp theo, chúng ta sẽ cài đặt PM2, một trình quản lý tiến trình cho các ứng dụng Node.js. PM2 cho phép daemonize các ứng dụng để chúng sẽ chạy ở nền như một dịch vụ (service).
Sử dụng npm để cài đặt PM2 mới nhất trên máy chủ VPS của chúng ta:
npm install pm2@latest -g
Đầu tiên, chúng ta sẽ sử dụng lệnh pm2 start
để chạy app của chúng ta, index,js
ở dưới nền:
pm2 start index.js
Lệnh này sẽ khởi chạy app của chúng ta index.js
bằng PM2 và chạy nó ở chế độ nền. Nó cũng thêm ứng dụng của chúng ta vào danh sách tiến trình của PM2, danh sách này sẽ được xuất ra mỗi khi chúng ta khởi động một ứng dụng. Điều này cho phép chúng dễ dàng quản lý các ứng dụng đang chạy bằng PM2.
------------- __/\\\\\\\\\\\\\____/\\\\____________/\\\\____/\\\\\\\\\_____ _\/\\\/////////\\\_\/\\\\\\________/\\\\\\__/\\\///////\\\___ _\/\\\_______\/\\\_\/\\\//\\\____/\\\//\\\_\///______\//\\\__ _\/\\\\\\\\\\\\\/__\/\\\\///\\\/\\\/_\/\\\___________/\\\/___ _\/\\\/////////____\/\\\__\///\\\/___\/\\\________/\\\//_____ _\/\\\_____________\/\\\____\///_____\/\\\_____/\\\//________ _\/\\\_____________\/\\\_____________\/\\\___/\\\/___________ _\/\\\_____________\/\\\_____________\/\\\__/\\\\\\\\\\\\\\\_ _\///______________\///______________\///__\///////////////__ Runtime Edition PM2 is a Production Process Manager for Node.js applications with a built-in Load Balancer. Start and Daemonize any application: $ pm2 start app.js Load Balance 4 instances of api.js: $ pm2 start api.js -i 4 Monitor in production: $ pm2 monitor Make pm2 auto-boot at server restart: $ pm2 startup To go further checkout: http://pm2.io/ ------------- [PM2] Spawning PM2 daemon with pm2_home=/root/.pm2 [PM2] PM2 Successfully daemonized [PM2] Starting /home/myapp/index.js in fork_mode (1 instance) [PM2] Done. ┌────┬──────────┬─────────────┬─────────┬─────────┬──────────┬────────┬──────┬───────────┬──────────┬──────────┬──────────┬──────────┐ │ id │ name │ namespace │ version │ mode │ pid │ uptime │ ↺ │ status │ cpu │ mem │ user │ watching │ ├────┼──────────┼─────────────┼─────────┼─────────┼──────────┼────────┼──────┼───────────┼──────────┼──────────┼──────────┼──────────┤ │ 0 │ index │ default │ 1.0.0 │ fork │ 140692 │ 0s │ 0 │ online │ 0% │ 38.1mb │ root │ disabled │ └────┴──────────┴─────────────┴─────────┴─────────┴──────────┴────────┴──────┴───────────┴──────────┴──────────┴──────────┴──────────┘
Các ứng dụng đang chạy dưới PM2 sẽ được khởi động lại tự động nếu ứng dụng đó bị crash hoặc killed, nhưng chúng ta có thể thực hiện một bước bổ sung để cho ứng dụng được khởi chạy khi hệ thống khởi động bằng cách sử dụng lệnh con startup. Lệnh con này tạo ra và cấu hình một script khởi chạy để khởi động PM2 và các tiến trình được quản lý của nó khi hệ thống khởi động:
pm2 startup systemd
Chúng ta sẽ được output như dưới đây:
[PM2] Init System found: systemd Platform systemd Template [Unit] Description=PM2 process manager Documentation=https://pm2.keymetrics.io/ After=network.target [Service] Type=forking User=root LimitNOFILE=infinity LimitNPROC=infinity LimitCORE=infinity Environment=PATH=/root/.nvm/versions/node/v20.11.1/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin Environment=PM2_HOME=/root/.pm2 PIDFile=/root/.pm2/pm2.pid Restart=on-failure ExecStart=/root/.nvm/versions/node/v20.11.1/lib/node_modules/pm2/bin/pm2 resurrect ExecReload=/root/.nvm/versions/node/v20.11.1/lib/node_modules/pm2/bin/pm2 reload all ExecStop=/root/.nvm/versions/node/v20.11.1/lib/node_modules/pm2/bin/pm2 kill [Install] WantedBy=multi-user.target Target path /etc/systemd/system/pm2-root.service Command list [ 'systemctl enable pm2-root' ] [PM2] Writing init configuration in /etc/systemd/system/pm2-root.service [PM2] Making script booting at startup... [PM2] [-] Executing: systemctl enable pm2-root... Created symlink /etc/systemd/system/multi-user.target.wants/pm2-root.service → /etc/systemd/system/pm2-root.service. [PM2] [v] Command successfully executed. +---------------------------------------+ [PM2] Freeze a process list on reboot via: $ pm2 save [PM2] Remove init script via: $ pm2 unstartup systemd
Dưới đây là một số điểm chính của script khởi động được tạo:
- Script khởi động được lưu tại đường dẫn:
/etc/systemd/system/pm2-root.service
. - PM2 sẽ được chạy dưới quyền
root
. - Script được cấu hình để khởi động PM2 bằng phiên bản Node.js được quản lý bởi NVM (
/root/.nvm/versions/node/v20.11.1
). - Khi hệ thống khởi động lại, script này sẽ tự động được kích hoạt để khởi động PM2.
pm2 save
sẽ lưu trữ thông tin về các quy trình PM2 đang quản lý để có thể khôi phục lại sau khi hệ thống khởi động lại.pm2 unstartup systemd
được sử dụng để gỡ bỏ script khởi động của PM2 từ systemd. Khi chúng ta chạy lệnh này, PM2 sẽ gỡ bỏ script khởi động systemd đã được tạo trước đó để PM2 không còn tự động khởi động cùng với hệ thống.
Ở đây chúng ta sẽ chạy lệnh pm2 save
để lưu lại file script khởi động này:
pm2 save
Bây giờ chúng ta sẽ start dịch vụ này bằng systemctl
:
systemctl start pm2-root
Sau đó kiểm tra lại status:
systemctl status pm2-root
Chúng ta sẽ được output như dưới đây:
● pm2-root.service - PM2 process manager Loaded: loaded (/etc/systemd/system/pm2-root.service; enabled; vendor preset: enabled) Active: active (running) since Mon 2024-03-18 14:57:01 UTC; 32s ago Docs: https://pm2.keymetrics.io/ Process: 145513 ExecStart=/root/.nvm/versions/node/v20.11.1/lib/node_modules/pm2/bin/pm2 resurrect (code=exited, status=0/SUCCESS) Main PID: 140675 (PM2 v5.3.1: God) Tasks: 0 (limit: 2237) Memory: 4.0K CPU: 688ms CGroup: /system.slice/pm2-root.service ‣ 140675 "PM2 v5.3.1: God Daemon (/root/.pm2)" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" Mar 18 14:57:00 lahocore systemd[1]: Starting PM2 process manager... Mar 18 14:57:01 lahocore pm2[145513]: [PM2] Resurrecting Mar 18 14:57:01 lahocore pm2[145513]: [PM2] Restoring processes located in /root/.pm2/dump.pm2 Mar 18 14:57:01 lahocore pm2[145513]: ┌────┬──────────┬─────────────┬─────────┬─────────┬──────────┬────────┬──────┬───────────┬──────────┬──────────┬──────────┬──────────┐ Mar 18 14:57:01 lahocore pm2[145513]: │ id │ name │ namespace │ version │ mode │ pid │ uptime │ ↺ │ status │ cpu │ mem │ user │ watching │ Mar 18 14:57:01 lahocore pm2[145513]: ├────┼──────────┼─────────────┼─────────┼─────────┼──────────┼────────┼──────┼───────────┼──────────┼──────────┼──────────┼──────────┤ Mar 18 14:57:01 lahocore pm2[145513]: │ 0 │ index │ default │ 1.0.0 │ fork │ 140692 │ 13m │ 0 │ online │ 0% │ 51.7mb │ root │ disabled │ Mar 18 14:57:01 lahocore pm2[145513]: └────┴──────────┴─────────────┴─────────┴─────────┴──────────┴────────┴──────┴───────────┴──────────┴──────────┴──────────┴──────────┘ Mar 18 14:57:01 lahocore systemd[1]: Started PM2 process manager.
Dưới đây là các lệnh của PM2 để các bạn có thể quản lý ứng dụng của mình:
Dừng một ứng dụng trong PM2:
pm2 stop
Khởi động lại một dứng dụng:
pm2 restart app_name_or_id
Xem danh sách ứng dụng đang chạy trong PM2:
pm2 list
Xem thông tin ứng dụng:
pm2 info app_name
Thiết lập Nginx như một Reverse Proxy Server
Điều này sẽ giúp chuyển hướng yêu cầu từ máy khách tới các máy chủ back-end và xử lý yêu cầu này trước khi gửi đến máy chủ back-end.
Trong bước này, chúng ta sẽ cấu hình Nginx như một máy chủ proxy nghịch đảo để chuyển hướng yêu cầu từ người dùng đến ứng dụng của chúng ta đang chạy trên localhost. Chúng ta sẽ mở tệp cấu hình Nginx đã tạo ở các bước trên (với tên miền example.com
) để tiếp tục cấu hình. Mở file cấu hình bằng cách chạy lệnh:
sudo nano /etc/nginx/sites-available/example.com
Trong khối server, chúng ta đã có một khối location / hiện có. Thay thế nội dung của khối đó với cấu hình sau:
... location / { proxy_pass http://localhost:3000; 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; } ...
Sau đó lưu lại Ctrl + X -> Y -> Enter
.
Cấu hình này nghĩa là khi người dùng truy cập vào địa chỉ https://example.com/
, Nginx sẽ chuyển hướng yêu cầu đến ứng dụng của chúng ta đang chạy trên localhost với cổng 3000.
Ví dụ, nếu chúng ta có một ứng dụng Node.js đang chạy trên localhost với tệp index.js
và nó lắng nghe trên cổng 3000, mọi yêu cầu gửi đến https://example.com/
sẽ được chuyển tiếp tới index.j
s thông qua Nginx.
Điều này giúp tạo ra một phản ứng tự động từ phía máy chủ khi người dùng truy cập vào trang chủ của tên miền của chúng ta.
Bây giờ hãy kiểm tra lại nginx có bị lỗi gì không:
sudo nginx -t
Nếu mọi thứ OK hết thì sẽ restart lại nginx:
sudo systemctl restart nginx
Nếu ứng dụng Node.js của chúng ta đang chạy và cấu hình của ứng dụng cũng như cấu hình của Nginx đã được thiết lập đúng, bây giờ chúng ta có thể truy cập vào ứng dụng của mình thông qua máy chủ proxy nghịch đảo của Nginx. Truy cập vào tên miền mà chúng ta đã thiết lập và xem kết quả.
Lời kết
Bài viết hơi dài, nhưng mong nó sẽ giúp ích được cho các bạn! Bây giờ các bạn đã có ứng dụng Node.js của mình đang chạy sau một máy chủ proxy nghịch đảo của Nginx trên một máy chủ VPS Linux Ubuntu. Bạn nào có câu hỏi hoặc gặp khó khăn trong quá trình setup thì có thể nhắn trực tiếp lên page FB nhé!
Trong các bài viết sau mình sẽ hướng dẫn các bạn deploy các ứng dụng như Next.js, Nest.js, v.v lên VPS Linux Ubuntu.
Xem thêm: Next.js 14: Cách Sử Dụng Next Auth cơ bản để xác thực
Cảm ơn các bạn đã theo dõi bài viết!
Tham gia cuộc trò chuyện