In this article, I will illustrate how to deploy a Rails 5.2 app on AWS EC2, Ubuntu, Nginx and Passenger in details.

It takes 1–2 hours if everything goes well.

Environments

Ruby 2.5.1

rvm 1.29.7

Rails 5.2

AMS EC2

Ubuntu 18.04 LTS 20180814

1. Set up EC2 Ubuntu

Visit AWS EC2 console page and create a new EC2 instance.

Select “Ubuntu Server 18.04 LTS”.

FYI, the pricing is the same as Amazon Linux:

Ubuntu 18.04 LTS — Bionic

Login to the EC2 via ssh after it starts.

NOTE: the defaul user name is “ubuntu”.

$ ssh -p 22 -i ~/.ssh/[YOUR_KEY] ubuntu@[YOUR_IP_ADDRESS]

2. Install Ruby

Next, install Ruby in the Ubuntu.

System configuration

$ sudo apt-get update

$ sudo apt-get install -y curl gnupg build-essential

RVM configuration



$ curl -sSL

$ sudo gpg2 — keyserver hkp://pool.sks-keyservers.net — recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB

$ curl -sSL

$ sudo usermod -a -G rvm ‘YOUR_USER_NAME’ $ sudo apt-get install gnupg2 -y$ curl -sSL https://get.rvm.io | bash -s stable — ruby=2.5.1$ sudo gpg2 — keyserver hkp://pool.sks-keyservers.net — recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB$ curl -sSL https://get.rvm.io | sudo bash -s stable$ sudo usermod -a -G rvm ‘YOUR_USER_NAME’

Re-login to the EC2 in order to apply the above configurations.



$ ssh -p 22 -i ~/.ssh/[YOUR_KEY] ubuntu@[YOUR_IP_ADDRESS]

$ rvm -v

rvm 1.29.7 (latest) by Michal Papis, Piotr Kuczynski, Wayne E. Seguin [ $ exit$ ssh -p 22 -i ~/.ssh/[YOUR_KEY] ubuntu@[YOUR_IP_ADDRESS]$ rvm -vrvm 1.29.7 (latest) by Michal Papis, Piotr Kuczynski, Wayne E. Seguin [ https://rvm.io

Ruby configuration

Install Ruby secifying a particular version that you want to use globally, and set it as the default.

$ rvm install ruby 2.5.1

$ rvm — default use ruby 2.5.1

Install bundler

$ gem install bundler — no-rdoc — no-ri

Install Node.js

$ sudo apt-get install -y nodejs &&

> sudo ln -sf /usr/bin/nodejs /usr/local/bin/node

3. Set up Passenger & Nginx

Install Passenger packages

$ 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

$ sudo apt-get update $ 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

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

Activate Passenger Nginx

Confirm the path of the configuration file, and add the link.

$ if [ ! -f /etc/nginx/modules-enabled/50-mod-http-passenger.conf ]; then sudo ln -s /usr/share/nginx/modules-available/mod-http-passenger.load /etc/nginx/modules-enabled/50-mod-http-passenger.conf ; fi

$ sudo ls /etc/nginx/conf.d/mod-http-passenger.conf

Re-start the Nginx after the above commands.

$ sudo apt install nginx-core

$ sudo service nginx restart

Confirm the install

Make sure if the Passenger has been successfully installed.

$ sudo /usr/bin/passenger-config validate-install

What would you like to validate?

Use <space> to select.

If the menu doesn’t display correctly, press ‘!’ ‣ ⬢ Passenger itself

⬡ Apache — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — -

* Checking whether this Passenger install is in PATH… ✓

* Checking whether there are no other Passenger installations… ✓ Everything looks good. :-)

Also, make sure if the Nginx has started the Passenger.

$ sudo /usr/sbin/passenger-memory-stats

Version: 6.0.1

Date : 2019–01–17 21:25:01 +0000

— — — — — Nginx processes — — — — — -

PID PPID VMSize Private Name

— — — — — — — — — — — — — — — — — — —

14759 1 141.1 MB 0.4 MB nginx: master process /usr/sbin/nginx -g daemon on; master_process on;

14762 14759 143.7 MB 0.7 MB nginx: worker process

### Processes: 2

### Total private dirty RSS: 1.02 MB — — — Passenger processes — — -

PID VMSize Private Name

— — — — — — — — — — — — — — — -

14738 389.2 MB 2.3 MB Passenger watchdog

14748 673.0 MB 3.2 MB Passenger core

### Processes: 2

### Total private dirty RSS: 5.51 MB

Everything is fine if both Nginx and Passenger are running.

Update regulary

Both Nginx and Passenger are periodically updated via APT. So, it is better to update them regulary with the following commands.

$ sudo apt-get update

$ sudo apt-get upgrade

4. Deploy Rails App

Software to be pre-Installed

Install Git.

$ sudo apt-get install -y git

Install MySQL.

$ sudo apt-get install mysql-server mysql-client

$ sudo apt-get install libmysqlclient-dev

Install Yarn if it is required by your app.



$ echo “deb

$ sudo apt-get update && sudo apt-get install yarn $ curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -$ echo “deb https://dl.yarnpkg.com/debian/ stable main” | sudo tee /etc/apt/sources.list.d/yarn.list$ sudo apt-get update && sudo apt-get install yarn

Rails configuration

Clone your app with Git.

$ cd /var/www

$ sudo git clone [YOUR_GIT_URL]

$ sudo chown [YOUR_USER_NAME] -R [APP_REPOSITORY]

Set up your app with the following commands.

Write the code which was generated when “rails new” was conducted in “config.master.key”.

$ cd [APP_REPOSITORY]

$ vim config/master.key

$ bundle install — deployment — without development test

$ bundle exec rake db:create RAILS_ENV=production

$ bundle exec rake assets:precompile RAILS_ENV=production

Enhance the security level of the configuration files.

$ chmod 700 config db

$ chmod 600 config/database.yml config/master.key

“Uglifier::Error” occurred?

The following error could happen when “rake assets:precompile” is conducted.

Uglifier::Error: Unexpected token: punc ({). To use ES6 syntax, harmony mode must be enabled with Uglifier.new(:harmony => true)

It can be solved by editting “config/environments/production.rb” as follows.

# config.assets.js_compressor = :uglifier

config.assets.js_compressor = Uglifier.new(harmony: true)

Nginx configuration

Obtain the path of Ruby.

$ passenger-config about ruby-command

passenger-config was invoked through the following Ruby interpreter:

Command: /usr/local/rvm/gems/ruby-2.5.1/wrappers/ruby

Version: ruby 2.5.1p57 (2018–03–29 revision 63029) [x86_64-linux]

To use in Apache: PassengerRuby /usr/local/rvm/gems/ruby-2.5.1/wrappers/ruby

To use in Nginx : passenger_ruby /usr/local/rvm/gems/ruby-2.5.1/wrappers/ruby

To use with Standalone: /usr/local/rvm/gems/ruby-2.5.1/wrappers/ruby /usr/bin/passenger start

The path “/usr/local/rvm/gems/ruby-2.5.1/wrappers/ruby” is used later as [YOUR_RUBY_PATH].

Create an app configuration file.

$ sudo vim /etc/nginx/sites-enabled/[APP_REPOSITORY].conf

Write the settings in the file as follows.

[YOUR_RUBY_PATH] is the Ruby path as mentioned above.

# /etc/nginx/sites-enabled/[APP_REPOSITORY].conf

server {

listen 80;

server_name [YOUR_DOMAIN]; # Tell Nginx and Passenger where your app’s ‘public’ directory is

root /var/www/[APP_REPOSITORY]/public; # Turn on Passenger

passenger_enabled on;

passenger_ruby [YOUR_RUBY_PATH];

}

Re-start Nginx and check if it is working.



$ curl $ sudo service nginx restart$ curl http://[YOUR_DOMAIN

That’s it if the root HTML codes are properly displayed.

Your Rails app is ready to go!

Need to make it HTTPS?

Find out more:

“How to make EC2 + Ubuntu + Nginx + Passenger HTTPS with Let’s Encrypt”

Need to set up Action Cable?

Find out more:

“How to set up Rails 5 Action Cable in production”

Sources