Most Rails devs have moved on to CI pipelines, fancy cloud hooks, or even zero-deploy tools.
So when I tell people I still use Capistrano to deploy all my Rails apps, I get a look—like I just admitted to still using FTP.
But here’s the thing:
I’ve deployed hundreds of times using Capistrano.
And now I do it all inside Docker.
Not only does it work flawlessly, it avoids a whole category of headaches:
- No SSH agent weirdness
- No local Ruby version dependencies
- No flaky CI step failures
- No provisioning a new box every time
If you’re a solo developer or running a small team, this setup might save your sanity.
🧠 Why Not Just Use CI or GitHub Actions?
Because I don’t need to.
My Docker-based Capistrano workflow:
- Works consistently on every project
- Doesn’t rely on CI/CD services
- Deploys over existing installations, with zero downtime
- Avoids manual SSH key forwarding
- Is self-contained, fast, and shareable with collaborators
No CI pipeline. No secrets storage. No cloud runners.
Just a predictable image, and a deploy that just works.
🧱 How It Works
🐳 The Dockerfile (Summary)
This Dockerfile installs all the system dependencies needed to run Capistrano inside a container, bundles your app, and sets up a deploy script as the container's entrypoint.
FROM ruby:3.2.2-bullseye
# Installs system packages like libpq-dev, openssh-client, yarn, etc.
# Creates the working directory
# Installs bundler and installs gems
# Adds a deploy.sh script and runs it
You can build it like this:
docker build -t myapp-deploy -f Dockerfile.deploy.fixed .
The full Dockerfile is available in the free starter kit (link below).
🚀 Running the Deploy
Once built, you can deploy like this:
docker run -it --rm \
-v $(pwd)/server_key:/app/server_key \
-v $(pwd)/github_key:/app/github_key \
-v $(pwd):/app \
-e DEPLOY_STAGE=production \
myapp-deploy
This mounts your app directory and private SSH keys into the container so that Capistrano can connect to both the server and your Git repo.
🧰 The Deploy Script (deploy.sh) — Summary
This script configures the SSH environment inside the container, adds GitHub to known hosts, and kicks off the Capistrano deployment.
# Sets up /root/.ssh
# Copies and sets permissions for mounted SSH keys
# Adds github.com to known_hosts
# Writes SSH config for your target server
# Runs: bundle exec cap production deploy
The full script is included in the download below.
📦 Free Starter Kit
I've packaged everything (Dockerfile, deploy script, Capistrano config) into a free downloadable starter kit.
Grab it here → https://realliferails.com/dockerized-deploy-kit/
Includes:
Dockerfile.deploy.fixed
deploy.sh
- Example
deploy.rb
- README instructions
🤝 Tradeoffs
Let’s be honest:
- This doesn’t use CI. If that’s a dealbreaker for you, no problem.
- Some people dislike the Capistrano DSL. I don’t. It works.
- This method expects you to manage SSH keys carefully—but you are in control, not a black box.
🔧 Why I Stick With It
I use this for every Rails project.
It’s portable, reproducible, and doesn’t get in my way.
Even contractors can deploy safely without polluting their machines or setting up CI pipelines.
🛠 Need Help?
If you’re dealing with flaky deploys, broken staging environments, or SSH key nightmares, I run Rails Rescue Sprints that cover exactly this kind of infrastructure cleanup.
👉 https://realliferails.com/ruby-on-rails-rescue-sprint
Top comments (0)