How to Install and Configure Ruby With Rbenv, Rails, MariaDB, Nginx, SSL and Passenger on Ubuntu 20.04
Introduction
Nginx is a free, open-source, high-performance HTTP server. Ruby is a dynamic, open-source programming language that prioritizes simplicity and productivity. It features an easy syntax that is natural to read and write. Ruby on Rails is a widely used web framework for Ruby that was created to help software developers be more productive. However, getting a large number of gems and dependencies to work together might be difficult at times. This article teaches you how to set up a Rails environment with Passenger and Nginx, including popular gems and dependencies.
Phusion Passenger is a free, open-source web application server. It is designed to handle HTTP requests, monitor and manage processes and resources, as well as allow administration, monitoring, and problem diagnosis. In this article, you will set up Passenger to assist Nginx with serving your web application. Ruby is one of the languages that Passenger supports. You will be using Passenger because it offers multiple benefits, such as that it can run multiple applications at once (it's multitenant).
This article teaches you how to set up a web application with the following stacks:
- Nginx: a fast and popular web server.
- Ruby: the popular web framework.
- Passenger: an application server that assists Nginx in serving your Ruby application.
- Rbenv: a Ruby version manager.
- MariaDB: an open-source fork of the MySQL server.
- HTTPS configuration using a free SSL certificate from Let's Encrypt.
Prerequisites
- Deploy an Ubuntu 20.04 LTS cloud server at Vultr with at least 2 GB of RAM.
- Update the server.
- Create a non-root user with sudo privileges.
- Log in to your server as the non-root user.
- Create a DNS "A" record and point it to your server.
1. Install Rbenv and Dependencies
Install the Ruby dependencies.
$ sudo apt -y install git curl libssl-dev libreadline-dev zlib1g-dev autoconf bison build-essential libyaml-dev libreadline-dev libncurses5-dev libffi-dev libgdbm-dev libcurl4-openssl-dev
Download the Ruby installation script from GitHub with the
curl
utility into a file named.rbenv
and run the script.$ curl -fsSL https://github.com/rbenv/rbenv-installer/raw/HEAD/bin/rbenv-installer | bash
The
.bashrc
file contains a list of commands that are executed each time a user logs in to a new terminal session. Use the next command to create a new entry in the file. The new entry is a command that appends the location of your Rbenv command-line utility to the$PATH
environment variable. This entry in the.bashrc
file allows you to use Rbenv each time you log in to a new terminal session.$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
Create a second entry in the
.bashrc
file. This entry loads Rbenv automatically each time you log in to a new terminal session.$ echo 'eval "$(rbenv init -)"' >> ~/.bashrc
Apply the modifications you've made to your
~/.bashrc
file to your current terminal session.$ source ~/.bashrc
Verify that Rbenv is installed successfully.
$ type rbenv
Install the ruby-build plugin. The plugin adds the
rbenv install
command, making installing new versions of Ruby easier. Next, download and clone the ruby-build GitHub repository into a 'ruby-build' directory.$ git clone https://github.com/rbenv/ruby-build.git
Create a new temporary environment variable required to install the plugin and run the installation script.
$ PREFIX=/usr/local sudo ./ruby-build/install.sh
2. Install Ruby with ruby-build
Use the next command to install Ruby. The command automatically retrieves the latest Ruby version and installs it.
$ rbenv install $(rbenv install -l | grep -v - | tail -1)
Set the installed Ruby version as global.
$ rbenv global $(rbenv install -l | grep -v - | tail -1)
3. Install Ruby on Rails
Install Ruby on Rails with the gem command.
$ gem install rails
4. Install Maria DB
Install the Maria DB package using the APT package manager.
$ sudo apt -y install mariadb-server
The command above has installed Maria DB with the default configuration. Because the default configuration of Maria DB is insecure, use a script that the
mariadb-server
package provides to restrict access to the server and delete unused database accounts.$ sudo mysql_secure_installation
The script asks you several configuration questions. Answer them as follows:
- Enter current password for root - press Enter to continue without a password because you haven't set a password yet.
- Switch to unix_socket authentication ? - Type
N
to answer no and press Enter. - Set root password? - Type
Y
and press Enter. Input a password for the Maria DB root account twice. - Change the root password? - You need to change the default root password for security reasons. Type
Y
to answer yes and press Enter. Input a new password for the Maria DB root account twice. - Remove anonymous users? - Type
Y
to answer with the yes option and press Enter. You should go with the yes option because anonymous accounts are insecure and only for testing purposes. - Disallow root login remotely? - If you plan to access Maria DB from outside of the server you are installing it on, type
N
to answer no and press Enter. Otherwise, or if you're unsure which option to go with, typeY
to answer yes and press Enter. - Remove test database and access to it? - You do not need the test database, so type
Y
and press Enter. - Reload privilege tables now? - You need to reload the privilege tables to save the changes. Type
Y
and press Enter.
Open a new MariaDB shell under the root account.
$ sudo mysql -u root
Create a new MariaDB user with root privileges. The user's name must match your Ubuntu's non-root account username. Use the next command and replace
exampleuser
with your non-root account username. The names must match for socket authentication to work.MariaDB [(none)]> GRANT ALL PRIVILEGES ON *.* TO 'exampleuser'@'localhost' IDENTIFIED VIA unix_socket;
Exit the MariaDB shell.
MariaDB [(none)]> exit;
5. Install Passenger with Nginx
Install Nginx using the APT package manager.
$ sudo apt -y install nginx
Install the necessary cryptographic packages and add the Passenger PGP key.
$ sudo apt install -y dirmngr gnupg $ sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 561F9B9CAC40B2F7
Install the packages that are required for APT to use HTTPS.
$ sudo apt install -y apt-transport-https ca-certificates
Add the Passenger APT repository.
$ sudo sh -c 'echo deb https://oss-binaries.phusionpassenger.com/apt/passenger focal main > /etc/apt/sources.list.d/passenger.list'
Update the package lists.
$ sudo apt update
Install Passenger and the Nginx module using APT.
$ sudo apt install -y libnginx-mod-http-passenger
Restart Nginx to enable the installed module.
$ sudo service nginx restart
Validate the Passenger installation. You are prompted to select what you would like to validate. Press key Enter to go with the default option Passenger Itself. If you've completed the steps above without an error, the tool should complete the validation successfully.
$ sudo /usr/bin/passenger-config validate-install
6. Create a new Rails Application
Install the dependencies required to create a new Rails application.
$ sudo apt -y install sqlite3 libsqlite3-dev nodejs npm libmariadb-dev
Install Yarn, a dependency for Rails applications using the Node Package Manager.
$ sudo npm install yarn --global
Navigate to the
/var/www
directory. Nginx stores web applications in this directory.$ cd /var/www
Change the owner of the
/var/www
directory to your non-root user account. Use the next command and replaceexampleuser
with the name of your non-root user account.$ sudo chown -R exampleuser:exampleuser /var/www
Create a new Rails application inside the
/var/www
directory. Replaceexample
in the next command with your desired application name.$ rails new example --database mysql
Navigate to the newly created application's directory. Use the next command with your Rails application's name.
$ cd example
Edit the database configuration file.
$ nano config/database.yml
Find the
username
setting and set it to the username of your non-root user account.Save and exit the file.
Initialize the Rails database.
$ rake db:create
Restart the Rails application.
$ rails restart
7. Configure Passenger with Rbenv
Edit the Passenger configuration file in your favorite text editor.
$ sudo nano /etc/nginx/conf.d/mod-http-passenger.conf
Delete or comment out lines starting with
passenger_root
andpassenger_ruby
.Append the following lines into the file. Replace
example_user
in thepassenger_ruby
option path with the username of your non-root account.passenger_ruby /home/example_user/.rbenv/shims/ruby; passenger_root /usr/lib/ruby/vendor_ruby/phusion_passenger/locations.ini;
Save and exit the file.
8. Configure Nginx to use Ruby
Disable the default Nginx virtual host.
$ sudo rm /etc/nginx/sites-enabled/default
Edit a new virtual host file in your favorite text editor.
$ sudo nano /etc/nginx/sites-enabled/ruby-app.conf
Populate the file with the following contents. Replace
192.0.2.2
with the IP address of your server, and replaceexample
with the name of your Ruby application in the/var/www/example/public
path.server { listen 80; server_name 192.0.2.2; root /var/www/example/public; passenger_enabled on; # When you are ready to switch to production mode - change this to `production` passenger_app_env development; # <-- !important }
Restart the Nginx web server.
$ sudo service nginx restart
Configure the UFW firewall to allow traffic to the port 80. Your application is running on this port.
$ sudo ufw allow 80
Visit the IP address of your server in a web browser. The Rails welcome page shows up.
Your application is ready to be used in development mode.
9. Setup SSL
There are several SSL certificates providers for your domain, with some being paid and others being free. You should set up SSL no matter which provider you use. Let's Encrypt was established as a non-profit organization to provide free and automated encryption. Many technology firms have given their support to Let's Encrypt.
Install Certbot (the Let's Encrypt client) and the Certbot Nginx plugin using the APT package manager.
$ sudo apt -y install certbot python3-certbot-nginx
Edit your Ruby application's Nginx virtual host file.
$ sudo nano /etc/nginx/sites-enabled/ruby-app.conf
Change the
server_name
setting to your domain name.Save and exit the file.
Set up the SSL certificate. Replace
example.com
with your domain name andyouremail@example.com
with your email address.$ sudo certbot --nginx -d example.com --non-interactive --redirect --agree-tos -m youremail@example.com
Configure the UFW firewall to allow traffic to your HTTPS port 443.
$ sudo ufw allow 443
Navigate to your Ruby application's directory. Replace
example
with the name of your Ruby application.$ cd /var/www/example
Edit the development environment configuration file.
$ nano config/environments/development.rb
The last line of the file has the text
end
in it. Append the following before the line with the textend
. Replaceexample.com
with your domain name.config.hosts << "example.com"
Save and exit the file.
Restart your Rails application.
$ rails restart
Visit your domain name in a web browser. The Ruby on Rails welcome page shows up. The connection is now secured by HTTPS.
10. Configure Lets Encrypt to Renew the Certificate Automatically
Your newly issued certificate has an expiration date for security reasons. After this expiration date, the certificate becomes invalid. Let's Encrypt certificates are valid for 90 days after their issue date.
Cron is a Linux utility that allows users to schedule the execution of commands, scripts, and programs at specified intervals.
You may set up Cron to run the Lets Encrypt Certificate renewal command every day at 2:00 a.m. Your certificate will not be renewed every single day, as it is not a good practice. Instead, it will be renewed 30 days before the expiry date ( after 60 days of validity ).
Use the next command to edit the Cron schedule file. You are asked to select a text editor. Press Enter to go with the default option.
$ sudo crontab -e
Append the following to the end of the file.
0 2 * * * /usr/bin/certbot renew
Save and exit the file.
11. Switch to Production Mode
You should switch your Rails environment to the production mode in live applications because it's safer, faster, and more reliable than the development mode. Because the development mode was created to make the development process easier, it is not intended for use in real-world applications.
You should take into consideration that exposing your application for real production usage is not only about switching the Rails environment. If you're preparing to deploy your application for production use, you should understand what you're doing and take the necessary security measures to avoid further security risks. The security measures you should take depend on the type and details of your application.
The process of securing your application is named hardening. This article is not about and does not include hardening your application. Before exposing your application to the internet for production usage, you need to harden it. You may find hardening articles on the internet. Please, harden your application before deploying it into production to eliminate security risks.
You may switch the Rails environment to production mode as follows. Please remember to take the necessary security precautions mentioned above before deploying your application to production mode.
Edit the Nginx virtual host configuration file for your Rails application.
$ sudo nano /etc/nginx/sites-enabled/ruby-app.conf
Change the
rails_env
setting to the value production.Save and exit the file.
Restart the Nginx service to apply the changes.
$ sudo service nginx restart
You have now switched the Rails application to production mode.
Conclusion
In this article, you have learned how to install and configure Ruby With Rbenv, Rails, MariaDB, Nginx, SSL, and Passenger on Ubuntu 20.04. You have also learned how to switch the Rails environment to production mode.