DEV Community

Quinterabok
Quinterabok

Posted on

Fly.io

Complete Fly.io Deployment Guide for Rails App

A beginner-friendly, step-by-step guide to deploying Ruby on Rails applications to Fly.io with Supabase database, custom domain, and email setup.


Table of Contents

  1. Prerequisites
  2. Part 1: Install Fly CLI
  3. Part 2: Set Up Supabase Database
  4. Part 3: Deploy to Fly.io (Testing)
  5. Part 4: Create Admin User
  6. Part 5: Deploy to Production
  7. Part 6: Buy and Connect Domain
  8. Part 7: Set Up Email Forwarding
  9. Part 8: Managing Your App
  10. Troubleshooting

Prerequisites

Before starting, ensure you have:

  • ✅ A Rails application ready to deploy
  • ✅ Git installed and your code committed
  • ✅ AWS S3 bucket set up for file storage (or similar)
  • ✅ Terminal/Command line access
  • ✅ Credit/debit card for domain purchase (~$10/year)

Cost Estimate:

  • Fly.io hosting: $5-10/month
  • Supabase database: FREE
  • Domain name: ~$10/year
  • Email: FREE (forwarding)
  • Total: ~$70-130/year

Part 1: Install Fly CLI

Step 1: Install Fly.io Command Line Tool

For macOS/Linux:

curl -L https://fly.io/install.sh | sh
Enter fullscreen mode Exit fullscreen mode

For Windows (PowerShell):

powershell -Command "iwr https://fly.io/install.ps1 -useb | iex"
Enter fullscreen mode Exit fullscreen mode

Step 2: Sign Up / Login

# Sign up for new account
fly auth signup

# Or login if you have an account
fly auth login
Enter fullscreen mode Exit fullscreen mode

Follow the browser prompts to complete authentication.

Step 3: Verify Installation

fly version
Enter fullscreen mode Exit fullscreen mode

You should see the Fly CLI version number.


Part 2: Set Up Supabase Database

Why Supabase?

  • ✅ FREE tier (500MB database)
  • ✅ Automatic backups
  • ✅ Great dashboard
  • ✅ Saves $38/month vs Fly Postgres

Step 1: Create Supabase Account

  1. Go to: https://supabase.com
  2. Click "Start your project"
  3. Sign up with GitHub, Google, or Email

Step 2: Create Organization (First Time)

  1. Enter organization name (e.g., "My Company")
  2. Click "Create organization"

Step 3: Create New Project

Fill in the form:

  • Name: your-app-name-prod (e.g., name-website-prod)
  • Database Password: Click refresh icon to generate
    • IMPORTANT: Copy and save this password!
    • Example: Kx9mP#vL2nQ8wR5t
  • Region: Choose closest to your users
    • Southeast Asia (Singapore)
    • West EU (Ireland)
    • East US (North Virginia)
  • Pricing Plan: FREE (already selected)

Click "Create new project" and wait 1-2 minutes.

Step 4: Get Database Connection String

  1. Click ⚙️ Settings (left sidebar)
  2. Click "Database"
  3. Scroll to "Connection string"
  4. Click "URI" tab
  5. Copy the connection string
  6. Replace [YOUR-PASSWORD] with your actual password from Step 3

Example final URL:

postgresql://postgres.abcdefghijklmno:Kx9mP#vL2nQ8wR5t@aws-0-ap-southeast-1.pooler.supabase.com:6543/postgres
Enter fullscreen mode Exit fullscreen mode

Save this URL - you'll need it soon!


Part 3: Deploy to Fly.io (Testing)

Step 1: Navigate to Your Project

cd /path/to/your-rails-app
Enter fullscreen mode Exit fullscreen mode

Step 2: Initialize Fly.io App

fly launch --no-deploy
Enter fullscreen mode Exit fullscreen mode

You'll be asked several questions:

Question 1: Copy existing fly.toml?

Answer: N (No) - Start fresh

Question 2: App name

Enter: your-app-test (e.g., name-website-test)

Question 3: Organization

Select: Personal (or your organization)

Question 4: Region

Select: Closest to you or your users (e.g., sin for Singapore)

Question 5: Tweak settings?

Answer: Y (Yes)

Step 3: Configure Settings in Browser

A browser window opens with configuration form:

Fill in:

  1. App name: your-app-test (already filled)
  2. Organization: Personal (already selected)
  3. Region: Keep your selection
  4. Internal port: 8080
  5. VM Memory: 2GB (select from dropdown)
  6. Postgres Provider: Select none (we're using Supabase)
  7. Tigris Object Storage: Select Disabled (using S3)
  8. Redis: Keep none
  9. Sentry: Keep Disabled

Click "Confirm Settings"

Step 4: Set Environment Secrets

Back in your terminal, set your secrets:

Generate SECRET_KEY_BASE:

rails secret
Enter fullscreen mode Exit fullscreen mode

Copy the output.

Set Database URL (from Supabase):

fly secrets set DATABASE_URL="postgresql://postgres.abc:yourpassword@aws-0-region.pooler.supabase.com:6543/postgres" --app your-app-test
Enter fullscreen mode Exit fullscreen mode

Set Rails Secret:

fly secrets set SECRET_KEY_BASE="paste-secret-from-rails-secret-command" --app your-app-test
Enter fullscreen mode Exit fullscreen mode

Set AWS S3 Credentials (if using S3):

fly secrets set AWS_ACCESS_KEY_ID="your-aws-key" --app your-app-test
fly secrets set AWS_SECRET_ACCESS_KEY="your-aws-secret" --app your-app-test
fly secrets set AWS_REGION="your-region" --app your-app-test
fly secrets set BUCKET_NAME="your-bucket-name" --app your-app-test
fly secrets set AWS_ENDPOINT_URL_S3="your-s3-endpoint" --app your-app-test
Enter fullscreen mode Exit fullscreen mode

Verify All Secrets:

fly secrets list --app your-app-test
Enter fullscreen mode Exit fullscreen mode

You should see all your secrets listed (shows digests, not actual values).

Step 5: Update fly.toml Configuration

Open fly.toml in your editor and ensure it looks like this:

app = 'your-app-test'
primary_region = 'sin'
console_command = '/rails/bin/rails console'

[build]

[env]
  PORT = '8080'
  RAILS_ENV = 'production'
  RAILS_LOG_TO_STDOUT = 'true'

[processes]
  app = './bin/rake litestream:run ./bin/rails server'

[http_service]
  internal_port = 8080
  force_https = true
  auto_stop_machines = 'stop'
  auto_start_machines = true
  min_machines_running = 0
  processes = ['app']

  [[http_service.checks]]
    interval = '10s'
    timeout = '2s'
    grace_period = '5s'
    method = 'GET'
    path = '/up'
    protocol = 'http'
    tls_skip_verify = false
    [http_service.checks.headers]
      X-Forwarded-Proto = 'https'

[[vm]]
  memory = '2gb'
  cpu_kind = 'shared'
  cpus = 1
Enter fullscreen mode Exit fullscreen mode

Step 6: Deploy Your App

fly deploy --app your-app-test
Enter fullscreen mode Exit fullscreen mode

Wait 3-5 minutes for the build and deployment to complete.

Watch logs in another terminal:

fly logs --app your-app-test
Enter fullscreen mode Exit fullscreen mode

Step 7: Run Database Migrations

fly ssh console --app your-app-test -C "rails db:migrate"
Enter fullscreen mode Exit fullscreen mode

Step 8: Test Your App

fly open --app your-app-test
Enter fullscreen mode Exit fullscreen mode

Your app opens at: https://your-app-test.fly.dev

✅ Test Environment is Live!


Part 4: Create Admin User

Step 1: SSH into Your App

fly ssh console --app your-app-test
Enter fullscreen mode Exit fullscreen mode

Step 2: Start Rails Console

./bin/rails console
Enter fullscreen mode Exit fullscreen mode

Or:

bundle exec rails console
Enter fullscreen mode Exit fullscreen mode

Step 3: Create Admin

Admin.create!(
  email: 'admin@example.com',
  password: 'TestPassword123!',
  password_confirmation: 'TestPassword123!'
)
Enter fullscreen mode Exit fullscreen mode

Note: Replace Admin with User if your model is called User. Adjust fields based on your model.

Step 4: Verify Admin Created

Admin.last
Enter fullscreen mode Exit fullscreen mode

Should show your newly created admin.

Step 5: Exit

exit  # Exit Rails console
exit  # Exit SSH
Enter fullscreen mode Exit fullscreen mode

Alternative: One-Line Command

From your local terminal:

fly ssh console --app your-app-test -C "./bin/rails runner \"Admin.create!(email: 'admin@example.com', password: 'TestPassword123!', password_confirmation: 'TestPassword123!')\""
Enter fullscreen mode Exit fullscreen mode

Step 6: Test Admin Login

  1. Visit your app: https://your-app-test.fly.dev/admin
  2. Login with credentials you just created
  3. Verify everything works ✅

Part 5: Deploy to Production

Now that testing works, let's create a production environment.

Step 1: Create Production App

fly launch --no-deploy
Enter fullscreen mode Exit fullscreen mode

Configuration:

  • App name: your-app-prod
  • Region: Same as test or closer to users
  • Tweak settings: Y (Yes)

Step 2: Configure Production Settings

In the browser form:

  • App name: your-app-prod
  • Region: Choose production region
  • Internal port: 8080
  • VM Memory: 2GB (more for production)
  • Postgres: none (using Supabase)
  • Tigris: Disabled

Click "Confirm Settings"

Step 3: Create Production Supabase Database

Option A: Use Same Database

  • Use the same Supabase database for production
  • Good for small projects
  • Cost: FREE

Option B: Create Separate Database (Recommended)

  1. Go to Supabase dashboard
  2. Create new project: your-app-prod
  3. Get new DATABASE_URL
  4. Keep test and production data separate ✅

Step 4: Set Production Secrets

# Generate NEW secret for production
rails secret

# Set database URL
fly secrets set DATABASE_URL="your-production-supabase-url" --app your-app-prod

# Set NEW secret key base
fly secrets set SECRET_KEY_BASE="new-secret-from-rails-secret" --app your-app-prod

# Copy AWS credentials (or use different production bucket)
fly secrets set AWS_ACCESS_KEY_ID="your-aws-key" --app your-app-prod
fly secrets set AWS_SECRET_ACCESS_KEY="your-aws-secret" --app your-app-prod
fly secrets set AWS_REGION="your-region" --app your-app-prod
fly secrets set BUCKET_NAME="your-production-bucket" --app your-app-prod
fly secrets set AWS_ENDPOINT_URL_S3="your-s3-endpoint" --app your-app-prod

# Verify
fly secrets list --app your-app-prod
Enter fullscreen mode Exit fullscreen mode

Step 5: Update Production fly.toml

Open fly.toml and update:

app = 'your-app-prod'
primary_region = 'sin'

[env]
  PORT = '8080'
  RAILS_ENV = 'production'

[http_service]
  internal_port = 8080
  force_https = true
  auto_stop_machines = 'suspend'
  auto_start_machines = true
  min_machines_running = 1  # Keep 1 always running in production

[[vm]]
  memory = '2gb'
  cpu_kind = 'shared'
  cpus = 2  # More CPU for production
Enter fullscreen mode Exit fullscreen mode

Step 6: Deploy Production

fly deploy --app your-app-prod
Enter fullscreen mode Exit fullscreen mode

Wait for deployment to complete.

Step 7: Run Migrations

fly ssh console --app your-app-prod -C "rails db:migrate"
Enter fullscreen mode Exit fullscreen mode

Step 8: Create Production Admin

fly ssh console --app your-app-prod -C "./bin/rails runner \"Admin.create!(email: 'admin@yourdomain.com', password: 'StrongProductionPassword123!', password_confirmation: 'StrongProductionPassword123!')\""
Enter fullscreen mode Exit fullscreen mode

Save these credentials securely!

Step 9: Test Production App

fly open --app your-app-prod
Enter fullscreen mode Exit fullscreen mode

Visit: https://your-app-prod.fly.dev

✅ Production is Live!


Part 6: Buy and Connect Domain

Step 1: Buy Domain from Namecheap

Why Namecheap?

  • ✅ Cheapest overall (~$10/year)
  • ✅ FREE privacy protection forever
  • ✅ FREE email forwarding
  • ✅ Easy DNS management
  • ✅ Great support

Purchase Process:

  1. Go to: https://www.namecheap.com
  2. Search for your desired domain
  3. Add to cart
  4. At checkout:
    • ✅ Check: WhoisGuard (Privacy Protection) - FREE
    • ❌ Uncheck: PremiumDNS
    • ❌ Uncheck: Email hosting
    • ❌ Uncheck: Website builder
    • ❌ Uncheck: SSL certificate
  5. Complete purchase (~$10-13)

Step 2: Get Fly.io IP Addresses

# Get your production app's IPs
fly ips list --app your-app-prod
Enter fullscreen mode Exit fullscreen mode

Output shows:

VERSION  IP                      TYPE    REGION
v4       66.241.125.202         public  global
v6       2a09:8280:1::a0:a7a4:0 public  global
Enter fullscreen mode Exit fullscreen mode

Copy both IPs - you'll need them next!

Step 3: Add Domain to Fly.io

# Add main domain
fly certs add yourdomain.com --app your-app-prod

# Add www subdomain
fly certs add www.yourdomain.com --app your-app-prod
Enter fullscreen mode Exit fullscreen mode

Example:

fly certs add name.com --app name-website-prod
fly certs add www.noblmed.com --app name-website-prod
Enter fullscreen mode Exit fullscreen mode

Step 4: Configure DNS in Namecheap

Login to Namecheap:

  1. Go to: https://www.namecheap.com
  2. Click "Sign In"
  3. Enter credentials

Go to Domain Management:

  1. Click "Domain List" (left sidebar)
  2. Find your domain
  3. Click "Manage" button

Open Advanced DNS:

  1. Click "Advanced DNS" tab

Delete Old Records:

Look for and DELETE any existing:

  • A Records with @ or blank host
  • CNAME Records with @ or blank host
  • Parking page records

Add New DNS Records:

Record 1 - A Record (IPv4):

Type: A Record
Host: @
Value: 66.241.125.202  (your IPv4 from Step 2)
TTL: Automatic
Enter fullscreen mode Exit fullscreen mode

Click ✅ to save.

Record 2 - AAAA Record (IPv6):

Type: AAAA Record
Host: @
Value: 2a09:8280:1::a0:a7a4:0  (your IPv6 from Step 2)
TTL: Automatic
Enter fullscreen mode Exit fullscreen mode

Click ✅ to save.

Record 3 - CNAME Record (WWW):

Type: CNAME Record
Host: www
Target: your-app-prod.fly.dev.  (note the dot at end!)
TTL: Automatic
Enter fullscreen mode Exit fullscreen mode

Click ✅ to save.

Save All Changes:

Scroll to bottom and click "SAVE ALL CHANGES"

Step 5: Wait for DNS Propagation

Wait 10-30 minutes for DNS changes to spread worldwide.

Check DNS Status:

# Check main domain
dig yourdomain.com

# Check www subdomain
dig www.yourdomain.com
Enter fullscreen mode Exit fullscreen mode

Or check online: https://www.whatsmydns.net/

Step 6: Verify SSL Certificates

After 15-20 minutes:

# Check main domain certificate
fly certs show yourdomain.com --app your-app-prod

# Check www certificate
fly certs show www.yourdomain.com --app your-app-prod
Enter fullscreen mode Exit fullscreen mode

When ready, you'll see:

The certificate for yourdomain.com has been issued.
Status: Ready ✅
Enter fullscreen mode Exit fullscreen mode

Step 7: Test Your Domain

Open browser and visit:

Both should:

  • ✅ Load your website
  • ✅ Show 🔒 padlock (secure HTTPS)
  • ✅ Work perfectly!

🎉 Your Custom Domain is Live!


Part 7: Set Up Email Forwarding

Step 1: Enable Email Forwarding

In Namecheap (still on your domain's management page):

  1. Look for "Mail Settings" or "Email Forwarding" section
  2. Click "Add Forwarder" or "Enable Email Forwarding"

Step 2: Add Email Forwards

Create forwarding rules:

Example forwards:

How to add each:

  1. Click "Add Forwarder"
  2. Alias: Enter admin (without @domain)
  3. Forward to: Enter your Gmail
  4. Click "Add" or ✅
  5. Repeat for other addresses

Step 3: Save Email Settings

Click "Save Changes"

Step 4: Test Email Forwarding

  1. Send test email to: admin@yourdomain.com
  2. Check your Gmail inbox
  3. Should receive within 1-2 minutes ✅

Step 5: Set Up Gmail "Send As" (Optional)

To reply from admin@yourdomain.com:

  1. Open Gmail
  2. Click ⚙️ Settings"See all settings"
  3. Click "Accounts and Import" tab
  4. Find "Send mail as:"
  5. Click "Add another email address"
  6. Enter:
  7. Click "Next Step"
  8. For SMTP, you need paid email service (Google Workspace, Zoho, etc.)

Note: Free forwarding only receives emails. To send, you need:

  • Google Workspace ($6/month)
  • Zoho Mail (free for up to 5 users)
  • Or reply from your Gmail (recipient sees Gmail address)

Part 8: Managing Your App

View App Status

# Check if app is running
fly status --app your-app-prod

# List all machines
fly machine list --app your-app-prod

# View recent logs
fly logs --app your-app-prod
Enter fullscreen mode Exit fullscreen mode

Stop App (When Not in Use)

To save costs when not needed:

# Stop all machines
fly scale count 0 --app your-app-prod
Enter fullscreen mode Exit fullscreen mode

What happens:

  • ✅ App stops completely
  • ✅ No compute charges (only storage)
  • ✅ Visitors see "503 Service Unavailable"
  • ✅ Database and files remain safe

Start App Again

# Start 1 machine
fly scale count 1 --app your-app-prod
Enter fullscreen mode Exit fullscreen mode

What happens:

  • ✅ App starts in 10-30 seconds
  • ✅ Website works normally
  • ✅ Everything restored

Auto-Stop Configuration

Edit fly.toml to automatically stop when idle:

[http_service]
  auto_stop_machines = 'stop'      # Auto-stop when no traffic
  auto_start_machines = true       # Auto-start when visitor arrives
  min_machines_running = 0         # Allow stopping completely
Enter fullscreen mode Exit fullscreen mode

Benefits:

  • ✅ Automatically stops after 5 minutes of no traffic
  • ✅ Automatically starts when someone visits
  • ✅ Saves money on low-traffic sites
  • ⚠️ First visitor waits ~10 seconds for startup

For always-on production:

[http_service]
  auto_stop_machines = false
  auto_start_machines = true
  min_machines_running = 1  # Always keep 1 running
Enter fullscreen mode Exit fullscreen mode

Restart App

fly apps restart your-app-prod
Enter fullscreen mode Exit fullscreen mode

View Dashboard

fly dashboard --app your-app-prod
Enter fullscreen mode Exit fullscreen mode

Opens web dashboard in browser.

SSH into App

fly ssh console --app your-app-prod
Enter fullscreen mode Exit fullscreen mode

Run Rails Console

fly ssh console --app your-app-prod -C "./bin/rails console"
Enter fullscreen mode Exit fullscreen mode

Update App

After making code changes:

# Commit changes to git
git add .
git commit -m "Your changes"

# Deploy update
fly deploy --app your-app-prod

# Watch deployment
fly logs --app your-app-prod
Enter fullscreen mode Exit fullscreen mode

Scale Resources

# Add more memory
fly scale memory 4096 --app your-app-prod

# Add more machines
fly scale count 2 --app your-app-prod

# Change VM type
fly scale vm shared-cpu-2x --app your-app-prod
Enter fullscreen mode Exit fullscreen mode

View Costs

fly orgs show
Enter fullscreen mode Exit fullscreen mode

Shows your current usage and estimated costs.


Troubleshooting

Issue: "Database connection failed"

Solution:

# Verify DATABASE_URL is set
fly secrets list --app your-app-prod

# Re-set if needed
fly secrets set DATABASE_URL="your-correct-url" --app your-app-prod

# Restart app
fly apps restart your-app-prod
Enter fullscreen mode Exit fullscreen mode

Issue: "DNS not resolving"

Solution:

  1. Check DNS records in Namecheap
  2. Verify IPs match: fly ips list --app your-app-prod
  3. Wait 30 more minutes for propagation
  4. Clear browser cache or try incognito

Issue: "SSL certificate not issued"

Solution:

# Check certificate status
fly certs show yourdomain.com --app your-app-prod

# If stuck, remove and re-add
fly certs remove yourdomain.com --app your-app-prod
fly certs add yourdomain.com --app your-app-prod

# Wait 15 minutes
Enter fullscreen mode Exit fullscreen mode

Issue: "App not starting"

Solution:

# Check logs for errors
fly logs --app your-app-prod

# Common issues:
# - Missing SECRET_KEY_BASE
# - Wrong DATABASE_URL
# - Port configuration (should be 8080)

# Verify secrets
fly secrets list --app your-app-prod

# Check fly.toml port settings
cat fly.toml | grep port
Enter fullscreen mode Exit fullscreen mode

Issue: "Can't create admin"

Solution:

# SSH into app
fly ssh console --app your-app-prod

# Check your model name
./bin/rails runner "puts User.column_names"
# or
./bin/rails runner "puts Admin.column_names"

# Create with correct fields
./bin/rails console
Admin.create!(email: 'test@example.com', password: 'password123', password_confirmation: 'password123')
Enter fullscreen mode Exit fullscreen mode

Issue: "File uploads not working"

Solution:

# Verify S3 credentials are set
fly secrets list --app your-app-prod

# Should see:
# - AWS_ACCESS_KEY_ID
# - AWS_SECRET_ACCESS_KEY
# - AWS_REGION
# - BUCKET_NAME
# - AWS_ENDPOINT_URL_S3

# Test S3 connection in Rails console
fly ssh console --app your-app-prod -C "./bin/rails console"
# Then test upload
Enter fullscreen mode Exit fullscreen mode

Issue: "Out of memory errors"

Solution:

# Check current memory
fly status --app your-app-prod

# Increase memory
fly scale memory 4096 --app your-app-prod

# Or reduce memory if overprovisioned
fly scale memory 1024 --app your-app-prod
Enter fullscreen mode Exit fullscreen mode

Issue: "Emails not forwarding"

Solution:

  1. Check Namecheap email forwarding settings
  2. Verify Gmail isn't marking as spam
  3. Wait 30 minutes for DNS changes
  4. Test with different email provider

Get Help

# Fly.io community forum
# https://community.fly.io

# Fly.io documentation
# https://fly.io/docs

# View all Fly commands
fly help

# Get help for specific command
fly help deploy
Enter fullscreen mode Exit fullscreen mode

Quick Command Reference

Deployment

# Initialize app
fly launch --no-deploy

# Deploy app
fly deploy --app your-app-name

# Deploy with specific fly.toml
fly deploy --app your-app-name --config fly.toml
Enter fullscreen mode Exit fullscreen mode

App Management

# View status
fly status --app your-app-name

# View logs
fly logs --app your-app-name

# Restart app
fly apps restart your-app-name

# Stop app
fly scale count 0 --app your-app-name

# Start app
fly scale count 1 --app your-app-name

# Open app in browser
fly open --app your-app-name
Enter fullscreen mode Exit fullscreen mode

SSH & Console

# SSH into app
fly ssh console --app your-app-name

# Run Rails console
fly ssh console --app your-app-name -C "./bin/rails console"

# Run one-off command
fly ssh console --app your-app-name -C "rails db:migrate"
Enter fullscreen mode Exit fullscreen mode

Secrets

# List secrets
fly secrets list --app your-app-name

# Set secret
fly secrets set KEY="value" --app your-app-name

# Unset secret
fly secrets unset KEY --app your-app-name
Enter fullscreen mode Exit fullscreen mode

Domain & SSL

# Add domain
fly certs add yourdomain.com --app your-app-name

# Check certificate
fly certs show yourdomain.com --app your-app-name

# List all certificates
fly certs list --app your-app-name

# Remove certificate
fly certs remove yourdomain.com --app your-app-name
Enter fullscreen mode Exit fullscreen mode

Scaling

# Scale number of machines
fly scale count 2 --app your-app-name

# Scale memory
fly scale memory 2048 --app your-app-name

# Change VM type
fly scale vm shared-cpu-2x --app your-app-name
Enter fullscreen mode Exit fullscreen mode

Database

# Run migrations
fly ssh console --app your-app-name -C "rails db:migrate"

# Create database
fly ssh console --app your-app-name -C "rails db:create"

# Seed database
fly ssh console --app your-app-name -C "rails db:seed"

# Reset database (CAREFUL!)
fly ssh console --app your-app-name -C "rails db:reset"
Enter fullscreen mode Exit fullscreen mode

Cost Breakdown

Monthly Costs

Service Cost Notes
Fly.io Compute $5-10/month Depends on usage
Supabase Database FREE Up to 500MB
AWS S3 Storage $1-5/month Depends on files
Domain Name ~$1/month $10-13/year
Email Forwarding FREE Via Namecheap
SSL Certificates FREE Via Let's Encrypt
Total $7-16/month $84-192/year

Ways to Save

  1. Use auto-stop: App stops when not in use
  2. Use free tier Supabase: Instead of paid Postgres
  3. Share S3 bucket: Use same bucket for test/prod
  4. Buy domain for multiple years: Slight discount
  5. Use email forwarding: Instead of Google Workspace

Next Steps

After completing this guide, you can:

  1. Add monitoring: Set up Sentry or error tracking
  2. Add analytics: Google Analytics, Plausible, etc.
  3. Set up CI/CD: GitHub Actions for auto-deploy
  4. Add custom email: Google Workspace or Zoho
  5. Scale up: Add more machines, memory, regions
  6. Add CDN: Cloudflare for better performance
  7. Set up backups: Automate database backups
  8. Add staging: Create staging environment

Summary

You've learned how to:

✅ Install Fly CLI and set up account
✅ Create FREE Supabase database
✅ Deploy Rails app to Fly.io (test and production)
✅ Create admin users
✅ Buy and connect custom domain
✅ Set up FREE email forwarding
✅ Manage, stop, and start your app
✅ Troubleshoot common issues

Your app is now live with:

  • Custom domain with SSL
  • Professional email addresses
  • Free database
  • Scalable hosting
  • All for ~$7-16/month!

Congratulations! 🎉


Support & Resources


Made with ❤️ for beginners

Top comments (0)