Deploying Rails From Scratch
In this tutorial we will use tomo to deploy a sample Rails project to a virtual private server (VPS). These instructions use DigitalOcean as the hosting provider, but any provider that offers an Ubuntu 20.04 or 22.04 LTS VPS should work in a similar way. Here are the steps involved (step 1 is the only part that is DigitalOcean-specific):
- Create an Ubuntu VPS
- Install necessary apt packages
- Set up a deployer user
- Configure tomo
- Run tomo setup
- Run tomo deploy
This is a basic tutorial that skips over DNS, TLS, load balancing, PostgreSQL, etc. If you have suggestions for expanding this guide, consider opening an issue or pull request on GitHub. Thanks for reading!
Create an Ubuntu VPS
When creating the Droplet, make sure to choose Ubuntu 20.04 or 22.04 (LTS) x64:
And use SSH keys for authentication (tomo does not work with password authentication):
And select a Droplet size with at least 1GB RAM, or Ruby may fail to compile:
Once the Droplet is created, confirm that you are able to connect to it (substitute
IPADDR with the IP address provided in the DigitalOcean control panel for the new Droplet):
# Run on your local machine $ ssh -o PasswordAuthentication=no root@IPADDR echo "authenticated as root!" authenticated as root!
You may need to type
yes when prompted to trust the host fingerprint.
Install necessary apt packages
Rails requires certain operating system packages in order to build Ruby and install various gems that have native extensions. Connect to the VPS as root and install the following:
# Run these commands as root on the VPS apt-get -y update apt-get -y install autoconf \ bison \ build-essential \ curl \ git-core \ libdb-dev \ libffi-dev \ libgdbm-dev \ libgdbm6 \ libgmp-dev \ libncurses5-dev \ libreadline6-dev \ libsqlite3-dev \ libssl-dev \ libyaml-dev \ locales \ patch \ pkg-config \ rustc \ uuid-dev \ zlib1g-dev \ tzdata locale-gen en_US.UTF-8
It may take a minute or two for all the packages to install.
Set up a deployer user
Running a Rails app as
root is a security risk; we need to create a non-privileged user for this purpose. Run the following script to create a
deployer user that:
- has access to write to a
/var/wwwdirectory, which is the default location where tomo will deploy our app; and
- can “linger”, i.e. run long-running processes like the puma web server
# Run these commands as root on the VPS adduser --disabled-password deployer < /dev/null mkdir -p /home/deployer/.ssh cp /root/.ssh/authorized_keys /home/deployer/.ssh chown -R deployer:deployer /home/deployer/.ssh chmod 600 /home/deployer/.ssh/authorized_keys mkdir -p /var/www chown deployer:deployer /var/www loginctl enable-linger deployer
For convenience, the
deployer user will accept the same SSH key that you are already using to authenticate when connecting as
root. Test that it works:
# Run on your local machine $ ssh -o PasswordAuthentication=no deployer@IPADDR echo "authenticated as deployer!" authenticated as deployer!
We will be deploying this basic Rails app. It is a standard Rails app generated by
rails new, with the exception that
force_ssl has been set to
false for the production environment. This will allow us to deploy the app without having to set up HTTPS, which is outside the scope of this tutorial.
Clone the repository to get started:
# Run on your local machine $ git clone https://github.com/mattbrictson/rails-new
rails-new directory, install tomo and run
tomo init. This will set up a deploy configuration with a good set of defaults:
# Run on your local machine $ cd rails-new $ gem install tomo Fetching tomo-1.11.0.gem Successfully installed tomo-1.11.0 1 gem installed $ tomo init ✔ Created .tomo/config.rb
.tomo/config.rb configuration is ready right out of the box. All you will need to change is the
host line, and be sure to replace
IPADDR with the IP address of your VPS:
# Modify the 'host' line of .tomo/config.rb host "deployer@IPADDR"
Run tomo setup
Tomo comes with a
setup command that will prepare your VPS for its first deployment. This does things like install Node, Yarn, and Ruby. It also sets up some important environment variables. Just run:
# Run on your local machine $ tomo setup
You will be asked for two environment variables. Tomo will store these values on the VPS so that you only have to provide them once:
- DATABASE_URL is needed to tell Rails how to connect to the database. The basic app we are deploying uses sqlite. Provide this value when prompted:
sqlite3:/var/www/rails-new/shared/production.sqlite3. This will store the database in a shared location so that it doesn’t change from release to release.
- SECRET_KEY_BASE is needed by all Rails apps to securely encrypt session cookies and other important data. Run
ruby -rsecurerandom -e "puts SecureRandom.hex(64)"to generate an appropriate value.
tomo setup compiles Ruby from source, which will take several minutes.
Run tomo deploy
setup completes, your VPS is ready to go. Deploying is now just a matter of running
# Run on your local machine $ tomo deploy
When the deploy completes, the Rails app will be accessible on port 3000 of your VPS: