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:
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:
# 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:
# 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
:
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:
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:
# 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:
# 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:
# 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:
git push production main
Monitor your deployment:
# 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:
- Asset Compilation Failures
# Force a clean asset compilation
dokku run your-rails-app bundle exec rails assets:clobber assets:precompile
- Database Migration Issues
# Run migrations manually if needed
dokku run your-rails-app bundle exec rails db:migrate
- Worker Process Management
# 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
# 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:
# 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!
Originally published at https://sulmanweb.com.
Top comments (0)