Migrate from Heroku¶
PaaS Runtime is a Heroku-compatible platform — most Heroku apps migrate in under an hour. This recipe walks through every step.
Overview¶
The platforms share their core mental model (apps, dynos/processes, addons, config vars, releases, Procfile, buildpacks) so the surface mapping is mechanical:
| Heroku command | PaaS Runtime equivalent |
|---|---|
heroku login |
paas login |
heroku apps:create my-app |
paas apps create my-app |
heroku git:remote -a my-app |
paas apps:remote my-app (auto on create) |
heroku config:set KEY=val |
paas config:set KEY=val |
heroku config:set --app my-app KEY=val |
paas config:set KEY=val --app my-app |
heroku addons:create heroku-postgresql:standard-0 |
paas addons:create database:standard |
heroku addons:create heroku-redis:premium-0 |
paas addons:create valkey:standard |
heroku ps:scale web=3 worker=2 |
paas ps:scale web=3 worker=2 |
heroku logs --tail |
paas logs --tail |
heroku run bash |
paas run -- bash |
heroku domains:add www.example.com |
paas domains:add www.example.com |
heroku certs:auto:enable |
TLS is auto-enabled (cert-manager + Let's Encrypt) |
heroku releases |
paas releases |
heroku rollback v42 |
paas releases:rollback v42 |
heroku ps:exec |
paas shell (interactive WebSocket) |
heroku pipelines:promote |
git push paas main from staging branch |
Procfile compatibility¶
Your existing Procfile works as-is:
web: bundle exec puma -p $PORT
worker: bundle exec sidekiq
release: bundle exec rails db:migrate
clock: bundle exec clockwork lib/clock.rb
PaaS recognizes the same process types (web, worker, release, plus the cron-* family for scheduled jobs). The $PORT env var is injected identically.
Add-ons mapping¶
Heroku Postgres → PaaS PostgreSQL (CNPG)¶
| Heroku plan | PaaS plan | Memory | HA | Backups |
|---|---|---|---|---|
| Hobby Dev (free) | free |
256Mi | none | none |
| Hobby Basic | starter |
512Mi | none | nightly |
| Standard 0 | standard |
1Gi | primary + replica | WAL stream + nightly |
| Premium 0 | pro |
4Gi | primary + 2 replicas | WAL + cross-region |
Migrate your data with pg_dump / pg_restore:
# 1. Dump from Heroku
heroku pg:backups:capture
heroku pg:backups:download -o heroku.dump
# 2. Restore into PaaS
DATABASE_URL=$(paas addons:credentials db --raw)
pg_restore --no-owner --clean --no-acl --dbname="$DATABASE_URL" heroku.dump
Heroku Redis → PaaS Valkey¶
Valkey is wire-compatible with Redis 7. REDIS_URL is injected; rename to VALKEY_URL if needed:
Heroku Scheduler → cron processes¶
Heroku Scheduler jobs become entries in paas.toml:
[cron]
nightly_report = { schedule = "0 2 * * *", command = "rake report:nightly" }
hourly_sync = { schedule = "0 * * * *", command = "rake sync" }
Each entry becomes a Kubernetes CronJob in your tenant namespace.
Step-by-step migration¶
1. Authenticate¶
2. Create the app¶
3. Push your code¶
The Paketo buildpack picks up the same project (Gemfile, package.json, requirements.txt, etc.) Heroku used. First build is slower (~60–120s); subsequent pushes use cached layers.
4. Set environment variables¶
Bulk-import from your Heroku app:
heroku config --app my-heroku-app -s > heroku.env
# Inspect heroku.env, strip Heroku-specific vars (PORT, DYNO, etc.)
paas config:import heroku.env
Or set individually:
5. Add add-ons¶
paas addons:create database --type postgres --plan standard --name db
paas addons:create cache --type valkey --plan starter --name cache
A new release is triggered on each addon attach (env vars injected). Verify via paas config.
6. Verify¶
paas logs --tail # watch the rollout
curl https://my-app.runtime.di2amp.com/healthz
paas releases # confirm the new release is `active`
Heroku buildpacks compatibility¶
PaaS uses Paketo Cloud Native Buildpacks, an OCI-compliant evolution of the Heroku Buildpacks line. The CNB spec is identical, so language detection and configuration env vars carry over:
BP_NODE_VERSION=20(wasNODE_VERSIONon Heroku)BP_PHP_VERSION=8.3(wasPHP_VERSION)BP_GO_VERSION=1.22(wasGOOSE_VERSION)
Custom buildpacks declared in app.json buildpacks field require a manual port — the spec moved from heroku-buildpack (HBP) to CNB. Most major buildpacks have CNB equivalents.
Caveats¶
- Heroku regions (
us,eu) → PaaS regions (fr-par-1,fr-par-2,de-fra-1). Pick the closest in[app] region = "...". - Free tier limits are similar but not identical (PaaS: 30 min sleep, 512Mi RAM, 0.1 CPU shared).
- Heroku Connect (Salesforce sync) has no PaaS equivalent — use the Salesforce REST API directly.