Deploying a Ruby on Rails App on Deployxa: A Complete Guide | Deployxa

Rails is the original full-stack framework, and deploying it on Deployxa is straightforward. Here is the complete zero-config guide for Ruby apps.

← Back to Dispatch Articles
Engineering Log

Deploying a Ruby on Rails App on Deployxa: A Complete Guide

Rails is the original full-stack framework, and deploying it on Deployxa is straightforward. Here is the complete zero-config guide for Ruby apps.

Deploying a Ruby on Rails App on Deployxa

Ruby on Rails is the original full-stack web framework, and it is still a favorite of startups and solo founders for building web apps quickly. It is mature, opinionated, and has a rich ecosystem of gems. But deploying Rails has traditionally required writing a Dockerfile (to install Ruby, install gems, precompile assets, and run the app via Puma), configuring the database, and handling the asset pipeline. Deployxa's zero-config engine eliminates all of that, detecting Rails from your Gemfile and configuring the deployment. Here is how to deploy a Ruby on Rails app on Deployxa.

The direct answer is that Deployxa auto-detects Rails from your Gemfile (which includes rails). It configures the build and start commands: the build command is bundle install && rake assets:precompile, the start command is puma -C config/puma.rb, and the runtime is Ruby 3.3. You do not write a Dockerfile, you do not configure Puma manually, and you do not manage the asset pipeline. The platform handles all of it, just as it does for Laravel and Phoenix apps.

Why Rails Is a Great Choice for Startups

Three reasons explain why Rails is a great choice for startups. First, it is fast to build. Rails's convention-over-configuration approach means you can build a full-stack app in hours, not days. For startups that need to iterate quickly, Rails is hard to beat. Second, it is full-stack. Rails includes everything you need (ORM, routing, views, mailers, jobs, websockets), which means you do not need to assemble a stack from multiple libraries. Third, it has a rich ecosystem. Rails has gems for everything (auth, payments, admin, search), which means you can add features quickly. For more on startup deployment, see our article on why indie hackers are moving their micro-SaaS fleets from AWS to Deployxa.

The Architecture: Rails + Puma + Container

Here is how Deployxa deploys a Rails app.

The Rails container

The ingestion service detects Rails from your Gemfile. It configures the build and start commands:

  • Build command: bundle install && rake assets:precompile
  • Start command: puma -C config/puma.rb
  • Runtime: Ruby 3.3

The Puma configuration

Puma is Rails's default web server, which handles concurrent requests via multiple worker processes and threads. The default configuration (in config/puma.rb) is appropriate for most apps, but you can adjust it based on your container's CPU.

The reverse proxy

Traefik v3 routes traffic from your custom domain to the Rails container, with automatic SSL via Let's Encrypt.

Step-by-Step: Deploying a Rails App

Here is the exact workflow for a typical Cursor-generated Rails app.

Step 1: Create your Rails app

rails new my_app --database=postgresql
cd my_app
bundle install

Step 2: Create a controller

rails generate controller Pages index health
# app/controllers/pages_controller.rb
class PagesController < ApplicationController
  def index
    render json: { message: 'Hello, World!' }
  end

  def health
    render json: { status: 'ok' }
  end
end

Step 3: Configure routes

# config/routes.rb
Rails.application.routes.draw do
  root 'pages#index'
  get '/health', to: 'pages#health'
end

Step 4: Configure database.yml

# config/database.yml
default: &default
  adapter: postgresql
  encoding: unicode
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  url: <%= ENV.fetch("DATABASE_URL") { "postgres://localhost:5432/my_app" } %>

development:
  <<: *default
  database: my_app_development

test:
  <<: *default
  database: my_app_test

production:
  <<: *default

Step 5: Configure puma.rb

# config/puma.rb
max_threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }
min_threads_count = ENV.fetch("RAILS_MIN_THREADS") { max_threads_count }
threads min_threads_count, max_threads_count

port ENV.fetch("PORT") { 3000 }
environment ENV.fetch("RAILS_ENV") { "production" }

pidfile ENV.fetch("PIDFILE") { "tmp/pids/server.pid" }

workers ENV.fetch("WEB_CONCURRENCY") { 2 }

preload_app!

plugin :tmp_restart

Step 6: Push to GitHub

git init
git add .
git commit -m "rails app"
git remote add origin https://github.com/yourname/my_app.git
git push -u origin main

Step 7: Connect to Deployxa

In the Deployxa dashboard, connect your repository. Deployxa auto-detects Rails:

[ingest] Detected Ruby project
[ingest] Framework: rails
[ingest] Runtime: ruby 3.3
[ingest] Build command: bundle install && rake assets:precompile
[ingest] Start command: puma -C config/puma.rb
[ingest] Port: $PORT

Step 8: Configure environment variables

In the Deployxa dashboard, add:

  • DATABASE_URL: your Postgres connection string (e.g., postgres://user:pass@host:5432/myapp)
  • RAILS_MASTER_KEY: your Rails master key (from config/master.key)
  • RAILS_ENV: production
  • RAILS_SERVE_STATIC_FILES: true

The pre-flight scanner will warn you if any are missing. For more on environment variables, see our article on the vibe coder's guide to environment variables.

Step 9: Deploy

Click Deploy. The build installs gems and precompiles assets, the container starts Puma, and your app is live within 60 to 90 seconds.

Step 10: Run database migrations

After the first deployment, run your database migrations:

rails db:migrate RAILS_ENV=production

You can do this via the Deployxa CLI or by including the migration command in the build process.

Step 11: Add a custom domain

Add a custom domain in the Deployxa dashboard. SSL is provisioned automatically.

Step 12: Verify with deployxa doctor

Run deployxa doctor to verify health. The 14-point readiness engine checks SSL, DNS, environment variables, health endpoints, and container status.

Common Pitfalls and Troubleshooting

The first pitfall is the PORT environment variable. Rails apps typically listen on port 3000 by default, but Deployxa assigns a dynamic port via the PORT environment variable. The fix is to set port ENV.fetch("PORT") { 3000 } in config/puma.rb. The second pitfall is the RAILS_MASTER_KEY. Rails uses a master key to decrypt credentials, which needs to be set as an environment variable in production. The fix is to set RAILS_MASTER_KEY to the value from your config/master.key file. The third pitfall is the asset pipeline. Rails needs to precompile assets (CSS, JS, images) for production, which is done during the build. The fix is to ensure rake assets:precompile is in the build command. The fourth pitfall is the database connection pool. Rails's default pool size (5) is appropriate for most apps, but for high-traffic apps, you might need to adjust it. The fix is to set RAILS_MAX_THREADS (which controls the pool size) based on your app's needs. The fifth pitfall is static file serving. In production, Rails does not serve static files by default (it expects a reverse proxy to serve them). The fix is to set RAILS_SERVE_STATIC_FILES=true (which tells Rails to serve static files) or to configure Traefik to serve them.

Performance: Rails vs Laravel vs Phoenix

Rails, Laravel, and Phoenix are three leading full-stack frameworks. Rails (Ruby) is the original, with a mature ecosystem and a strong community. Laravel (PHP) is the most popular (by usage), with a larger ecosystem than Rails. Phoenix (Elixir) is the fastest (via the Erlang VM), with excellent realtime support. For startups that want to build quickly, Rails is a great choice. For teams that prefer PHP, Laravel is a great choice. For teams that need realtime and performance, Phoenix is the best choice. Deployxa supports all three equally, with the AutoRepairService and the zero-config engine handling each framework automatically. For more on framework comparisons, see our articles on deploying Laravel with Octane and deploying Phoenix with Elixir.

Advanced Rails Patterns

Beyond the basics, Rails apps benefit from several advanced patterns. The first is Active Record. Active Record is Rails's ORM, which provides a rich DSL for database queries and migrations. The second is Active Job. Active Job handles background jobs (via Sidekiq, Resque, or other backends), which is useful for email sending, report generation, and other asynchronous tasks. The third is Action Cable. Action Cable handles WebSockets, which is useful for realtime features (chat, notifications, live updates). The fourth is Devise. Devise is a popular auth gem that handles user registration, login, password reset, and more. The fifth is testing. Rails has excellent testing support (via rspec-rails or minitest), which makes it easy to write unit and integration tests. For more on testing, see our article on the testing void. For more on Rails deployment, see our articles on deploying a Spring Boot app and deploying an Express app with PM2.

Conclusion: Rails Without the Configuration

Rails is the original full-stack framework, and deploying it should be as simple as pushing to Git. Deployxa's zero-config engine makes it so: no Dockerfile, no Puma configuration, no asset pipeline management. Stop configuring Puma and start shipping.

Ready to deploy your Rails app? Drag your project to Deployxa Drop for an instant live preview, or install the CLI with npm i -g @deployxa/cli and deploy from your terminal. For more on framework deep-dives, see our articles on deploying a Phoenix app with Elixir and deploying a Spring Boot app. Learn about deploying an Express app with PM2 and deploying a Flask app with Gunicorn in our companion articles. Explore our free developer tools to speed up your workflow.

Ready to deploy with Deployxa?

Deploy your apps globally with automatic SSL and AI diagnostics.

Start Free Now