Ubuntu packages Ruby, but Rails projects usually pin a specific Ruby version in .ruby-version, and you’ll want to upgrade independently of the OS. A version manager — rbenv or mise — installs Ruby per user and switches versions per project.

1. Build dependencies

Ruby is compiled from source by these tools, so install the libraries first:

sudo apt update
sudo apt install -y git curl build-essential libssl-dev libreadline-dev zlib1g-dev \
  libyaml-dev libffi-dev libgdbm-dev libncurses5-dev libdb-dev uuid-dev \
  libpq-dev libsqlite3-dev

libpq-dev is for PostgreSQL’s pg gem; libsqlite3-dev for SQLite. Missing libyaml-dev or libssl-dev produces a Ruby without YAML or OpenSSL support — a common source of confusing errors later.

2a. Install Ruby with rbenv

git clone https://github.com/rbenv/rbenv.git ~/.rbenv
git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build
echo 'eval "$(~/.rbenv/bin/rbenv init - bash)"' >> ~/.bashrc
source ~/.bashrc

rbenv install -l              # latest stable versions
rbenv install 3.3.6
rbenv global 3.3.6
ruby -v

Compiling takes a few minutes (longer on 1–2 vCPU servers). Update ruby-build later with git -C ~/.rbenv/plugins/ruby-build pull to see new versions.

2b. Or with mise

mise manages Ruby, Node, Python and more with one tool — handy because Rails often also needs Node for asset tooling:

curl https://mise.run | sh
echo 'eval "$(~/.local/bin/mise activate bash)"' >> ~/.bashrc
source ~/.bashrc
mise use --global [email protected]
ruby -v

Either tool reads .ruby-version files in projects.

3. Bundler and gem settings

gem install bundler
echo "gem: --no-document" >> ~/.gemrc     # skip docs, faster installs

4. Install Rails and create an app

gem install rails
rails -v
rails new myapp --database=postgresql
cd myapp

Install and prepare PostgreSQL (see PostgreSQL users and databases):

sudo apt install -y postgresql
sudo -u postgres createuser --createdb $USER
bin/rails db:create
bin/rails server -b 127.0.0.1

curl http://127.0.0.1:3000 should return the Rails welcome page.

Rails 7+ apps use import maps or jsbundling by default; if your app uses jsbundling/cssbundling, install Node.js too (see installing Node.js).

5. Production basics

On a production server:

  • Run as a dedicated user (e.g. deploy) with its own rbenv/mise install.
  • Set RAILS_ENV=production and provide RAILS_MASTER_KEY (or config/master.key) for credentials.
  • Install gems without development and test groups:
bundle config set --local deployment true
bundle config set --local without 'development test'
bundle install
bin/rails assets:precompile
bin/rails db:migrate
  • Run the app with Puma behind Nginx, supervised by systemd — see deploying Rails with Puma and Nginx.
  • Background jobs (Sidekiq, Solid Queue, GoodJob) run as separate services.

Kamal: Rails’ own deployment tool

Rails 8 includes Kamal, which deploys Dockerised apps to any server over SSH (with zero-downtime switching via kamal-proxy). If you’re comfortable with Docker, kamal setup and kamal deploy can replace a hand-built server setup — all you need is a VPS with SSH access.

Troubleshooting

  • ruby-build: definition not found — update ruby-build.
  • BUILD FAILED … OpenSSL — install libssl-dev, then retry.
  • An error occurred while installing pg — install libpq-dev.
  • Build killed — not enough RAM; add swap or build on a bigger machine.
  • rbenv: command not found in cron/systemd — use the full shim path (~/.rbenv/shims/ruby) or the absolute Ruby path.

A Rails app with PostgreSQL and a job worker runs comfortably on 2–4 GB of RAM — see our Ubuntu VPS plans.

  • Ruby
  • Rails
  • Ubuntu