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 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
Log into DigitalOcean and create a “Droplet” (aka a VPS). If this is your first time using DigitalOcean, check out their Droplet QuickStart guide for an introduction to the service.
When creating the Droplet, make sure to choose Ubuntu 20.04, 22.04, or 24.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/www
directory, 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!
Configure tomo
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
Inside the 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
The .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 to specify a value for the DATABASE_URL environment variable. Tomo will store this value on the VPS so that you only have to provide it once. Provide this value when prompted: sqlite3:/var/www/rails-new/shared/production.sqlite3
.
Note that tomo setup
compiles Ruby from source, which will take several minutes.
Run tomo deploy
Once setup
completes, your VPS is ready to go. Deploying is now just a matter of running tomo deploy
:
# Run on your local machine
$ tomo deploy
When the deploy completes, the Rails app will be accessible on port 3000 of your VPS: http://IPADDR:3000
.
Congratulations!