As in many of my previous articles, although I had done this procedure several times through the years before, I have never documented it until now. I am writing this article with no pretension to make this an innovative tutorial, everything that will be said below, all commands and instructions are already available online in many other articles and documentation, etc. The host providers themselves make these instructions very clear. My main goal in writing this is to register for my future reference, as we often forget commands and spend lots of time "googling" to remember.
That said, deploying a Ruby on Rails application on a VPS involves several steps, including configuring the environment, installing necessary software, and deploying your Rails application. While the process is similar across various VPS providers, in this article I will cover DigitalOcean as it offers a straightforward and user-friendly experience.
For web server options, you can use either Apache or Nginx. However, the chosen option for this article was Nginx, as it is often recommended due to its performance advantages. Nginx handles concurrent connections more efficiently and has a smaller memory footprint compared to Apache, making it a popular choice for serving Rails applications.
Get to work!
Create a DigitalOcean Droplet
- Go to DigitalOcean and log in to your account, if you don't have use, create it for free here;
- Create a Droplet;
- Choose an image. In this article, for a Rails app, the choosen ption as Ubuntu 22.04 LTS;
- Choose a plan based on your app’s requirements - if you are just exploring, the Basic plan should be sufficient;
- Add your SSH key for secure access;
Public key pairs and SSH PEMs are beyond the scope of this article, so I won't extend about it. For more information, refer to DigitalOcean’s SSH key documentation.
Once created, your Droplet will have an IP address. Use SSH to access your Droplet:
ssh root@your_droplet_ip
Set Up the Environment
After accessing your DigitalOcean Droplet, the first step is to ensure your system is up-to-date and ready for your Ruby on Rails application. This involves updating the package list and upgrading existing packages to their latest versions. Remember that keeping the system updated ensures you have the latest security patches and features. Next, we need to install essential packages that will be required by Ruby, Rails, and your database. These include compilers and libraries for building Ruby, handling SSL, and interacting with PostgreSQL.
- Update the System:
sudo apt update
sudo apt upgrade
- Install Essential Packages:
sudo apt install curl gnupg build-essential libssl-dev libreadline-dev zlib1g-dev libsqlite3-dev libpq-dev
These packages allow your Rails application to interact with the database, handle dependencies, and work with encrypted communications, ensuring your application is secure and efficient.
Install Ruby with Rbenv
To manage Ruby versions efficiently, we'll use rbenv, a popular Ruby version management tool. Unlike system-wide installations, rbenv allows you to easily switch between different versions of Ruby without interfering with the default system version. This makes it ideal for managing multiple Ruby projects that may require different versions.
Install rbenv and ruby-build
First, install rbenv and its companion plugin ruby-build, which simplifies the process of installing different Ruby versions. Run the following commands to download and set up these tools:
# Download rbenv
curl -fsSL https://github.com/rbenv/rbenv/archive/refs/tags/v2.8.2.tar.gz | tar -xz -C ~/.rbenv --strip-components=1
# Add rbenv to the shell path
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(rbenv init -)"' >> ~/.bashrc
# Reload shell configuration
source ~/.bashrc
Next, install ruby-build, which is a plugin that provides an easy way to install different Ruby versions:
git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build1
Install Ruby
With rbenv and ruby-build set up, you can now install Ruby. It's good practice to install the latest stable version to ensure your Rails app benefits from the newest features and security updates. For this guide, we'll install Ruby 3.3.3 (adjust the version if a newer one is available):
rbenv install 3.3.3
rbenv global 3.3.3
The rbenv global command sets the default Ruby version for your entire system. You can switch between versions later if needed by using rbenv local in specific directories.
Verify Ruby Installation:
Finally, confirm that Ruby was installed correctly by checking its version:
ruby -v
You should see the version number 3.3.3 (or the version you installed) printed to the terminal, confirming that Ruby is ready for use.
Install and Configure PostgreSQL
PostgreSQL is a powerful, open-source object-relational database system that's highly compatible with Ruby on Rails applications. In this section, we'll install PostgreSQL, create a dedicated user and database for your Rails app, and configure the system to allow password authentication.
Install
First, install PostgreSQL and its additional components:
sudo apt install postgresql postgresql-contrib
Start and Enable PostgreSQL Service
Ensure that PostgreSQL is running and set to start on boot:
sudo systemctl start postgresql
sudo systemctl enable postgresql
Create a PostgreSQL User
PostgreSQL uses "roles" for authentication. We'll create a new role (user) with a password and a new database owned by that user.
sudo -u postgres psql
In the PostgreSQL prompt:
CREATE USER myuser WITH PASSWORD 'mypassword';
Save this user and password securely.
Install Node.js
Node.js is a JavaScript runtime that's essential for Rails applications, particularly for compiling assets like JavaScript and CSS. Rails uses Node.js to handle frontend asset compilation through Webpacker or the asset pipeline. In this section, we'll install Node.js, configure it, and ensure it's properly integrated into your Rails environment.
There are a couple of ways to install Node.js on a server running Ubuntu. The choosen in this article is through the NodeSource repository, which is a popular provider of Node.js binaries and package management tools. This method ensures you’re installing a stable and supported version of Node.js that fits your project’s requirements.
By running the following command, you will be adding this repository to your system:
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt install -y nodejs
This command fetches the latest setup script from NodeSource for version 18.x of Node.js. You can replace 18.x with a different version if needed, such as 16.x for the Node.js 16 LTS version.
After adding the NodeSource repository, the next step is to install Node.js:
sudo apt install -y nodejs
This command installs both Node.js and its package manager npm (Node Package Manager). The -y flag automatically answers "yes" to any prompts during the installation.
Install Rails and Bundler
Once Ruby is installed and configured on your server, the next step is to install Rails and its dependency manager, Bundler.
Bundler
Bundler is a critical tool in the Ruby ecosystem, as it helps manage gem dependencies, ensuring your application runs the correct versions of libraries. It manages Ruby gems (libraries) required by your application. It ensures your project has the right gems installed, in the correct versions. Install with the following command:
gem install bundler
Rails
With Bundler installed, you can now install Rails. This is the framework that will power your web application. Install it by running:
gem install rails
This command installs the latest stable version of Rails. You can specify a particular version if needed by appending the version number. Once Rails is installed, you can verify the installation by checking the version:
rails -v
Deploy Your Rails Application
Now that oour server is set up with Ruby, Rails, PostgreSQL, and other essential components, the next step is to deploy your Rails application to the server. This involves cloning your application’s repository, installing the necessary gems, and configuring your database.
Clone Your Application
The first step is to clone your Rails application repository from your version control system (e.g., GitHub). Navigate to the directory where you want your application to be hosted (typically /var/www for production environments):
cd /var/www
Then, clone your Git repository:
git clone https://github.com/yourusername/yourapp.git
This will download the entire application into the yourapp directory.
Navigate into your application’s directory:
cd yourapp
Install Gems
Once the repository is cloned, you need to install the required Ruby gems listed in the Gemfile of your application. This ensures all necessary libraries and dependencies are available.
Run the following command to install the gems:
bundle install
This command uses Bundler to install the exact versions of the gems your Rails application depends on, as specified in the Gemfile and Gemfile.lock.
Configure Database
Rails uses a configuration file called database.yml to manage connections to your PostgreSQL database. You’ll need to update this file to match the database settings you previously configured in PostgreSQL.
Edit the config/database.yml file:
nano config/database.yml
In this file, update the following fields to match your PostgreSQL setup:
production:
adapter: postgresql
encoding: unicode
database: myapp_production
pool: 5
username: myuser
password: mypassword
host: localhost
Create and Migrate Database
Once your database.yml file is configured, you need to create the actual database in PostgreSQL and run any pending migrations to set up the required tables.
Run the following commands to create the database and apply the migrations:
rails db:create
This command creates the database specified in database.yml.
rails db:migrate
This will apply all the migrations defined in your Rails application, ensuring the database schema is set up as needed.
Set Up Puma
Puma is a highly performant web server designed for concurrent applications like Ruby on Rails. It’s often used in production environments due to its speed, lightweight nature, and ability to handle multiple threads and workers efficiently.
Create the Puma Configuration File
To configure Puma for your Rails application, you need to create a config/puma.rb file. This file will define how many workers and threads Puma should use, as well as which port and environment the server should run in. Create config/puma.rb:
# Puma configuration
workers 2
threads 1, 6
port ENV.fetch("PORT") { 3000 }
environment ENV.fetch("RAILS_ENV") { "development" }
Configuring Puma with multiple workers and threads can improve performance, but tuning these options is beyond the scope of this article.
Start Puma
Once your configuration file is set up, you can start Puma by running the following command:
bundle exec puma -C config/puma.rb
Ensure Puma Persists
To ensure your Rails application stays running after deployment, it’s essential to set up a system service like systemd to manage Puma. This is especially useful when you need the server to automatically restart if it crashes or after rebooting the VPS.
Create a systemd Service File
Create a puma.service file in the /etc/systemd/system/ directory:
[Unit]
Description=Puma HTTP Server for Rails App
After=network.target
[Service]
Type=simple
User=www-data
WorkingDirectory=/var/www/your-app-name
ExecStart=/usr/local/bin/puma RAILS_ENV=production bundle exec puma -C /var/www/your-app-name/config/puma.rb
Restart=always
[Install]
WantedBy=multi-user.target
Make sure to adjust the WorkingDirectory and ExecStart paths to point to your application and Puma binary.
Enable and Start the Puma Service
Once the systemd service file is created, reload the systemd daemon and start the Puma service:
sudo systemctl daemon-reload
sudo systemctl start puma
sudo systemctl enable puma
This ensures that Puma will automatically restart if the server is rebooted or crashes, persisting the application availability in production environments.
Configure Nginx
Nginx is a high-performance web server often used as a reverse proxy to manage traffic and forward requests to Puma or another web server running your Rails application.
Install Nginx
sudo apt install nginx
Configure Nginx
Create a new configuration file for your Rails application in the /etc/nginx/sites-available/ directory. You can name the file after your app, like yourapp:
server {
listen 80;
server_name your_domain_or_ip;
root /var/www/yourapp/public;
location / {
try_files $uri/index.html $uri @app;
}
location @app {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
}
Enable the Nginx Configuration
Create a symbolic link to enable the new configuration file:
sudo ln -s /etc/nginx/sites-available/yourapp /etc/nginx/sites-enabled/
Test Nginx Configuration
Check if the configuration is correct:
sudo nginx -t
Restart Nginx
Once the configuration is verified, restart Nginx to apply the changes:
sudo systemctl restart nginx
This configuration sets Nginx to listen on port 80 and forward requests to Puma running on port 3000. You can adjust the server_name to your domain or IP address. The reverse proxy handles incoming traffic and passes it to the Puma server.
Configure Firewall
Allow Nginx Through Firewall:
sudo ufw allow 'Nginx Full'
Final Checks
Access Your Application: Open a web browser and navigate to your domain or IP address you defined on nignx sites avaiable. You should see your Rails application.
Monitor Logs: Check Nginx and Rails logs for any issues:
tail -f /var/log/nginx/error.log
tail -f /var/www/yourapp/log/production.log
By following these steps, you should have a Ruby on Rails application successfully deployed on a DigitalOcean Droplet with Nginx and Puma.
Deploying a Ruby on Rails application on DigitalOcean with Nginx provides a robust and scalable environment for your web app. By following the steps outlined, you've set up a Droplet, configured your environment, and installed the necessary software to get your Rails app up and running.
Choosing Nginx as your web server offers several advantages, including better handling of concurrent connections and reduced memory usage, which can lead to improved performance for your application. While Apache is a viable option, Nginx’s efficiency and speed make it a preferred choice for many Rails deployments.
With your Rails app now live on DigitalOcean, you can focus on developing and scaling your application while enjoying the benefits of a reliable VPS provider. Don’t forget to monitor your logs and maintain regular updates to ensure optimal performance and security for your application.
Happy deploying!
References: How To Install Ruby on Rails with rbenv on Ubuntu 22.04
Top comments (0)