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 Heroku | Different 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 processes | Add-ons are dokku plugins, not Heroku Elements (Postgres, Redis, MySQL, MongoDB are first-class). |
DATABASE_URL + REDIS_URL set automatically | SSL 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
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:
- Put Heroku into maintenance:
heroku maintenance:on -a my-heroku-app. - Take a final Postgres dump and restore on OwnStack (steps 2 + 5 again).
- Update DNS to point at OwnStack (step 7).
- Wait for DNS propagation (typically < 5 minutes for short TTLs).
- Hit your custom domain — it's now served from OwnStack.
- Leave Heroku running for a day before deleting; rollback is just flipping DNS back.