# Rails 8 Production Setup with Dokku Guide

## The Challenge: Modernizing Rails Deployment

When I recently needed to deploy my Rails 8 application with multiple databases, I faced a common dilemma: choosing between expensive managed solutions and complex self-managed servers. My requirements were specific:

* Multiple PostgreSQL databases for different concerns
    
* SSL certificate management
    
* Automated deployment pipeline
    
* Cost-effective hosting
    
* Easy database management
    
* Background job processing
    

Let me walk you through how I solved this using Dokku.

## Setting Up Our Foundation

First, let's prepare our server. I chose a 2GB RAM VPS - here's why:

* Dokku needs about 1GB RAM to operate smoothly
    
* Rails 8 with Puma and background jobs needs the other 1GB
    
* Anything less resulted in occasional memory issues during asset compilation
    

### Initial Server Configuration

SSH into your server and install Dokku:

```bash
wget -NP . https://dokku.com/install/v0.35.13/bootstrap.sh
sudo DOKKU_TAG=v0.35.13 bash bootstrap.sh
```

After countless deployments, I've found this version to be particularly stable with Rails 8.

## The Database Architecture

One of Rails 8's strengths is its multi-database support. In my setup, I separated concerns into four databases:

```bash
# Create our databases
dokku postgres:create rails_primary_db
dokku postgres:create rails_cache_db
dokku postgres:create rails_queue_db
dokku postgres:create rails_cable_db
```

Here's why I chose this architecture:

* Primary DB: Core application data
    
* Cache DB: Session and cache storage
    
* Queue DB: Background job management
    
* Cable DB: Action Cable subscriptions
    

### The Magic of Database Linking

This is where things get interesting. When linking databases, Dokku generates unique environment variables:

```bash
# Link each database and capture the environment variable names
dokku postgres:link rails_primary_db your-rails-app
# Returns: DATABASE_URL=postgres://...

dokku postgres:link rails_cache_db your-rails-app
# Returns: DOKKU_POSTGRES_AQUA_URL=postgres://...

dokku postgres:link rails_queue_db your-rails-app
# Returns: DOKKU_POSTGRES_BLACK_URL=postgres://...

dokku postgres:link rails_cable_db your-rails-app
# Returns: DOKKU_POSTGRES_BLUE_URL=postgres://...
```

## Rails 8 Configuration Magic

Here's how I configured my Rails 8 application to use these databases. In `config/database.yml`:

```yaml
production:
  primary: &primary_production
    <<: *default
    database: <%= ENV['DATABASE_URL'] || 'rails_primary_db' %>
    url: <%= ENV['DATABASE_URL'] %>

  cache:
    <<: *primary_production
    database: <%= ENV['DOKKU_POSTGRES_AQUA_URL'] || 'rails_cache_db' %>
    migrations_paths: db/cache_migrate
    url: <%= ENV['DOKKU_POSTGRES_AQUA_URL'] %>

  queue:
    <<: *primary_production
    database: <%= ENV['DOKKU_POSTGRES_BLACK_URL'] || 'rails_queue_db' %>
    migrations_paths: db/queue_migrate
    url: <%= ENV['DOKKU_POSTGRES_BLACK_URL'] %>

  cable:
    <<: *primary_production
    database: <%= ENV['DOKKU_POSTGRES_BLUE_URL'] || 'rails_cable_db' %>
    migrations_paths: db/cable_migrate
    url: <%= ENV['DOKKU_POSTGRES_BLUE_URL'] %>
```

## The Deployment Pipeline

Create a `Procfile` in your Rails root:

```plaintext
web: bin/rails server -p $PORT -e $RAILS_ENV
worker: bin/jobs
release: bundle exec rails db:migrate 2>/dev/null || bundle exec rails db:setup
```

I learned the hard way that the `release` command needs error handling for first deployments, hence the `2>/dev/null || bundle exec rails db:setup` pattern.

## Environment Configuration

Rails 8 needs specific environment variables. Here's my production setup:

```bash
# Rails essentials
dokku config:set your-rails-app RAILS_ENV=production
dokku config:set your-rails-app RACK_ENV=production
dokku config:set your-rails-app RAILS_MASTER_KEY=$(cat config/credentials/production.key)

# Rails 8 specifics
dokku config:set your-rails-app RAILS_SERVE_STATIC_FILES=true
dokku config:set your-rails-app RAILS_LOG_TO_STDOUT=true
```

## Git Deployment Setup

Configure your local repository:

```bash
# Add Dokku remote
git remote add production dokku@your-server-ip:your-rails-app

# Verify remote addition
git remote show production

# Set deployment branch
dokku git:set your-rails-app deploy-branch main
```

## SSL Configuration

Rails 8 expects HTTPS in production. Here's how to set it up with Let's Encrypt:

```bash
# Install the plugin
sudo dokku plugin:install https://github.com/dokku/dokku-letsencrypt.git

# Configure your domain
dokku domains:clear-global
dokku domains:set your-rails-app yourdomain.com

# Setup SSL
dokku letsencrypt:set your-rails-app email your@email.com
dokku letsencrypt:enable your-rails-app
dokku letsencrypt:cron-job --add
```

## Deployment and Monitoring

Deploy your application:

```bash
git push production main
```

Monitor your deployment:

```bash
# Real-time logs
dokku logs your-rails-app -t

# Process status
dokku ps:report your-rails-app

# Database status
dokku postgres:info rails_primary_db
```

## Troubleshooting Common Rails 8 Issues

During my deployments, I encountered several Rails 8-specific issues:

1. **Asset Compilation Failures**
    
    ```bash
    # Force a clean asset compilation
    dokku run your-rails-app bundle exec rails assets:clobber assets:precompile
    ```
    
2. **Database Migration Issues**
    
    ```bash
    # Run migrations manually if needed
    dokku run your-rails-app bundle exec rails db:migrate
    ```
    
3. **Worker Process Management**
    
    ```bash
    # Restart workers after config changes
    dokku ps:restart your-rails-app worker
    ```
    

## Maintenance Tips

Based on my experience, here are some crucial maintenance practices:

### Database Backups

```bash
# Backup all databases
for db in primary cache queue cable; do
  dokku postgres:export rails_${db}_db > ${db}_backup.dump
done
```

### Performance Monitoring

Monitor your Rails 8 application's health:

```bash
# Check memory usage
dokku ps:report your-rails-app

# View error logs
dokku logs your-rails-app -t | grep ERROR
```

## Conclusion

Deploying Rails 8 with Dokku has been a game-changer for my development workflow. The combination of Rails 8's robust multi-database support and Dokku's Heroku-like deployment experience has made managing production applications both cost-effective and developer-friendly.

Remember to:

* Keep your Rails master key secure
    
* Regularly backup all databases
    
* Monitor worker processes
    
* Keep an eye on memory usage
    

The setup might seem extensive, but once configured, deployments become as simple as `git push production main`. Feel free to reach out if you encounter any Rails 8-specific deployment challenges!

This guide reflects my real-world experience deploying Rails 8 applications with Dokku. As you work with this setup, you'll likely discover additional optimizations specific to your use case.

Happy deploying!

---
