Skip to main content

Deploy Rails

This guide will help you deploy a Ruby on Rails application to Deployxa.

Overview

Ruby on Rails is a full-stack web framework for building database-backed applications. Deployxa provides optimized deployments for Rails with automatic configuration.

Features:

  • Automatic framework detection
  • Ruby 3.0+ support
  • PostgreSQL and MySQL support
  • Asset pipeline
  • Database migrations
  • Puma web server
  • Automatic HTTPS

Prerequisites

  • A Rails application (version 7 or higher recommended)
  • A GitHub repository with your code
  • A Deployxa account
  • PostgreSQL or MySQL database

Quick Start

1. Create Your Rails App

If you don't have a Rails app yet:

gem install rails
rails new my-rails-app --database=postgresql
cd my-rails-app

2. Configure for Production

Update config/environments/production.rb:

Rails.application.configure do
config.force_ssl = true
config.log_level = :info
config.assets.compile = false
end

Update config/database.yml:

production:
<<: *default
url: <%= ENV['DATABASE_URL'] %>

3. Push to GitHub

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

4. Deploy to Deployxa

  1. Go to Deployxa Dashboard
  2. Click "New Project"
  3. Select your GitHub repository
  4. Deployxa will automatically detect Rails
  5. Click "Deploy"

Your app will be live in under 60 seconds!

Configuration

Detected Settings

Deployxa automatically detects these settings:

SettingValue
FrameworkRails
Build Commandbundle install --without development test
Output Directorypublic
Start Commandbundle exec puma -C config/puma.rb
Port3000

Custom Configuration

If you need to customize settings:

  1. Go to ProjectSettingsBuild
  2. Modify settings as needed
  3. Save changes

Example Custom Settings:

{
"buildCommand": "bundle install --without development test && bundle exec rake assets:precompile",
"outputDirectory": "public",
"startCommand": "bundle exec puma -C config/puma.rb"
}

Environment Variables

Adding Environment Variables

  1. Go to ProjectEnvironment
  2. Click "Add Variable"
  3. Enter key and value
  4. Click "Save"

Required Rails Environment Variables:

RAILS_ENV=production
RAILS_LOG_TO_STDOUT=true
RAILS_SERVE_STATIC_FILES=true
SECRET_KEY_BASE=your-secret-key-base-here

# Database
DATABASE_URL=postgresql://user:pass@host:5432/dbname

# Redis (optional)
REDIS_URL=redis://user:pass@host:6379/0

Generating SECRET_KEY_BASE

Generate a new secret key base:

rails secret

Or use Ruby:

ruby -rsecurerandom -e 'puts SecureRandom.hex(64)'

Database Configuration

Using Managed Database

  1. Go to ProjectSettingsDatabase
  2. Click "Create Database"
  3. Choose database type (PostgreSQL recommended)
  4. Configure database settings
  5. Copy connection details to environment variables

Database Migrations

Run migrations automatically on deployment:

Option 1: Post-Deploy Script

Create a deployment script:

#!/bin/bash
bundle exec rake db:migrate
bundle exec rake assets:precompile

Option 2: Manual Migration

Run migrations via SSH or console:

bundle exec rake db:migrate

Database Seeding

Seed your database after migration:

bundle exec rake db:seed

Asset Pipeline

Precompiling Assets

Compile assets automatically:

bundle exec rake assets:precompile

This command should be run during deployment.

Using Propshaft (Rails 7+)

For modern asset management:

# Gemfile
gem "propshaft"

Using Webpacker / Shakapacker

For advanced asset management:

bundle add webpacker
rails webpacker:install

Build assets:

bundle exec rake assets:precompile

Custom Domains

Adding a Custom Domain

  1. Go to ProjectDomains
  2. Click "Add Domain"
  3. Enter your domain (e.g., example.com)
  4. Configure DNS records
  5. Wait for verification

DNS Configuration

For Apex Domain (example.com):

Type: A
Name: @
Value: 76.76.21.21

For Subdomain (www.example.com):

Type: CNAME
Name: www
Value: cname.deployxa.com

Performance Optimization

Enable Puma Workers

Configure Puma workers based on CPU cores:

# config/puma.rb
workers ENV.fetch("WEB_CONCURRENCY") { 2 }
threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }
threads threads_count, threads_count

Enable Caching

Configure Rails caching:

# config/environments/production.rb
config.action_controller.perform_caching = true
config.cache_store = :memory_store

Database Indexing

Add indexes to frequently queried columns:

# db/migrate/xxxx_add_index_to_users.rb
class AddIndexToUsers < ActiveRecord::Migration[7.0]
def change
add_index :users, :email
end
end

Monitoring

Viewing Logs

  1. Go to ProjectLogs
  2. Select log type:
    • Build Logs: Deployment process
    • Runtime Logs: Application output
    • Error Logs: Application errors

Rails Logging

Configure logging in config/environments/production.rb:

config.log_level = :info
config.log_tags = [ :request_id ]

View logs:

log/production.log

Monitoring Metrics

  1. Go to ProjectAnalytics
  2. View metrics:
    • Request count
    • Response times
    • Error rates
    • Bandwidth usage
    • CPU/RAM usage

Health Checks

Deployxa automatically monitors your application:

  • HTTP health checks every 30 seconds
  • Automatic restart on failure
  • Alerts on consecutive failures

Troubleshooting

500 Internal Server Error

Problem: Application returns 500 error

Solution:

  1. Check runtime logs for errors
  2. Verify environment variables
  3. Check database connection
  4. Ensure SECRET_KEY_BASE is set
  5. Check file permissions

Database Connection Failed

Problem: ActiveRecord::ConnectionNotEstablished

Solution:

  1. Verify DATABASE_URL is correct
  2. Check database host and port
  3. Ensure database exists
  4. Check firewall rules
  5. Verify database user permissions

Migration Failed

Problem: rake db:migrate fails

Solution:

  1. Check database connection
  2. Verify migration files
  3. Check for syntax errors
  4. Run migrations locally first
  5. Check database permissions

Assets Not Loading

Problem: CSS/JS files return 404

Solution:

  1. Run rake assets:precompile
  2. Check public/assets directory exists
  3. Verify asset paths are correct
  4. Check file permissions

Memory Errors

Problem: Killed or out of memory

Solution:

  1. Reduce Puma workers
  2. Optimize application code
  3. Upgrade plan for more RAM
  4. Use background jobs for heavy tasks

Best Practices

Project Structure

my-rails-app/
├── app/
│ ├── controllers/
│ ├── models/
│ ├── views/
│ └── assets/
├── config/
│ ├── environments/
│ ├── initializers/
│ └── database.yml
├── db/
│ ├── migrate/
│ └── schema.rb
├── public/
├── log/
├── Gemfile
├── Gemfile.lock
├── Rakefile
└── README.md

Environment Variables

  • Never commit .env file
  • Use .env.example as template
  • Rotate secrets regularly
  • Use different values per environment

Security

  • Keep Rails updated
  • Use HTTPS only
  • Validate all inputs
  • Use CSRF protection
  • Sanitize user data
  • Use parameterized queries

Performance

  • Use Puma with multiple workers
  • Enable caching
  • Optimize database queries
  • Use background jobs
  • Use CDN for static assets
  • Enable compression

Database

  • Use migrations for schema changes
  • Index frequently queried columns
  • Use transactions for complex operations
  • Backup database regularly
  • Use connection pooling

Advanced Configuration

Custom Puma Configuration

# 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

worker_timeout 3600 if ENV.fetch("RAILS_ENV", "development") == "development"

port ENV.fetch("PORT") { 3000 }

environment ENV.fetch("RAILS_ENV") { "development" }

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

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

preload_app!

plugin :tmp_restart

Background Jobs with Sidekiq

For background jobs:

# Gemfile
gem "sidekiq"
# config/initializers/sidekiq.rb
Sidekiq.configure_server do |config|
config.redis = { url: ENV.fetch("REDIS_URL") { "redis://localhost:6379/0" } }
end

Sidekiq.configure_client do |config|
config.redis = { url: ENV.fetch("REDIS_URL") { "redis://localhost:6379/0" } }
end

Active Storage

For file uploads:

# config/storage.yml
amazon:
service: S3
access_key_id: <%= ENV['AWS_ACCESS_KEY_ID'] %>
secret_access_key: <%= ENV['AWS_SECRET_ACCESS_KEY'] %>
region: <%= ENV['AWS_REGION'] %>
bucket: <%= ENV['AWS_BUCKET'] %>

Examples

Basic Rails App

# app/controllers/welcome_controller.rb
class WelcomeController < ApplicationController
def index
render plain: "Hello, Deployxa!"
end
end
# config/routes.rb
Rails.application.routes.draw do
root "welcome#index"
end

With Database Model

# app/models/user.rb
class User < ApplicationRecord
validates :name, presence: true
validates :email, presence: true, uniqueness: true
end
# app/controllers/users_controller.rb
class UsersController < ApplicationController
def index
@users = User.all
render json: @users
end

def create
@user = User.new(user_params)
if @user.save
render json: @user, status: :created
else
render json: @user.errors, status: :unprocessable_entity
end
end

private

def user_params
params.require(:user).permit(:name, :email)
end
end

API Endpoint

# app/controllers/api/v1/users_controller.rb
module Api
module V1
class UsersController < ApplicationController
def index
render json: User.all
end
end
end
end
# config/routes.rb
Rails.application.routes.draw do
namespace :api do
namespace :v1 do
resources :users, only: [:index, :show, :create]
end
end
end

Resources


Need Help? Contact support@deployxa.com or join our community Discord.