The Problem
My organization wanted to move our self-hosted Metabase instances from Heroku to Metabase Cloud. The catch: Metabase's migration script requires you to be on the latest version first, and our instance was significantly out of date. That dependency turned a simple migration into a multi-step detour.
The Game Plan
The first instinct was to use Heroku buildpacks to upgrade the instance directly on Heroku:
heroku login
cd metabase
heroku buildpacks:set https://github.com/metabase/metabase-buildpack -a metabase
git commit --allow-empty -m "Trigger rebuild"
git push heroku masterThis got us from v0.41.4 to v0.45.3 — but the latest version at the time was v0.48.8. Worse, Heroku itself was now a dead end:
"Starting with this release, Metabase 0.45 — Heroku support is now deprecated."
Further upgrades on Heroku were no longer possible.
The Revised Game Plan
With Heroku out of the picture, the new approach had three steps:
- Back up the Metabase database from Heroku
- Restore it into a fresh PostgreSQL container on an EC2 instance running the latest Metabase via Docker
- Run Metabase Cloud's migration script against the EC2 instance
Step 1 — Back Up the Heroku Database
# Create a backup of the Metabase instance on Heroku
heroku pg:backups:capture --app metabase-app
# Download the backup locally
heroku pg:backups:download --app metabase-app
# List all backups for the app
heroku pg:backups --app metabase-app
# Get details about a specific backup
heroku pg:backups:info b017 --app metabase-app
# --- Extras ---
# View the backup schedule
heroku pg:backups:schedules --app metabase-app
# Set an automated backup schedule
heroku pg:backups:schedule DATABASE_URL --at '02:00 America/Los_Angeles' --app metabase-app
# Restore a specific backup
heroku pg:backups:restore b101 DATABASE_URL --app metabase-appStep 2 — Set Up PostgreSQL on EC2
SSH into your EC2 instance, then install the Heroku CLI and restore the backup into a Docker-managed Postgres container:
# Install Heroku CLI on EC2
curl https://cli-assets.heroku.com/install.sh | sh
heroku login -i
# Copy the Postgres backup from your local machine to EC2
scp metabase-app.dump user@remote_host:/path/to/destination/
# Pull and run a Postgres container
docker pull postgres
docker run --name postgres_container -e POSTGRES_PASSWORD=YOUR_PASSWORD -d postgres
# Copy the dump file into the container
docker cp metabase-app.dump postgres_container:/
# Shell into the container
docker exec -it postgres_container bash
# Create the target database and restore
psql -U postgres -c "CREATE DATABASE metabasedb;"
pg_restore -U postgres -d metabasedb -O /metabase-app.dumpStep 3 — Launch Metabase on Docker
Point Metabase at the restored Postgres database:
sudo docker run -d -p 3000:3000 \
-e "MB_DB_TYPE=postgres" \
-e "MB_DB_DBNAME=yourdbname" \
-e "MB_DB_PORT=5432" \
-e "MB_DB_USER=yourusername" \
-e "MB_DB_PASS=yourpassword" \
-e "MB_DB_HOST=yourdbhost" \
metabase/metabaseThe Final Touches
Once the container is running, verify the version by navigating to http://<your-ec2-instance-public-ip>:3000 and going to Settings → Admin. You should see v0.48.x (or whatever the current latest is).
From there, download and run Metabase Cloud's migration script against the EC2 instance. The script handles the rest — and once it's done, you're fully on managed hosting with no more Heroku maintenance to worry about.