docker · deploy · alternative

Free Kamal Alternative: Docker to a VPS, No Registry

Ship a Next.js Docker image to your own server with one command: no registry account, a one-step rollback, and a health check before it goes live.

A faded tile reading Kamal with a curved arrow to the BoringPush logo, titled Free Kamal alternative
A faded tile reading Kamal with a curved arrow to the BoringPush logo, titled Free Kamal alternative · Photo: BoringPush

You need a registry just to move one image

The usual path for a container deploy is: build the image, push it to a registry, then have the server pull it. For one app on one server, that's an extra account, an extra credential and an extra place for your image to live.

Kamal, the Rails team's deploy tool, describes itself on its site (checked 2026-10-20) as "Capistrano for Containers" that can deploy web apps "anywhere," onto "vanilla Ubuntu servers" with an SSH key, which it provisions with Docker. It's a well-known way to get container deploys onto your own servers.

This post is about a smaller route for a Next.js app, in the project you already have.

Why we built our own

Kamal's idea is a good one: put the new version next to the old one, check it's alive, switch over, and keep the old one close. We built that idea into BoringPush for the smallest case, one app on one server.

There are two routes, and you choose. The default route is bare metal: your computer builds, the server swaps, and the previous version is always one command away. The Docker route does the same with containers, and it's the one this post is about.

What you get

One command builds your app into a container and sends it straight to your server. No registry account, no registry password, and nothing to sign up for. Your SSH key is the only credential.

If the new version doesn't come up healthy, the last good one is brought back. And your data stays put through every release.

The command

VPS_HOST=your-server bp docker ship

Here's what you'll see, in order:

  1. A check that both machines have Docker. If the server doesn't, you get the one-line install command.
  2. A code check. A problem stops the deploy before anything is built.
  3. A build made for the kind of server you have, tagged with your latest commit.
  4. The image sent over SSH, with nothing in between.
  5. The old version parked as "previous", and the new one made live.
  6. A health check. The new container has to answer before the deploy counts as done.
  7. An automatic undo if it doesn't: the previous version comes back and you're told it failed.
  8. A tidy-up that keeps only the live and previous versions, so your disk doesn't fill.

Undo a release by hand at any time:

VPS_HOST=your-server bp docker ship --rollback

On the very first deploy there's no previous version yet, and you're told so.

Your data and secrets stay put

Your database lives in its own storage, outside the container, so a new version keeps the same data. Secrets come from a file on your server and are never baked into the image.

The app is reachable only through your web server, not directly from the internet. And the container restarts by itself if it ever stops. The README lists the image at about 285 MB.

Kamal next to this script

BoringPush Docker shipKamal
RegistryNoneNot covered in the pages I checked
ServersOneMany, per Kamal's pitch
Server setupYou install Docker (you get the command)Provisions Docker for you, per Kamal's site
Zero-downtime methodStarts the new version, checks health, otherwise restores the previousDescribed by Kamal; I didn't verify how
SetupA few settings and one commandKamal's own config file

I checked only Kamal's front page for this post, so read its docs for details I've marked as unverified. The honest summary: Kamal is built for fleets, and this is built for a single box.

Who this fits

It fits one app on one server, where you already like containers. You get the safety of a health check and a previous version, without learning a new tool or opening a registry account.

If you run several servers, or want a managed rollout across them, look at a fleet tool like Kamal instead.

Know this first

Why BoringPush is the way to do this

Containers shouldn't need a registry account to move one app to one server. In BoringPush the image goes straight to your server, the old version is kept, and a bad release undoes itself.

It's the shortest path from a Docker image to a live app, and it's already built into the kit you're using.

FAQ

Do I need Docker Hub or any registry?

No. The image goes from your machine to your server over SSH. You need Docker installed on both.

Can I use it for a staging server?

Yes. Give the second app its own name and port, and you get a separate staging copy next to production.

What happens to my database on deploy?

It stays where it is. The database lives in separate storage that the container mounts, so a new version picks up the same data. Back it up like any database file: see Back Up SQLite With VACUUM INTO.

How is this different from the default deploy?

The default route builds on your laptop and swaps the new version in. Docker builds a container and swaps container versions. Pick Docker if you want isolation or already run containers; the Docker Compose and SQLite post covers the storage pitfalls.

What if the new image is unhealthy?

The previous version is restored and the command tells you it failed. If there's no previous version (your first deploy), there's nothing to restore, and you'll need to fix it forward.

Keep reading

Get BoringPush →

+ all the boring stuff (analytics, auth, SQLite ↔ Supabase, full marketplace, webhooks)

The Agent-First Shipping Kit

Command from your phone.

Built so autonomous AI agents build what you want without breaking what's already paying you.

$199

Get BoringPush

One-time payment · Lifetime updates · Unlimited projects.

Keep reading