Deploy một dự án Rails với Passenger và Nginx

Phusion passenger được hiểu như một công cụ kết nối tự động giữa webserver và một ứng dụng web app


10 min read
Deploy một dự án Rails với Passenger và Nginx

1. Giới thiệu Passenger.

Phusion passenger được hiểu như một công cụ kết nối tự động giữa webserver và một ứng dụng web app, Ví dụ: Bạn có một web app (rails) và bạn muốn deploy lên một máy chủ (vps) đang sử dụng websever (nginx), passenger sẽ giúp việc deploy trở nên dễ dàng.

Passenger giúp tối ưu hóa hiệu suất, sử dụng bộ nhớ thấp và dễ sử dụng.

Dưới đây là bảng so sánh tốc độ giữa các Rails Server, Passenger vượt trội hơn hẳn .


2. Cài đặt Passenger + Nginx trên Linux/Unix production server

Nội dung

  • 2.1: Cài đặt Passenger packages
  • 2.2: Cấu hình module Passenger với Nginx
  • 2.3: Kiểm tra cài đặt
  • 2.4: Cập nhật định kỳ

Trong bài viết này chúng ta sẽ triển khai trên Ubuntu 18.04 LTS

2.1: Cài đặt Passenger packages

Để tiếp tục chúng ta phải cài đặt Nginx, nếu đã cài vui lòng bỏ qua bước này:

Chạy lệnh sau:

sudo apt-get install nginx

Tiếp theo là việc cài đặt Passenger + Nginx module thông qua Phusion APT repository.

# Install our PGP key and add HTTPS support for APT
sudo apt-get install -y dirmngr gnupg
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 561F9B9CAC40B2F7
sudo apt-get install -y apt-transport-https ca-certificates

sudo sh -c 'echo deb https://oss-binaries.phusionpassenger.com/apt/passenger bionic main > /etc/apt/sources.list.d/passenger.list'
sudo apt-get update

sudo apt-get install -y libnginx-mod-http-passenger

2.2: Cấu hình Passenger với Nginx

Kiểm tra các tập tin cấu hình xem đã tồn tại hay chưa, để nạp module Passenger với nginx:

sudo ln -s /usr/share/nginx/modules-available/mod-http-passenger.load /etc/nginx/modules-enabled/50-mod-http-passenger.conf

Nếu không tìm thấy file: /etc/nginx/conf.d/mod-http-passenger.conf, hãy tạo mới sau đó thêm các tùy chọn passenger_rubypassenger_root như sau, ví dụ:

passenger_root /usr/lib/ruby/vendor_ruby/phusion_passenger/locations.ini;
passenger_ruby /usr/bin/passenger_free_ruby;

Tiếp theo khởi động lại dịch vụ Nginx:

sudo service nginx restart # huặc sudo systemctl restart nginx

‌2.3: Kiểm tra cài đặt

Sau khi cài đặt xong,  để kiểm tra: sudo /usr/bin/passenger-config validate-install. Ví dụ:

sudo /usr/bin/passenger-config validate-install
 #* Checking whether this Phusion Passenger install is in PATH... ✓
 #* Checking whether there are no other Phusion Passenger installations... ✓

Cuối cùng, kiểm tra các thông tin cấu hình đã chính xác chưa bằng lệnh sau: sudo /usr/sbin/passenger-memory-stats. Các thông số Nginx cũng như Passenger như sau, ví dụ:

sudo /usr/sbin/passenger-memory-stats
#Version: 6.0.2
#Date   : 2019-06-16 10:22:34 +0000

#---------- Nginx processes -----------
#PID    PPID   VMSize    Private  Name
#--------------------------------------
#29605  1      141.9 MB  0.5 MB   nginx: master process /usr/sbin/nginx -g #daemon on; master_process on;
#29609  29605  144.6 MB  0.9 MB   nginx: worker process
### Processes: 2
### Total private dirty RSS: 1.43 MB

#----- Passenger processes -----
#PID    VMSize    Private  Name
#-------------------------------
#29583  390.0 MB  2.6 MB   Passenger watchdog
#29594  675.0 MB  4.1 MB   Passenger core
#29769  429.3 MB  68.6 MB  Passenger AppPreloader: #/var/www/deploy_ror_app/code (forking...)

Nếu vẫn không thấy process của Nginx or Passenger chạy, có lẽ vì một số vấn đề như cài đặt hoặc cấu hình. Hãy tham khảo thêm ở đây.

2.4: Cập nhật định kỳ

Để cập nhật Nginx, Passenger và system, chạy lệnh sau:

sudo apt-get update
sudo apt-get upgrade

Không cần phải khởi động lại Nginx hoặc Passenger sau khi cập nhật, qúa trình được thực hiện tự động bởi APT.

Bước tiếp theo

Việc đã cài đặt Passenger đã xong, chúng ta có thể triển khai ứng dụng Rails lên production server!


3. Triển khai Ruby app trên Linux/Unix production server

Nếu chưa cài đặt Ruby on Rails vui lòng tham khảo tại đây.

Nội dung

  • 3.1 Đưa app code lên server
  • 3.1.1 Đăng nhập vào server, tạo user cho app
  • 3.1.2 Cài đặt Git lên server
  • 3.1.2 Pull code
  • 3.2 Chuẩn bị môi trường cho app
  • 3.2.1 Đăng nhập với app user
  • 3.2.2 Cài đặt các dependencies
  • 3.2.3 Cấu hình database.yml và secrets.yml
  • 3.2.4 Biên dịch Rails assets và chạy database migrations
  • 3.3 Cài đặt Nginx và Passenger
  • 3.3.1 Các lệnh Ruby nên dùng cho Passenger
  • 3.3.2 Quay lại với tài khoản admin
  • 3.3.3 Cấu hình Nginx
  • 3.3.4 Kiểm thử

Đầu tiên chúng ta cần tạo một rails app dưới local or có thể clone về tại đây

rvm use 2.6.1 # sử dụng ruby 2.6.1 thông qua RVM 
rails new deploy_ror_app
cd deploy_ror_app

Thêm gem "passenger" vào Gemfile

gem "passenger", require: "phusion_passenger/rack_handler"

Sau đó bundle install

Tạo mới một repository deploy_rails_app, sau đó push code lên github, thay username bằng tên người dùng github.

git init
git add . 
git commit -m 'init app' 
git remote add origin [email protected]:username/deploy_rails_app.git
git push -u origin master

3.1 Đưa app code lên server

3.1.1 Đăng nhập vào server, tạo user cho app

Đăng nhập vào server sử dụng SSH:

ssh [email protected]

Với user là tài khoản có quyền admin hoặc sudo.

Từ giờ trở đi, tất cả các lệnh thực hiện đều ở trên server

Chúng ta nên tạo một user để chạy ứng dụng. Vì lý do bảo mật nên app sẽ chỉ nên chạy trong phạm vi của user đó (để hạn chế thiệt hại mà các lỗ hổng bảo mật trong ứng dụng có thể gây ra).

Để thêm mới user: rails_user

sudo adduser rails_user

Cấu hình SSH key cho rails_user user:

sudo mkdir -p ~rails_user/.ssh 
touch $HOME/.ssh/authorized_keys
sudo sh -c "cat $HOME/.ssh/authorized_keys >> ~ror_user/.ssh/authorized_keys"
sudo chown -R ror: ~rails_user/.ssh
sudo chmod 700 ~rails_user/.ssh
sudo sh -c "chmod 600 ~rails_user/.ssh/*"

3.1.2 Cài đặt Git lên server

sudo apt-get install nginx

3.1.2 Pull code

Tạo thư mục để lưu trữ source code và gán quyền sở hữu cho user.

sudo mkdir -p /var/www/deploy_rails_app 
sudo chown rails_user:rails_user -R /var/www/deploy_rails_app

Thay deploy_rails_apprails_user bằng tên app và tên app_user.

Pull source code từ Github:

cd /var/www/deploy_rails_app
sudo -u ror -H
git clone git://github.com/username/deploy_rails_app.git code

Code sau khi pull về sẽ nằm ở thư mục: /var/www/deploy_rails_app/code.

3.2 Chuẩn bị môi trường cho app

3.2.1 Đăng nhập với app user

‌‌Đăng nhập vào server dưới tài khoản người dùng của ứng dụng như sau:

thaidn$ sudo -u rails_user -H bash -l

Nếu đang sử dụng RVM, hãy chọn một Ruby version phù hợp. Ví dụ:

rvm use 2.6.1

3.2.2 Cài đặt các dependencies

Ứng dụng có nhiều dependencies khác nhau, hầu hết các dependencies này là gems trong Gemfile được quản lý bởi Bundler. Bạn có thể cài đặt chúng bằng cách chạy:

cd /var/www/deploy_rails_app/code 
bundle install --deployment --without development test

3.2.3 Cấu hình database.yml và secrets.yml

Chúng ta sẽ cấu hình với cơ sở dữ liệu SQLite(mặc định), ngoài ra bạn thể tham khảo cách cấu hình cho PosgreSQL, MongoDB, etc. Sửa lại file: config/database.yml

nano config/database.yml

Đảm bảo phần production giống như dưới đây:

production:
    adapter: sqlite3 
    database: db/production.sqlite3

Rails cũng cần một secret key để mã hóa các sessions của nó. Bắt đầu từ Rails 4, secret key này được lưu trữ trong config/secret.yml. Nhưng trước tiên, chúng ta cần tạo một secret key. Chạy:

bundle exec rake secret

Lệnh này sẽ xuất ra nội dung một secret key. Sao chép giá trị đó vào config/secret.yml:

nano config/secrets.yml

‌Đây là nội dung file nếu đã tồn tại, tạo mới nếu chưa có.

production:
    secret_key_base: <%=ENV["SECRET_KEY_BASE"]%>

Sau đó chèn chuỗi secret key đó vào đây.

production:
    secret_key_base: nội dung 'rake secret' vừa tạo

‌Để ngăn người dùng khác trên hệ thống đọc thông tin nhạy cảm, cấp quyền truy cập cho user: rails_user với thư mục config và thư mục db:

chmod 700 config db
chmod 600 config/database.yml config/secrets.yml

‌‌3.2.4 Biên dịch Rails assets và chạy database migrations

bundle exec rake assets:precompile db:migrate RAILS_ENV=production

3.3 Cài đặt Nginx và Passenger

Bây giờ chúng ta đã hoàn tất việc đưa app lên server và thiết lập môi trường cho ứng dụng, sau đây là việc cấu hình Nginx cho Passenger chạy ứng dụng.

3.3.1 Các lệnh Ruby nên dùng cho Passenger

Trong trường hợp có nhiều Ruby version trên hệ thống, chạy passenger-config about ruby-command để xem version nào bạn đang sử dụng.

passenger-config about ruby-command

 #Command: /usr/local/rvm/wrappers/ruby-2.6.1/ruby
 #Version: ruby 2.6.1p33 (2019-01-30 revision 66950) [x86_64-linux]
 #To use in Nginx : passenger_ruby /usr/local/rvm/wrappers/ruby-2.6.1/ruby

‌Hãy note lại phần "Command" (/usr/local/rvm/gems/ruby-2.6.1/wrappers/ruby). Chúng ta sẽ cần nó trong những bước sau.

3.3.2 Quay lại với tài khoản admin

Chúng ta đã đăng nhập vào tài khoản người dùng của ứng dụng (rails_user) để cài đặt môi trường, tuy nhiên user đó không có quyền sudo. Để chỉnh sửa các tệp cấu hình, cần thoát tài khoản hiện tại:

rails_user$ exit 
thaidn$

3.3.3 Cấu hình Nginx

Cần tạo tệp cấu hình Nginx và thiết lập mục virtual host trỏ đến ứng dụng. Mục virtual host này cho Nginx (và Passenger) biết ứng dụng của bạn được đặt ở đâu.

sudo nano /etc/nginx/sites-enabled/deploy_rails_app.conf 

‌Đổi deploy_rails_app với tên app bạn đã tạo.

Nội dung bên trong file:

server {
    listen 80;
    server_name server.com;

    # Tell Nginx and Passenger where your app's 'public' directory is
    root /var/www/deploy_ror_app/code/public;

    # Turn on Passenger
    passenger_enabled on;
    passenger_ruby /path-to-ruby;
}

Thay server.comvới tên host (DomainName huặc IP của server) và /var/www/deploy_rails_app/code với đường dẫn tới thư mục app. Nginx được cấu hình trỏ tới thư mục public!

Thay /path-to-ruby bằng lệnh chúng ta đã note ở mục 3.3.1.

Khởi động lại Nginx:

sudo service nginx restart

3.3.4 Kiểm thử

Hãy thử chạy ở dưới local trước, đổi server_name bằng tên server hostname, như trong phần server_name của file cấu hình Nginx.

curl http://server.com/
#...your app's front page HTML...

‌ ‌Nếu không thấy nội dung HTML xuất hiện, sau đây là những nguyên nhân:

  1. Cấu hình sai phần server_name. Tên server_name phải khớp chính xác với tên máy chủ trong URL. Ví dụ: nếu bạn sử dụng lệnh curl http://45.55.91.235 để truy cập ứng dụng, thì server_name tương ứng 45.55.91.235
  2. Chưa cấu hình bản ghi DNS (thiết lập DNS nằm ngoài phạm vi của hướng dẫn này). Chúng ta nên sử dụng địa chỉ IP của máy chủ làm tên máy chủ.

Bước tiếp theo

Tới đây, chúng ta đã triển khai thành công ứng dụng!


4. Triển khai cập nhật ứng dụng

Ở bước trước, chúng ta đã triển khai một ứng dụng trên production server. Tiếp theo là việc cập nhật ứng dụng và cần triển khai các bản cập nhật?‌‌Nội dung

  • 4.1 Pull code mới nhất
  • 4.2 Chuẩn bi ứng dụng
  • 4.2.1 Chuyển đổi Ruby version
  • 4.2.2 Cài đặt các dependencies
  • 4.2.3 Biên dịch Rails assets và migration
  • 4.3 Khởi động ứng dụng

4.1 Pull code mới nhất

Đăng nhập vào server:

ssh [email protected]

Chuyển đến thư mục chứa source code trên server, sau đó pull code mới nhất về:

cd /var/www/deploy_rails_app/code
git pull

4.2 Chuẩn bị ứng dụng

4.2.1 Chuyển Ruby version

Nếu đang sử dụng RVM để quản lý, để chuyển về version tương ứng (chúng ta nên thống nhất một version khi tạo & triển khai app), ví dụ: ở đây là 2.6.1

rvm use 2.6.1

4.2.2 Cài đặt các dependencies

Các gem dependencies của ứng dụng có thể đã thay đổi, để cài đặt các cập nhật. Chạy:

bundle install --deployment --without development test

4.2.3 Biên dịch Rails assets và migration

bundle exec rake assets:precompile db:migrate RAILS_ENV=production

‌4.3 Khởi động ứng dụng

passenger-config restart-app `pwd`

Để deploy một cách tự động và đơn giản hơn, trong bài viết sau chúng ta sẽ thực hiện deploy thông qua Capistrano.


Tham khảo:

https://techblog.vn/tim-hieu-ve-phusion-passenger-va-su-dung-no-de-deploy-mot-rails-application
https://www.phusionpassenger.com/library/walkthroughs/deploy/ruby/ 
https://shinesolutions.com/2016/05/13/the-emergence-of-the-3-towers-devsecops/
https://www.bacancytechnology.com/blog/comparison-of-ruby-web-servers

Related Articles

RESTful: Phần 4 - API Rate Limiting
10 min read
RESTful: Phần 3 - API Caching
12 min read
The queue data structure
3 min read

GO TOP

🎉 You've successfully subscribed to itplusX!
OK
]