Skip to main content

Migrate from Heroku

Migration from one cloud platform to another can be a challenge. This page shows how to smoothly and quickly migrate from Heroku to Divio and how much you can gain from this transition.

Applications deployed on Divio are containerised using Docker. If you use Procfile instead of Docker images on Heroku, the first step is to create a Dockerfile in the repository with your apps. Your Heroku Procfile has a web command that translates into an entrypoint of the new Dockerfile, e.g.

Procfile
release: python manage.py migrate
web: gunicorn my_sample_project.wsgi:application --workers 2

This is how you can define the same in the Dockerfile

Dockerfile
...

EXPOSE 8000
CMD gunicorn my_sample_project.wsgi:application --bind 0.0.0.0:8000 --workers 2

The entire Dockerfile for a Django app with uv could look like this:

Dockerfile
FROM python:3.14-slim

ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1

WORKDIR /app

COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv

COPY pyproject.toml uv.lock ./
RUN uv sync --frozen --no-dev --no-install-project

COPY . .

ENV PATH="/app/.venv/bin:$PATH"

RUN python manage.py collectstatic --noinput

EXPOSE 8000

CMD gunicorn my_sample_project.wsgi:application --bind 0.0.0.0:8000 --workers 2

Docker examples for dozens of other technologies can be found in the Quickstart docs.

Create the Divio application

With a Dockerfile committed to the repository, you're ready to add the new Divio application!

note

Hold off on deploying until the environment variables are in place — otherwise the first build will start with no configuration.

  1. Import the Git repository. In the Control Panel, choose Import from Git and connect the same repository you used on Heroku. Pick a name, slug, and subscription plan to finish creating the app.

  2. Add a database service. A blank Divio app does not include a database by default. Open the Services view of the new application and add a PostgreSQL instance to each environment (e.g. Test and Live), see Services for more details. Once provisioned, Divio automatically exposes a DATABASE_URL environment variable to the app — this replaces the one Heroku used.

  3. Configure release commands. If your Procfile has a release: line (for example python manage.py migrate), add it under release commands on the application's settings page so it runs before each deployment.

  4. Add any add-on services you depended on. If the Heroku app used Redis, object storage, or similar, add the equivalent Divio service now so the matching environment variables exist before the first deploy.

The next two sections cover bringing your data and configuration across. Once environment variables are migrated, trigger the first deployment.

note

Deployment provisions the service and attaches it to the application, so you need to do this before importing the database.

Migrate environment variables

Export Heroku config variables, skipping values that Divio provisions automatically (e.g. DATABASE_URL, REDIS_URL) and Heroku-internal ones:

heroku config -s --app YOUR_HEROKU_APP | grep -vE '^(DATABASE_URL|REDIS_URL|HEROKU_)'

Add the remaining variables to your Divio app from the Env Variables view, then redeploy the environment to apply them.

Import the database

note

Deployment provisions the service and attaches it to the application, so you need to make the first deployment before importing the database.

Put an app into maintenance mode:

heroku maintenance:on --app YOUR_HEROKU_APP

capture a fresh backup:

pg_dump \
--no-owner \
--no-acl \
--exclude-schema=_heroku \
--exclude-extension=pg_stat_statements \
"$(heroku config:get DATABASE_URL -a YOUR_HEROKU_APP)" | \
sed "/^CREATE EVENT TRIGGER/{N;/_heroku\./d}" > latest_dump.sql
Heroku backups

Backups available on Heroku (using heroku pg:backups:download) cannot be used because they include objects from the _heroku management schema and database events relying on them.

Create the local Divio configuration file with the Divio CLI:

divio app configure

and push the dump to a Divio environment:

divio app push db -d latest_dump.sql YOUR_ENVIRONMENT

Replace YOUR_ENVIRONMENT with the target environment (e.g. live). The --binary flag tells the CLI to upload the dump as-is instead of converting it from a plain SQL file. See Interact with the cloud database for more on push/pull options.

Useful Heroku CLI commands

A few Heroku CLI commands that come in handy during migration:

# List all apps deployed on Heroku.
heroku apps

# Put an app into maintenance mode.
heroku maintenance:on --app YOUR_HEROKU_APP

# Stream live logs while validating the new Divio deployment.
heroku logs --tail --app YOUR_HEROKU_APP