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.
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
...
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:
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!
Hold off on deploying until the environment variables are in place — otherwise the first build will start with no configuration.
-
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.
-
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_URLenvironment variable to the app — this replaces the one Heroku used. -
Configure release commands. If your
Procfilehas arelease:line (for examplepython manage.py migrate), add it under release commands on the application's settings page so it runs before each deployment. -
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.
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
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
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