Setup Rails with nginx + Passenger

Setup Rails with nginx + Passenger

In my previous posts, I had set up Ruby on Rails running with Puma and SQLite. This is a very fast installation of the environment with minimal configuration but it is not meant for production use.

After that, I installed PostgreSQL and configure Rails with PostgreSQL. Now in this post, I’ll be installing nginx with Passenger and configure Rails with it.

These installations are done in AWS EC2 t3.nano. The operating system used is Ubuntu 18.04 with additional 1GB of swap memory.

Install packages

Installing nginx if you do not already have nginx in your Ubuntu and all the required packages for nginx and Passenger.

# Install nginx
sudo apt update
sudo apt install nginx -y

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

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

# Install Passenger and nginx module
sudo apt install libnginx-mod-http-passenger -y

Setup configuration file

Setting up the nginx configuration file. The ls command should yield a file named mod-http-passenger.conf. If it it doesn’t you will encounter errors restarting your nginx service.

# Setup configuration file 
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 
sudo service nginx restart

Setup virtual host

We will be creating a configuration file to host our rails app in the “sites-available” folder and later enabling it by creating a soft link in “sites-enabled” folder.

# Create the rails app file in sites-available directory
sudo vim /etc/nginx/sites-available/blog

Paste the content below into the file.

server {
  listen 80;
  server_name rails.oofnivek.com;
  passenger_ruby /home/ubuntu/.rbenv/versions/2.5.1/bin/ruby;
  passenger_enabled on;
  passenger_app_env development;
  root /home/ubuntu/ror/blog/public;
}

Replace the server_name value with your domain. Since we are migrating from Puma web server to nginx + Passenger, I left the passenger_app_env set to “development” for testing. Your passenger_ruby value might vary from mine. To find out yours in your environment, run this command.

passenger-config --ruby-command
setup rails with nginx passenger
My passenger_ruby value in my environment.

Enable the site

Enabling your rails site in nginx to test if your migration from Puma to nginx is successful.

sudo ln -s /etc/nginx/sites-available/blog /etc/nginx/sites-enabled/blog
sudo service nginx restart
setup rails with nginx passenger
Successful migration from Puma to nginx + Passenger.

Production mode

To switch it to production mode, replace the value of passenger_app_env from development to production.

You can hardcode your database password in your rails database.yml file if you prefer to skip a few steps and also avoiding rebooting your server.

# Modify app environment to production
sudo sed -i 's/passenger_app_env development/passenger_app_env production/' /etc/nginx/sites-available/blog

# My PostgreSQL blog role is using 'password1' as password
echo "export BLOG_DATABASE_PASSWORD='password1'" >> ~/.bashrc
source ~/.bashrc

# Have to reboot server in order to refresh this value
echo "export BLOG_DATABASE_PASSWORD='password1'" >> ~/.profile

After configuring the production database connection, we create the database and migrate the tables.

# Create blog_production database 
cd ~/ror/blog/ 
RAILS_ENV=production rails db:create 
RAILS_ENV=production rails db:migrate 

# Configure default route 
vim ~/ror/blog/config/routes.rb

Add the line to default root to posts index route like my example below.

Rails.application.routes.draw do
  resources :posts
  root 'posts#index'
end

Finally, speed up your rails by precompiling it and reboot your Ubuntu so that the saved database password in the environment variable will take effect.

# Speed up your rails by precompiling assets
rails secret > ~/ror/blog/config/secrets.yml
cd ~/ror/blog
RAILS_ENV=production rails assets:precompile

# Finally reboot the server to refresh the environment variable
sudo reboot now

That’s all, once rebooted your site will be up and running in production mode.

Setup Rails with PostgreSQL

Setup Rails with PostgreSQL

In my previous Ubuntu install Rails post, I had installed Ruby on Rails environment in Ubuntu 18.04 but utilizing SQLite. Now I am trying to connect Ruby on Rails to PostgreSQL. To install PostgreSQL, refer to my Ubuntu install PostgreSQL post.

Firstly, we need to install PostgreSQL gem and log in as postgres user.

gem install pg
sudo su - postgres
psql

Create a role

From within PostgreSQL, run the command below to create a new role. The du command to check the newly created role and q to quit the PostgreSQL prompt. Lastly exit the postgres user back to ubuntu user.

create role blog with createdb login password 'password1';
\du
\q
exit

Create a project

Now we will create a project called “blog” and have it connect to the PostgreSQL database. Let’s reuse the same project folder structure from my previous Ubuntu install Rails post.

cd ~/ror
rails new blog --database=postgresql
cd blog
vim config/database.yml
setup rails with postgresql
Your configuration should look similar to this.

Setup a new database

Run the command below after successfully configure your database.yml file.

rake db:setup
setup rails with postgresql
You should be seeing similar result upon successful setup.

Create CRUD scaffold

Create a scaffold with CRUD (create, read, update, delete) to see if you are able to store into the PostgreSQL database.

rails g scaffold Post title:string body:text
rake db:migrate
rails server
setup rails with postgresql
The index page of all the posts.
setup rails with postgresql
Creating a new post.
setup rails with postgresql
Successfully created a new post.
setup rails with postgresql
Index page showing the new post.

Verification

setup rails with postgresql
Successfully querying PostgreSQL using pgAdmin to verify the post created.

 

 

Ubuntu install Rails

Ubuntu install Rails

This installation is done at AWS EC2 t3.nano running Ubuntu 18.04. Although t3.nano is better than t2.nano, it is still having 0.5G of RAM only. I suggest adding 1G of swap memory to it.

Install Node.js and npm

As always, prior to installation, do an update first. Copy the command below to update and install Node.js and npm. Last command shows the version of Node.js after installation.

sudo apt update
sudo apt install nodejs npm -y
nodejs -v

Install SQLite

To install SQLite, use the command below.

sudo apt install sqlite3 libsqlite3-dev -y

Install rbenv and dependencies

The commands below will install the dependencies and pull rbenv codes from GitHub. After that sets the environment variables and reloads the environment variables. Lastly, check if rbenv was configured correctly.

sudo apt install autoconf bison build-essential libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libncurses5-dev libffi-dev libgdbm5 libgdbm-dev -y
git clone https://github.com/rbenv/rbenv.git ~/.rbenv
git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(rbenv init -)"' >> ~/.bashrc
source ~/.bashrc
type rbenv
ubuntu install ruby on rails
If everything went smoothly, you should see a similar output like this.

Install Ruby

To see the list of all available versions, use “-l”. At the time of this post, 2.5.1 is the stable release of Ruby. The installation is pretty slow with no progress bar, so don’t be alarmed if the screen isn’t moving.

rbenv install -l
rbenv install 2.5.1

Once completed, set the default Ruby version.

rbenv global 2.5.1
ruby -v
ubuntu install ruby on rails
The last command shows the Ruby version installed.

Installing Rails

The “–no-document” setting turn of the local documentation during the gem installation. This is to speed up the installation process.

echo "gem: --no-document" > ~/.gemrc
gem install bundler
gem install rails
rbenv rehash
rails -v
ubuntu install ruby on rails
At the end of a successful installation of Rails.

Create an application

Create an empty application to test if you had successfully setup your Ruby on Rails. This setup is for development use only, not for production use.

cd ~
mkdir ror
cd ror
rails new hello_world
cd hello_world
rails server
ubuntu install ruby on rails
After successful creation of empty application and getting the development web server started.

Please refer to my configure security group blog post if you are unsure of how to allow inbound traffic for port 3000.

ubuntu install ruby on rails
Sample screenshot of a successful setup.