Deploying Ruby Applications
This comprehensive guide covers everything you need to know about deploying Ruby applications with Flux-Orbit, from simple Sinatra apps to full Rails applications.
Overview
Flux-Orbit automatically detects Ruby applications by looking for:
Gemfile(primary indicator)Gemfile.lockfor dependency resolution.ruby-versionfor version specification (optional)config.rufor Rack applications
Basic Ruby Deployment
Simple Sinatra API
docker run -d \
--name sinatra-api \
-e GIT_REPO_URL=https://github.com/your-username/sinatra-api \
-e APP_PORT=4567 \
-p 4567:4567 \
runonflux/orbit:latest
What Happens Automatically
- Detection: Finds
Gemfileand identifies as Ruby project - Version Selection:
- Checks
RUBY_VERSIONenvironment variable - Checks
.ruby-versionfile - Checks
rubydirective in Gemfile (e.g.,ruby '3.2.0') - Falls back to Ruby 3.0.0
- Checks
- Runtime Installation:
- Downloads and installs Ruby via rbenv
- Installs to
/opt/flux-tools/rbenv - Configures PATH and gem environment
- Dependencies: Runs
bundle install --deployment --without development test - Build: Precompiles assets if Rails app detected
- Start: Executes appropriate server command (rails, rackup, ruby, etc.)
Framework-Specific Guides
Ruby on Rails
Rails is a full-stack web framework for Ruby. Flux-Orbit automatically detects and optimizes Rails applications:
docker run -d \
--name rails-app \
-e GIT_REPO_URL=https://github.com/your-username/rails-app \
-e APP_PORT=3000 \
-e RUBY_VERSION=3.2.0 \
-e RAILS_ENV=production \
-p 3000:3000 \
runonflux/orbit:latest
Example config/puma.rb (recommended):
# Puma configuration for production
workers ENV.fetch("WEB_CONCURRENCY") { 2 }
threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }
threads threads_count, threads_count
preload_app!
port ENV.fetch("PORT") { 3000 }
environment ENV.fetch("RAILS_ENV") { "production" }
on_worker_boot do
ActiveRecord::Base.establish_connection if defined?(ActiveRecord)
end
# Bind to 0.0.0.0 for container networking
bind "tcp://0.0.0.0:#{ENV.fetch('PORT') { 3000 }}"
Important Rails Configuration:
- Asset Precompilation: Automatically runs
rails assets:precompile - Database Migrations: Use deployment hooks (see below)
- Secret Key: Set
SECRET_KEY_BASEenvironment variable
Sinatra Framework
Sinatra is a lightweight DSL for creating web applications:
docker run -d \
--name sinatra-api \
-e GIT_REPO_URL=https://github.com/your-username/sinatra-api \
-e APP_PORT=4567 \
-p 4567:4567 \
runonflux/orbit:latest
Example app.rb:
require 'sinatra'
require 'json'
set :bind, '0.0.0.0'
set :port, ENV['APP_PORT'] || 4567
get '/health' do
content_type :json
{ status: 'healthy' }.to_json
end
get '/' do
'Hello from Sinatra on Flux!'
end
Example config.ru:
require './app'
run Sinatra::Application
Hanami Framework
Hanami is a modern web framework for Ruby:
docker run -d \
--name hanami-app \
-e GIT_REPO_URL=https://github.com/your-username/hanami-app \
-e APP_PORT=2300 \
-p 2300:2300 \
runonflux/orbit:latest
Rack Applications
For custom Rack applications with config.ru:
docker run -d \
--name rack-app \
-e GIT_REPO_URL=https://github.com/your-username/rack-app \
-e APP_PORT=9292 \
-p 9292:9292 \
runonflux/orbit:latest
Version Management
Specify Ruby Version
Option 1: Environment Variable
docker run -d \
-e GIT_REPO_URL=https://github.com/your-username/ruby-app \
-e APP_PORT=3000 \
-e RUBY_VERSION=3.2.0 \
-p 3000:3000 \
runonflux/orbit:latest
Option 2: .ruby-version File
3.2.0
Option 3: Gemfile
source 'https://rubygems.org'
ruby '3.2.0'
gem 'rails', '~> 7.0'
gem 'puma', '~> 6.0'
Build Configuration
Asset Precompilation (Rails)
Rails assets are automatically precompiled in production mode:
docker run -d \
-e GIT_REPO_URL=https://github.com/your-username/rails-app \
-e APP_PORT=3000 \
-e RAILS_ENV=production \
-e SECRET_KEY_BASE=your-secret-key \
-p 3000:3000 \
runonflux/orbit:latest
Custom Build Command
Override the default build command if needed:
docker run -d \
-e GIT_REPO_URL=https://github.com/your-username/ruby-app \
-e APP_PORT=3000 \
-e BUILD_COMMAND="bundle exec rake custom:build" \
-p 3000:3000 \
runonflux/orbit:latest
Custom Run Command
Override the default run command:
docker run -d \
-e GIT_REPO_URL=https://github.com/your-username/rails-app \
-e APP_PORT=3000 \
-e RUN_COMMAND="bundle exec puma -C config/puma.rb" \
-p 3000:3000 \
runonflux/orbit:latest
Environment Variables
Ruby-Specific Variables
| Variable | Description | Default |
|---|---|---|
RUBY_VERSION | Ruby version to install | Auto-detected from Gemfile |
RAILS_ENV | Rails environment | production |
RACK_ENV | Rack environment | production |
BUNDLE_WITHOUT | Bundle groups to exclude | development test |
Rails Application Variables
docker run -d \
--name rails-app \
-e GIT_REPO_URL=https://github.com/your-username/rails-app \
-e APP_PORT=3000 \
-e RUBY_VERSION=3.2.0 \
-e RAILS_ENV=production \
-e SECRET_KEY_BASE=your-very-long-secret-key \
-e DATABASE_URL=postgresql://user:pass@db:5432/mydb \
-e REDIS_URL=redis://redis:6379/0 \
-e RAILS_LOG_TO_STDOUT=true \
-e RAILS_SERVE_STATIC_FILES=true \
-p 3000:3000 \
runonflux/orbit:latest
Advanced Scenarios
Monorepo - Deploy Specific Service
docker run -d \
--name rails-admin \
-e GIT_REPO_URL=https://github.com/your-username/monorepo \
-e PROJECT_PATH=apps/admin \
-e APP_PORT=3000 \
-p 3000:3000 \
runonflux/orbit:latest
Private Repository
docker run -d \
--name private-rails-app \
-e GIT_REPO_URL=https://github.com/your-username/private-app \
-e GIT_TOKEN=ghp_your_personal_access_token \
-e APP_PORT=3000 \
-p 3000:3000 \
runonflux/orbit:latest
With Database Migrations
Create pre-deploy.sh in your repository root:
#!/bin/bash
# Run database migrations before deployment
echo "Running database migrations..."
bundle exec rails db:migrate RAILS_ENV=production
Create post-deploy.sh:
#!/bin/bash
# Clear cache after deployment
echo "Clearing Rails cache..."
bundle exec rails cache:clear RAILS_ENV=production
docker run -d \
--name rails-app-with-migrations \
-e GIT_REPO_URL=https://github.com/your-username/rails-app \
-e APP_PORT=3000 \
-e DATABASE_URL=postgresql://user:pass@db:5432/mydb \
-p 3000:3000 \
runonflux/orbit:latest
Learn more: Deployment Hooks Guide
CI/CD Integration
Automatic Deployment with Webhooks
docker run -d \
--name rails-app \
-e GIT_REPO_URL=https://github.com/your-username/rails-app \
-e APP_PORT=3000 \
-e API_KEY=your-secret-api-key \
-p 3000:3000 \
-p 9001:9001 \
runonflux/orbit:latest
Configure GitHub Webhook:
- Payload URL:
https://your-app-9001.app.runonflux.io/webhook - Content type:
application/json - Secret: Not needed (use X-API-Key header instead)
- Events: Just the
pushevent
Add API Key Header:
Use X-API-Key: your-secret-api-key in your webhook configuration.
Polling for Updates
docker run -d \
--name rails-app \
-e GIT_REPO_URL=https://github.com/your-username/rails-app \
-e APP_PORT=3000 \
-e POLLING_INTERVAL=300 \
-p 3000:3000 \
runonflux/orbit:latest
Troubleshooting
Asset Compilation Fails
Problem: "Asset precompilation failed"
Solution: Ensure Node.js is available for JavaScript runtime (automatically installed if detected):
# Gemfile
gem 'mini_racer' # Or 'therubyracer'
Or explicitly set Node.js version:
-e NODE_VERSION=20
Bundle Install Fails
Problem: Native extension build errors
Solution: Flux-Orbit includes build-essential and common libraries. For additional dependencies, use deployment hooks:
#!/bin/bash
# pre-deploy.sh
apt-get update && apt-get install -y libspecial-dev
Server Not Binding to Port
Problem: Application not accessible
Solution: Ensure your server binds to 0.0.0.0 (not localhost):
# Puma config
bind "tcp://0.0.0.0:#{ENV.fetch('PORT') { 3000 }}"
# Sinatra
set :bind, '0.0.0.0'
# Rackup
# Use 'rackup -o 0.0.0.0 -p $PORT'
Database Connection Issues
Problem: Can't connect to database
Solution: Use DATABASE_URL environment variable:
-e DATABASE_URL=postgresql://user:pass@host:5432/dbname
And in config/database.yml:
production:
url: <%= ENV['DATABASE_URL'] %>
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
Secret Key Base Missing
Problem: Rails requires SECRET_KEY_BASE in production
Solution: Generate and set secret key:
# Generate a secret key locally
rails secret
# Use it in deployment
-e SECRET_KEY_BASE=the-generated-secret-key
Memory Issues During Asset Compilation
Problem: Out of memory during rails assets:precompile
Solution: Increase Node.js heap size:
-e NODE_OPTIONS="--max-old-space-size=2048"
Performance Tips
-
Use Puma: Configure workers and threads appropriately
workers ENV.fetch("WEB_CONCURRENCY") { 2 }
threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }
threads threads_count, threads_count -
Preload App: Enable
preload_app!in Puma config for faster worker spawning -
Database Connection Pooling: Match pool size to thread count
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> -
Dependency Caching: Dependencies are cached based on Gemfile.lock hash - no reinstall if unchanged
-
Asset Pipeline: Use Sprockets or Webpacker efficiently, enable CDN for assets in production
-
Health Checks: Implement
/healthendpoint for faster deployment verification# config/routes.rb
get '/health', to: proc { [200, {}, ['OK']] }
Example Repository Structure
my-rails-app/
├── Gemfile # Ruby dependencies
├── Gemfile.lock # Locked dependency versions
├── .ruby-version # Optional: Pin Ruby version
├── config.ru # Rack configuration
├── pre-deploy.sh # Optional: Run migrations
├── post-deploy.sh # Optional: Cache warming
├── app/
│ ├── controllers/
│ ├── models/
│ └── views/
├── config/
│ ├── database.yml
│ ├── routes.rb
│ └── puma.rb
├── db/
│ └── migrate/
└── public/
└── assets/ # Compiled assets
Common Rails Gems for Production
# Gemfile
source 'https://rubygems.org'
ruby '3.2.0'
# Core
gem 'rails', '~> 7.0'
gem 'puma', '~> 6.0' # Application server
gem 'bootsnap', require: false # Faster boot times
# Database
gem 'pg', '~> 1.5' # PostgreSQL
# gem 'mysql2', '~> 0.5' # MySQL alternative
# Performance
gem 'redis', '~> 5.0' # Caching/sessions
gem 'rack-timeout' # Request timeouts
# Assets
gem 'sprockets-rails' # Asset pipeline
# gem 'webpacker', '~> 5.0' # Alternative: Webpack
# Production
gem 'rack-attack' # Rate limiting
gem 'rack-cors' # CORS for APIs
group :development, :test do
gem 'rspec-rails'
gem 'factory_bot_rails'
end