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=productionand provideRAILS_MASTER_KEY(orconfig/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— installlibssl-dev, then retry.An error occurred while installing pg— installlibpq-dev.- Build killed — not enough RAM; add swap or build on a bigger machine.
rbenv: command not foundin 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.