Mina was the fast alternative to Capistrano: one SSH connection per deploy, a bash script uploaded and executed, atomic symlinked releases, the same `deploy.rb` shape Ruby developers already knew. It was deliberately small and deliberately opinionated, and for a long time that was exactly the right answer.

If your `deploy.rb` still works, it will keep working. But the project moves slowly now, and the bolt-ons every team eventually needs — a web UI, an audit log of who deployed what, role-based access, AI-assisted error analysis, build pipelines that run off the target server — were never in scope for Mina, and they are not coming.

DeployHQ keeps the parts of Mina you actually relied on (any Git remote, any SSH host, atomic releases via symlink swap, before/after hooks) and adds the parts you have always had to build around it.

For a related guide if you are evaluating multiple Ruby deploy tools, see [Migrating from Capistrano to DeployHQ](/support/migrating-to-deployhq/migrating-from-capistrano-to-deployhq) — the migration shape is nearly identical. If your deploys currently run from a CI pipeline rather than `mina deploy`, see [Migrating from GitHub Actions to DeployHQ](/support/migrating-to-deployhq/migrating-from-github-actions-to-deployhq) for the hybrid pattern.

## Feature parity: Mina to DeployHQ

Everything `mina deploy` does, DeployHQ does. The configuration moves from a Ruby DSL into a web UI; the deploy semantics stay the same.

| Mina | DeployHQ |
| --- | --- |
| `config/deploy.rb` | DeployHQ project (web-configured) |
| `set :domain`, `set :user`, `set :deploy_to` | Server entry per environment |
| `set :branch, "main"` | Branch per environment |
| `set :repository` | Repository connection (Git, SVN, or Mercurial) |
| `set :shared_files`, `set :shared_dirs` | Shared paths configured once per environment |
| Mina release directory and `current` symlink | [Atomic deploy with automatic symlink swap](/support/deployments/zero-downtime-deployments/setting-up-zero-downtime-deployments) |
| `task :deploy do ... end` blocks | Deploy lifecycle stages in the dashboard |
| `queue!` and `queue` commands | [SSH commands](/support/ssh-commands) tied to deploy lifecycle |
| `invoke :"git:clone"`, `invoke :"deploy:link_shared_paths"` | Built into the standard DeployHQ deploy flow |
| `mina rollback` | [One-click rollback](/support/deployments/rolling-back-a-deployment) to any prior deploy |
| `:keep_releases` | Configurable release retention per environment |
| Mina stages plugin (multi-environment) | Native multi-environment per project |

## What DeployHQ adds that Mina never did

| Capability | Why it matters |
| --- | --- |
| Web UI plus REST and GraphQL API | Deploy from a browser, a CLI, or a CI step. No `mina` binary or Ruby on the deploying machine. |
| Audit log of every deploy | Who deployed what, when, from which branch, with which commit hash. Mina did not record any of this. |
| [Build pipelines](/support/build-pipelines) | Run `bundle install --deployment`, asset precompile, npm builds once on our build infrastructure — not piped through `queue!` on the target. |
| AI deploy error explanation | When a deploy fails, the failed step is summarised in plain English with a likely fix. |
| [DeployHQ CLI](/support/cli) | `deployhq deploy production` from your terminal, scriptable in CI. |
| Per-environment permissions | Grant deploy-to-staging without granting deploy-to-production. |
| Optional [Managed VPS](/support/managed-vps-hosting) (beta) | Provision a server inside DeployHQ if you do not already have one. |

## Migration in three steps

### 1. Connect your repository

Point DeployHQ at the same Git URL your `set :repository` line uses. Read-only deploy keys are generated automatically. DeployHQ checks out your code on our build infrastructure, so you do not need `git` on the target server (Mina cloned on the target; DeployHQ does not).

### 2. Recreate your servers and shared paths

Each Mina target — typically one per stage if you use the stages plugin — becomes a DeployHQ environment with one or more servers attached:

- `set :domain, "example.com"` and `set :user, "deploy"` become the server's hostname and SSH user.
- `set :deploy_to, "/var/www/app"` becomes the environment deploy path.
- `set :shared_dirs, %w(log tmp/pids public/uploads)` becomes shared paths.
- `set :shared_files, %w(.env config/database.yml)` becomes shared files.

If you ran Mina against multiple servers via custom tasks or the cluster plugin, add them all to the same environment in DeployHQ — deploys run in parallel against every server with the same atomic symlink swap.

### 3. Translate `queue!` commands into SSH commands

This is the bulk of the migration. Every `queue!` line in your `task :deploy` block becomes an SSH command tied to a deploy stage.

A typical Rails Mina recipe like this:

```ruby
task :deploy => :environment do
  deploy do
    invoke :'git:clone'
    invoke :'deploy:link_shared_paths'
    invoke :'bundle:install'
    invoke :'rails:db_migrate'
    invoke :'rails:assets_precompile'

    on :launch do
      queue! "sudo systemctl restart puma"
    end
  end
end
```

becomes, in DeployHQ:

- `bundle install` — moved into the [build pipeline](/support/build-pipelines), so it runs once on our build server and the bundled gems are uploaded with the release rather than installed on every target.
- `assets:precompile` — also a build pipeline step, for the same reason.
- `rails db:migrate` — an SSH command set to run *after upload, before changing the symlink*.
- `sudo systemctl restart puma` — an SSH command set to run *after deploy*.

`invoke :'git:clone'` and `invoke :'deploy:link_shared_paths'` have no equivalent — they are part of the standard DeployHQ deploy flow and happen automatically.

For most Mina projects, end-to-end migration is a half-day. Concierge migration is available on Pro and above — send us your `deploy.rb` and we will rebuild the project with you on a screenshare.

## What teams ask before they switch

**Do I lose Mina's single-SSH-connection speed advantage?** Not in practice. DeployHQ's atomic deploy is comparable in wall-clock time on a single server, and faster on multi-server deploys because it deploys to all servers in parallel rather than serially.

**Can I keep using my existing servers?** Yes. DeployHQ deploys to any SSH-reachable host. Bring your own VPS, dedicated server, or cloud instance.

**What about my Mina plugins (mina-rails, mina-puma, mina-sidekiq)?** Their behaviours map to DeployHQ build pipelines (asset precompile, bundle install) and SSH commands (puma restart, sidekiq restart). You do not reinstall the plugins — you replicate what they did.

**What happens to my custom `task :foo` blocks?** Anything that ran over SSH on the target server runs identically — it is just configured in the dashboard instead of `deploy.rb`.

**What if I want to roll back?** One click. DeployHQ keeps your last N releases on the server (you configure N). Rollback flips the symlink back. No `mina rollback` required.

**Do you support multi-server deploys?** Yes. Add multiple servers to one environment; DeployHQ deploys to all of them in parallel with the same atomic symlink swap.

## Start your migration

Start a free DeployHQ project — connect your repo, point at one server, and deploy in under 15 minutes. No credit card.

If you also need a server, the [Managed VPS beta](/support/managed-vps-hosting) provisions one inside the same dashboard.

Mina is a trademark of its respective maintainers. DeployHQ is not affiliated with the Mina project. We just understand what graduating from a single-file `deploy.rb` looks like.
