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.

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 shipHere's what you'll see, in order:
- A check that both machines have Docker. If the server doesn't, you get the one-line install command.
- A code check. A problem stops the deploy before anything is built.
- A build made for the kind of server you have, tagged with your latest commit.
- The image sent over SSH, with nothing in between.
- The old version parked as "previous", and the new one made live.
- A health check. The new container has to answer before the deploy counts as done.
- An automatic undo if it doesn't: the previous version comes back and you're told it failed.
- 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 --rollbackOn 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 ship | Kamal | |
|---|---|---|
| Registry | None | Not covered in the pages I checked |
| Servers | One | Many, per Kamal's pitch |
| Server setup | You install Docker (you get the command) | Provisions Docker for you, per Kamal's site |
| Zero-downtime method | Starts the new version, checks health, otherwise restores the previous | Described by Kamal; I didn't verify how |
| Setup | A few settings and one command | Kamal'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
- Not zero-downtime. Replacing a container can leave a short gap while the new one starts. If that matters, use the default deploy route, which keeps the old version serving until the new one is ready.
- One server only. There's no rolling release across machines.
- Scheduled jobs aren't set up for you. They're set up on the default route. With Docker, add the same schedule to your server yourself.
- A big upload each time. The whole image goes over SSH, though compression helps.
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
- Docker Compose + Next.js: Don't Let It Eat Your SQLite — the storage details
- Free Vercel Alternative: Host Next.js on a $6 VPS — the default deploy route
- Free GitHub Actions Alternative: Deploy Without CI Minutes — no hosted runners involved
+ all the boring stuff (analytics, auth, SQLite ↔ Supabase, full marketplace, webhooks)
Command from your phone.
Built so autonomous AI agents build what you want without breaking what's already paying you.
- Built-in analytics — cookie-free mode, $0 forever, no PostHog bill
- SQLite ↔ Supabase: one setting, same field names
- Full digital marketplace & feedback boards included
- 3 payment rails: Stripe, LemonSqueezy & Dodo Payments
- Agent fences: lint gate, read-only data access, auto-rollback
- Ship from your phone via SSH & WireGuard/Tailscale in under a minute
$199
Get BoringPushOne-time payment · Lifetime updates · Unlimited projects.
Keep reading


