Skip to content
dply/edge

Guides

Migrate from Heroku

Move a Heroku app to dply: keep your Procfile, copy config vars, replace add-ons with dply resources, move the database, and switch the domain.

This guide is for apps that run on Heroku dynos today: Rails, Node, Python, PHP, Go, Java and the other stacks Heroku buildpacks build. On dply they run as container apps that sleep when idle, with managed databases and Valkey attached as resources. Your Procfile keeps working, so most apps move without code changes.

How the pieces map

Heroku dply
App A container app
Buildpacks A generated image for the detected stack, or your own Dockerfile (Frameworks & runtimes)
Procfile web The app's start command (Procfile)
Procfile release The release command: runs before the new version takes traffic
Procfile worker Queue workers (Queue workers)
Dynos and dyno types Instances and instance size (Scaling & sleep)
Eco dynos sleeping Sleeps after: idle instances sleep and wake on the next request
Config vars Environment (Environment variables)
Heroku Postgres dply Postgres (Postgres, MySQL & MongoDB)
Heroku Data for Redis dply Valkey (Valkey (Redis))
Other add-ons A dply resource where one exists; otherwise keep the provider and copy its variables
Heroku Scheduler A Scheduled task (Scheduled tasks)
heroku run The app's Console, or dply-edge ssh from the CLI
Review apps Preview deployments
*.herokuapp.com The app's *.on-dply.live hostname (Domains)
heroku releases:rollback Roll back (Deployments)
Aptfile Not read. List the packages under container.packages in dply.yaml (OS packages)

Differences to plan for

  • web must listen on $PORT. dply sets PORT (8080 for generated images), as Heroku does.
  • PHP apps ignore web. dply runs the PHP server itself, so heroku-php-apache2 and heroku-php-nginx lines are skipped. See Deploy a Laravel app.
  • Workers start when you add them. A worker: line is only offered as the workers' command; nothing runs until you add queue workers.
  • No persistent disk. As on Heroku, the filesystem resets on restart. Keep uploads in object storage.

1. Deploy the app

  1. Choose New app, connect your source control, and select the repository and branch Heroku deploys.
  2. Check that dply detects the stack and shows App, then choose Deploy.

The build log shows [Procfile] release: … when it picks up your release command.

2. Copy config vars

Export them in .env format:

bash
heroku config -s -a your-app > heroku.env

Delete the lines dply sets for you from the resources you attach next, such as DATABASE_URL and REDIS_URL, and Heroku-only values. Then paste the rest into Environment, or push the file with the CLI:

bash
dply-edge env push --file heroku.env

Warning

env push replaces every variable on the app with the file's contents. Run it before you add variables by hand.

3. Attach resources

On the app's Overview, choose Add resource and add a Database (Postgres), dply Valkey for Redis, and Queue workers if your Procfile has a worker line. In the workers' settings, choose Use Procfile: worker (…) to use that command. Redeploy so the app receives the new variables.

4. Move the database

  1. Put the Heroku app in maintenance mode: heroku maintenance:on -a your-app.

  2. Capture a backup and download it. Heroku backups are pg_dump -Fc files:

    bash
    heroku pg:backups:capture -a your-app
    curl -o app.dump "$(heroku pg:backups:url -a your-app)"
    
  3. Open the database from the app's Overview. Under Export and import, choose Get upload command, run it where app.dump is, then choose Load it.

See Postgres, MySQL & MongoDB.

5. Switch the domain

  1. Check the app on its on-dply.live address.
  2. Add the domain under Routing, Domains.
  3. Lower the TTL on the existing record, then point it at the CNAME target dply shows instead of the Heroku DNS target.
  4. Choose Verify DNS and wait for TLS to be active.
  5. Remove the domain from Heroku, then scale the Heroku dynos to zero.

See Domains.

Next steps

View as Markdown llms.txt

dply/edge