- vừa được xem lúc

How To Set Up a Node.js Application for Production with pm2, nginx

0 0 87

Người đăng: Dương Phạm

Theo Viblo Asia

Mở đầu

Bài này mình viết với mục đích để tổng hợp lại kiến thức và bổ sung kĩ thuật liên quan đến server cho bản thân. Thực tế thì có rất nhiều cách để deploy ứng dụng nodejs (express framework), nhưng trong bài này mình sẽ lựa chọn stack capistrano + pm2 + nginx

Init project

Để cho nhanh mình sử dụng express-generator để init project như sau:

npx express-generator --view=ejs --git

Tham khảo: https://expressjs.com/en/starter/generator.html .

Sau khi đã init và start ứng dụng thành công , bước tiếp theo là cài đặt capistrano cho việc tự động depoly code lên server

Capistrano (local side)

Prerequisite

Trước tiên các bạn cần phải cài đặt ruby (rbenv or rvm). Sau đó bạn có thể init Gemfile bằng câu lệnh bundle init

Edit Gemfile như dưới đây, sau đó chạy bundle install để cài đặt gem.

source 'https://rubygems.org' git_source(:github) {|repo_name| "https://github.com/#{repo_name}" } group :development do gem 'capistrano', require: false gem 'capistrano-npm', require: false
end

Generate file config với câu lệnh $ cap install. Trong Capfile bỏ comment dòng dưới đây

# Load DSL and set up stages
require 'capistrano/setup'
require 'capistrano/deploy'
require 'capistrano/scm/git'
install_plugin Capistrano::SCM::Git
require 'capistrano/npm' Dir.glob('lib/capistrano/tasks/*.rake').each { |r| import r }

Việc tiếp theo là sửa file config/deploy.rb

# config valid for current version and patch releases of Capistrano
lock "~> 3.14.1" set :application, 'nodejs_skeleton'
set :repo_url, '_@.com:duongpham910/nodejs_skeleton.git'
set :keep_releases, 5
set :deploy_to, '/var/www/nodejs_skeleton' namespace :deploy do desc 'Restart pm2' task :restart_app do on roles(:app) do execute 'sudo /etc/init.d/nodejs_skeleton restart' end end before :finished, :restart_app
end

Tuỳ thuộc vào môi trường ( trong trường hợp này là production). Mở file config/deploy/production.rb

set :user, 'ec2-user'
set :stage, :production
set :ssh_options, { keys: %w(~/key.pem), forward_agent: false, auth_methods: %w(publickey)
} # Pass varibale to deploy from different git branches
set :deploy_ref, ENV['DEPLOY_REF']
if fetch(:deploy_ref) set :branch, fetch(:deploy_ref)
else set :branch, 'master'
end # Setup IP with ec2 server
server '', user: fetch(:user), roles: %w[app web]

EC2 (server side)

Prerequisite

Cần cài đặt các package sau

  • Nginx
sudo yum install nginx
  • Node (& yarn or npm)

Cài đặt nvm

> git clone https://github.com/creationix/nvm.git ~/.nvm source ~/.nvm/nvm.sh

Sửa file .bashrc như dưới, sau đó chạy lệnh source .bashrc

if [[ -s ~/.nvm/nvm.sh ]] ; then source ~/.nvm/nvm.sh ;
fi

Cuối cùng

nvm install 12.16.1
nvm use 12.16.1
node -v
ln -s `which node` /usr/local/bin/node //create symlink
  • PM2
npm install -g pm2
ln -s `which pm2` /usr/local/bin/pm2 //create symlink

App preparation

Các bạn cần tạo thư mục có đường dẫn như sau /var/www/nodejs_skeleton. Cấp quyền cho thư mục:

sudo chmod -R 777 /www

Trong nodejs_skeleton directory tạo thư mục sau để chuẩn bị cho việc deploy bằng capistrano

repo
releases
shared

Configuration

Nginx

Tạo file config như sau sudo vi /etc/nginx/conf.d/nodejs_skeleton.conf

server { 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; }
}

Tiếp theo các bạn cần sửa file nginx.config sudo vi /etc/nginx/nginx.conf

 # listen 80 default_server; # listen [::]:80 default_server; # server_name _; # root /usr/share/nginx/html;

Kiểm tra file nginx đã hoạt động chính xác chưa

sudo nginx -t
Still error: nginx: [warn] conflicting server name "" on 0.0.0.0:80, ignored

Lệnh start/stop/restart service của nginx như sau

sudo chkconfig nginx on
sudo service nginx start/stop/restart

PM2

Tạo thư mục client_deploy rồi tạo file config cho PM2 như dưới (hoặc đặt trong thư mục shared) với cluster 2 instance

// Options reference: https://pm2.io/doc/en/runtime/reference/ecosystem-file/
module.exports = { apps : [{ name: 'nodejs_skeleton', cwd: '/var/www/nodejs_skeleton/current', script: '/var/www/nodejs_skeleton/current/bin/www', exec_mode: 'cluster_mode', instances: 2, max_memory_restart: '300M', env: { NODE_ENV: 'production' } }],
};

Init.d Script

  • Tạo 1 Script tên nodejs_skeleton như dưới trong /etc/init.d/nodejs_skeleton
  • Cấp quyền: sudo chmod 755 /etc/init.d/nodejs_skeleton
#!/bin/bash
# chkconfig: 2345 98 02
#
# description: PM2 next gen process manager for Node.js NAME=nodejs_skeleton
PM2=/usr/local/bin/pm2
NODE=/usr/local/bin/node
USER=ec2-user
CONFIG_FILE_PATH=/home/ec2-user/client_deploy/ecosystem.config.js export PATH=/usr/local/bin:$PATH
export PM2_HOME="/home/ec2-user/.pm2" get_user_shell() { local shell shell=$(getent passwd "${1:-$(whoami)}" | cut -d: -f7 | sed -e 's/[[:space:]]*$//') if [[ $shell == *"/sbin/nologin" ]] || [[ $shell == "/bin/false" ]] || [[ -z "$shell" ]]; then shell="/bin/bash" fi echo "$shell"
} super() { local shell shell=$(get_user_shell $USER) su - "$USER" -s "$shell" -c "PATH=$PATH; PM2_HOME=$PM2_HOME $*"
} start() { echo "Starting $NAME" super $PM2 start $CONFIG_FILE_PATH --update-env
} stop() { super $NODE $PM2 kill
} restart() { echo "Restarting $NAME" stop start
} reload() { echo "Reloading $NAME" super $PM2 reload all
} status() { echo "Status for $NAME:" super $NODE $PM2 list RETVAL=$?
} case "$1" in start) start ;; stop) stop ;; status) status ;; restart) restart ;; *) echo "Usage: {start|stop|status|restart}" exit 1 ;;
esac
exit $RETVAL

Commands

Cũng giống như các câu lệnh của webserver như nginx. Khi bị lỗi cũng có thể stop/start hoặc restart.

  • Start PM2
sudo /etc/init.d/nodejs_skeleton start
  • Stop PM2
sudo /etc/init.d/nodejs_skeleton stop
  • Restart PM2
sudo /etc/init.d/nodejs_skeleton restart
  • Check Status
sudo /etc/init.d/nodejs_skeleton status

Deploy

cap staging deploy // Deploy code base from master branch
cap staging deploy DEPLOY_REF=A // Deploy code from branch A

Bình luận

Bài viết tương tự

- vừa được xem lúc

Deploy ReactJs Project lên môi trường Production với PM2

Mở đầu. PM2 là một công cụ quản lý process của NodeJS, có thể tự động quản lý và tự động khởi động lại các process khi có lỗi.

0 0 29

- vừa được xem lúc

Blue-Green deployment với nginx và pm2

Trong bài viết này sẽ mô tả lại quá trình triển khai(deploy) ứng dụng node.js với nginx và pm2 sử dụng kĩ thuật Blue-Green deployment để giảm thiểu downtime tới mức thấp nhất.

0 0 13

- vừa được xem lúc

PM2 - Quản lý tiến trình ứng dụng Node.js

PM2 là một trình quản lý tiến trình mạnh mẽ dành cho các ứng dụng Node.js, giúp đơn giản hóa việc triển khai, giám sát và quản lý ứng dụng của bạn.

0 0 10

- vừa được xem lúc

Quản lý laravel queue work với PM2

Thông thường với ứng dụng Laravel, chúng ta thường chạy và giám sát queue bằng cách sử dụng supervisor. Tuy nhiên supervisor chỉ có trên linux, trong trường hợp máy chủ là windows hoặc đơn giản là muố

0 0 13

- vừa được xem lúc

Deploy Serverless với Express và MongoDB

Trong bài viết này, chúng ta sẽ cùng tìm hiểu quá trình xây dựng một ứng dụng web hướng database. Bài viết phù hợp cho developer nào theo hướng full-stack cho các dự án riêng mà không cần phải lo lắng đến việc cài đặt và bảo trì hạ tầng với nhiều service phức tạp.

0 0 41

- vừa được xem lúc

Xây dựng server với chức năng gửi MAIL, tạo HTML Email Responsive thông qua một vài framework hỗ trợ.

1. Tìm hiểu về Nodemailer.

0 0 182