← All posts

9 min read

Heroku Self-Hosted Alternative: Git-Push Rails on a VPS

Key takeaways

  • A self-hosted Heroku alternative means running a buildpack-based platform like Dokku on your own VPS so git push still triggers build, release, and restart.
  • Rails builds need at least 2 GB of RAM, since gem compilation and asset precompilation can OOM-kill a 1 GB VPS mid-deploy.
  • Rollback re-points to the previous slug but never reverses your database, so keep migrations backwards-compatible for one deploy.
  • Self-hosting means you own Postgres backups, HTTPS renewal, monitoring, and OS patching, budgeting a few hours a week.
  • If your blocker is payment rather than preference, a managed PaaS accepting MTN or Airtel Money beats self-hosting.

A heroku self-hosted alternative means running a platform like Dokku on your own VPS so you keep the git push deploy workflow without paying Heroku. You handle the server, HTTPS, and Postgres yourself. This guide walks through the exact setup and the trade-offs at each step, so you can decide between self-hosting and a managed PaaS you can actually pay for with mobile money.

What does 'self-hosted Heroku alternative' actually mean for a Rails app?

Heroku is winding down, with its next chapter announced as reduced investment in the platform (Heroku pricing and plans), so teams that lived on git push heroku main need to know what they are rebuilding. It is three layers, not one.

The three Heroku features you are actually replacing

First, the entry point: a git remote that accepts a push and triggers a deploy. Second, the build pipeline: buildpacks that detect your Rails app, install Ruby and gems, and compile a slug. Third, the runtime: a process manager that reads your Procfile, runs web and worker dynos, and restarts them when they crash. Self-hosting means you own all three on a VPS you pay for directly.

Self-hosted vs managed: where the line sits

Managed platforms like Render or Railway run those layers for you but bill in USD by card, which many East African developers cannot do. Self-hosted keeps the git-push workflow but puts the server, and the payment, in your hands. We compare managed options honestly at Omeganodes vs Heroku.

Which self-hosted PaaS options support Rails buildpacks and Procfiles?

Three realistic routes exist for running a Heroku-style Rails deploy on your own VPS: a buildpack-based platform, a Docker-based platform, or plain Capistrano/Kamal on bare systemd. They differ mainly in setup effort and how closely they reproduce git push doing everything.

Buildpack-based platforms on your own server

This is the closest match to Heroku. You install the platform once, add a git remote, and git push triggers buildpack detection, bundle install, asset precompilation, and a Procfile-defined process. No Dockerfile, no YAML. Setup takes an hour or two on a fresh VPS, and ongoing maintenance is mostly patching the platform itself.

Docker-based platforms: more control, more YAML

Docker-based tools give you reproducible builds and easier multi-service setups, but you write a Dockerfile or compose file and manage build contexts. For a Rails side project, that is extra work buildpacks would have done for you. Worth it if you need non-Procfile services or custom system dependencies.

Plain VPS with Capistrano or Kamal

Capistrano or Kamal on systemd is the lightest on server resources but the heaviest on you. Deploys are script-driven rather than push-based, and you own SSL renewal, restarts, and rollback logic yourself.

RouteSetup effortProcfile/buildpack fidelityOngoing work
Buildpack PaaSLowNear-exactPatch platform
Docker PaaSMediumPartial (you write Dockerfile)Maintain images
Capistrano/KamalHighNoneOwn everything

If you would rather skip the self-hosting entirely, Omeganodes runs this same push-to-deploy model on managed EU servers, with MTN and Airtel mobile money accepted.

What infrastructure do you need before you can self-host a Heroku-style platform?

Before your first git push, you need six things running: a VPS, a domain, a reverse proxy, Postgres, backups, and monitoring. Miss any one and your deploy pipeline stalls or your data does.

Server sizing for Rails builds

Rails builds are memory hungry. Compiling gems like nokogiri or running asset precompilation can push a 1 GB VPS into OOM kills mid-deploy. Start with 2 GB RAM and 2 vCPUs for one small app, and add swap as a buffer. If you later run the platform plus several apps on one box, 4 GB is the realistic floor.

HTTPS, domains and the reverse proxy

You need a domain with DNS access you control, because automatic HTTPS issues certificates per hostname. A reverse proxy (Caddy or nginx with certbot) terminates TLS and routes traffic to your containers. Most Docker-based PaaS projects handle this for you; the CNCF Cloud Native Landscape groups the available options under "App Definition and Development" if you want to browse them.

Postgres, backups and monitoring you now own

Heroku gave you a managed database with automated backups. Self-hosting means you install Postgres, schedule pg_dump to off-server storage, and test a restore. Add basic monitoring (uptime checks plus memory and disk alerts) before your first real user, not after your first outage.

Managed platforms like Omeganodes bundle these pieces so you skip the setup entirely, which is the trade-off the next sections weigh.

How does a git-push deploy work when the platform runs on your own server?

The whole workflow fits in four steps: push to a bare repo, let a hook build your slug, run release tasks, then restart and roll back if needed. Each step has a failure mode you should know before your first deploy.

Step 1: the bare repo and post-receive hook

On your server, create a bare git repo and drop a post-receive hook in hooks/. The hook receives your push and decides what happens next. If the script has a syntax error or wrong permissions, git accepts your push silently and deploys nothing, which is the most confusing failure for first-timers. Test the hook manually with echo before wiring up the real build.

Step 2: buildpack detection and the build phase

The hook passes your code to a buildpack, which detects Rails by finding a Gemfile and config/application.rb, then bundles gems and precompiles assets. This is the step that eats time and RAM: a 512MB VPS can get OOM-killed during asset compilation. Set RAILS_ENV=production and a valid SECRET_KEY_BASE before the build or precompile fails mid-deploy. If you'd rather skip this entirely, a managed push-to-deploy option like Omeganodes runs the same buildpack pipeline on EU servers so you push from GitHub without touching hooks.

Step 3: Procfile, release tasks and process types

Your Procfile declares process types: web: bundle exec puma -C config/puma.rb, worker: bundle exec sidekiq. The platform reads it, starts one dyno per line, and routes traffic to web. Release tasks like rails db:migrate run between build and restart. A migration that locks a table while old workers still run is the classic trap: migrate before restart, and keep migrations backwards-compatible for one deploy.

Step 4: restart, rollback and what breaks

Restart means stopping old processes and starting new ones against the new slug, so expect a few seconds of 502s unless your proxy drains connections. Rollback re-points to the previous slug, but it does not reverse your database: if the last release migrated, rolling back the code leaves the schema ahead of it. Keep a rails db:rollback migration handy, or accept that rollback covers code only.

What do you give up by self-hosting instead of using managed Rails hosting?

The ops time you inherit

Running your own platform means you own every failure. When the Docker daemon wedges at 2am or disk fills on your only VPS, you debug it. A solo founder should budget a few hours a week for patching, backups, and monitoring that a managed PaaS does for you.

What no self-hosted setup gives you for free

Managed hosting bundles things you must assemble yourself: managed Postgres with automated backups and failover, autoscaling, DDoS protection, and security patching of the host OS. Heroku's build system also handles buildpacks, Procfile, and release phase commands predictably, as documented in the Heroku Dev Center. Replicating that pipeline on a raw server is real engineering work, not configuration.

Where managed PaaS like Omeganodes still falls short of Heroku

Omeganodes removes the card and ops problems, accepting MTN and Airtel Money with automatic HTTPS on EU servers (terms), but it does not match Heroku's breadth: no managed add-on marketplace, fewer runtime guarantees, and no 100,000-user track record. If you need autoscaling or SOC 2 support today, self-hosting and Omeganodes both fall short of what Heroku offered.

When is self-hosting the wrong choice for a small Rails team?

If payment, not preference, is your constraint

Some developers self-host because they cannot pay a managed provider, not because they want to run servers. That is the wrong reason. If your blocker is a missing USD-billing card, a PaaS that accepts MTN Mobile Money or Airtel Money solves the payment problem directly, and you keep the git push to deploy workflow you wanted from Heroku in the first place. Self-hosting adds a second job you did not ask for.

If your hourly rate exceeds a VPS-plus-your-time

A $5 VPS is cheap until you count the hours spent on upgrades, failed deploys, and 2 a.m. restarts. Freelancers who bill by the hour lose money every time they debug Nginx instead of shipping client work. If uptime for paying customers matters more than learning ops, run a managed PaaS and spend your time on the product. When you do migrate later, plan the database move carefully and test restores first; the Postgres backup documentation covers pg_dump and restore steps.

How do you migrate an existing Heroku Rails app to a self-hosted setup?

Export config vars and database

Start with a full inventory. Run heroku config and copy every variable into your new platform's environment settings, including anything addons injected silently. Dump Postgres with pg_dump in your Heroku maintenance window, then restore it on your own server and run your migrations against the copy before anyone depends on it.

Replace addons one at a time: Redis, background workers, and scheduled jobs each need a self-managed equivalent running beside the app. Test each on the new box before touching DNS.

Cut over the domain without downtime

Deploy the app to your own server first, verify it works on a test domain, then lower the DNS TTL a day ahead of the switch. When you're ready, point the A record at the new server and keep the Heroku app running until the old TTL expires. Automatic HTTPS should issue a certificate on first request; confirm it before dropping the Heroku dynos.

Rollback is your safety net: if the new server misbehaves, flip DNS back to Heroku while it still runs. Only delete the Heroku app after a full week of clean traffic.

FAQ

Do I need Kubernetes to self-host a Heroku alternative?

No. A buildpack-based platform on a single VPS reproduces the git-push workflow without Kubernetes, and a 2 GB server is enough for one small Rails app. Kubernetes adds setup effort and resource overhead that a solo founder rarely needs. Only consider it if you expect to run many apps across multiple servers with strict isolation.

How much RAM does a Rails build actually need?

Plan for at least 2 GB. Compiling gems like nokogiri or precompiling assets can push a 1 GB VPS into OOM kills mid-deploy, and a 512 MB box can be killed during asset compilation. Add swap as a buffer, and treat 4 GB as the realistic floor if you run the platform plus several apps on one machine.

Can I roll back a deploy if something breaks?

Yes, but only the code. Rollback re-points to the previous slug, yet it does not reverse your database, so a migrated schema stays ahead of the rolled-back code. Keep a rails db:rollback migration handy, and keep migrations backwards-compatible for one deploy so old workers survive the restart window.

What do I have to handle myself that Heroku did for me?

You own Postgres with scheduled pg_dump backups (tested restores, not just dumps), automatic HTTPS and certificate renewal, monitoring with disk and memory alerts, OS patching, and the platform itself. Budget a few hours a week for this maintenance, because a failed disk or wedged daemon at 2 a.m. is now your problem.

Deploy at the speed of Africa

World-class hosting, open to every developer, wherever you build and however you pay. Start free in a couple of minutes — no credit card, no lock-in.