Migrate from Heroku

Most Heroku apps move to OwnStack with no code changes. Buildpacks work the same; app.json is honored; $PORT is set; DATABASE_URL appears the way you expect. The migration is mostly logistics: copy config, restore data, swap DNS.

What changes, what doesn't

Same as HerokuDifferent on OwnStack
Procfile process types (web, worker, etc.)app.json's formation block is honored as authoritative — see Scaling.
Heroku buildpacks (Ruby, Node, Python, etc.)You own the host; logs, disk, and instance limits are whatever your stack provides.
$PORT binding for web processesAdd-ons are dokku plugins, not Heroku Elements (Postgres, Redis, MySQL, MongoDB are first-class).
DATABASE_URL + REDIS_URL set automaticallySSL is automatic via Let's Encrypt — same idea, different mechanism.
Release tasks via Procfile release:No paid dyno tiers; vertical/horizontal scale is your stack's instance type or count.

Step 1 — Inventory the Heroku app

$ heroku apps:info -a my-heroku-app
$ heroku config -a my-heroku-app -s > heroku-config.env
$ heroku ps -a my-heroku-app

Capture the buildpacks, dyno formation, and add-ons (especially Postgres + Redis plans). The -s flag on heroku config emits a shell-quoted env file you can paste into OwnStack later.

Step 2 — Capture a Postgres dump

$ heroku pg:backups:capture -a my-heroku-app
$ heroku pg:backups:url -a my-heroku-app
https://xfer.heroku.com/...

OwnStack can restore directly from a Heroku backup URL — see Restore.

Step 3 — Generate the app on OwnStack

$ ownstack generate --no-interview my-app buildpack
$ ownstack remote -a my-app
$ ownstack app stacks:add my-app <your-stack>

Step 4 — Push config vars

OwnStack accepts the same Heroku-formatted env file you exported in step 1:

$ ownstack config:push --app=my-app --file=heroku-config.env

Or set vars one at a time with ownstack config:set.

Step 5 — Provision the database, then restore

$ ownstack db create --app=my-app
$ ownstack db restore --app=my-app --url='https://xfer.heroku.com/...'
$ ownstack db restore:info <ID> --follow
Watch for password drift after restore

Heroku Postgres backups via pg_dumpall include ALTER ROLE statements that can desync the postgres password from DATABASE_URL. If your first deploy fails with password authentication failed for user "postgres", see Repair after import.

Step 6 — Deploy

$ ownstack deploy --wait

If the build succeeds and migrations run, you're live on the stack at the auto-generated subdomain.

Step 7 — Swap DNS

Add your custom domain to the OwnStack app and point DNS at the stack:

$ ownstack app domains:add my-app example.com

See Add a custom domain for the DNS records and SSL specifics. Once DNS resolves, Let's Encrypt issues automatically.

Step 8 — Cut over

When you're ready to flip:

  1. Put Heroku into maintenance: heroku maintenance:on -a my-heroku-app.
  2. Take a final Postgres dump and restore on OwnStack (steps 2 + 5 again).
  3. Update DNS to point at OwnStack (step 7).
  4. Wait for DNS propagation (typically < 5 minutes for short TTLs).
  5. Hit your custom domain — it's now served from OwnStack.
  6. Leave Heroku running for a day before deleting; rollback is just flipping DNS back.