Back to Blog
Guide8 min read2026-05-01

How to Migrate from Heroku: Step-by-Step Guide

A complete step-by-step guide to migrating your apps, databases, and scheduled jobs away from Heroku to a modern cloud PaaS.

How to Migrate from Heroku: Step-by-Step Guide

Heroku's free tier removal changed everything. Thousands of developers suddenly needed a new home for their apps — one that still offered the simple, git-driven workflow they loved, without the runaway pricing of Heroku's paid tiers. This guide walks you through every step of migrating off Heroku, from exporting your database to redeploying your first container.

What You're Actually Migrating

Before you touch a single config file, inventory what you have:

  • Web dynos — your main application process
  • Worker dynos — background job processors
  • Scheduler tasks — recurring cron-style jobs
  • Heroku Postgres — your relational database
  • Config vars — environment variables
  • Buildpacks — your runtime environment

Each of these maps directly to something on a modern PaaS like PandaStack.

Step 1: Export Your PostgreSQL Database from Heroku

Start with data — it's the most critical thing to get right.

# Capture a Heroku Postgres backup
heroku pg:backups:capture --app your-app-name

# Download the latest backup
heroku pg:backups:download --app your-app-name

# This creates latest.dump in your current directory
ls -lh latest.dump

Heroku exports in pg_dump custom format. Keep this file safe — you'll restore it into your new database.

Step 2: Export Your Config Vars

# List all config vars
heroku config --app your-app-name

# Export as shell-compatible format
heroku config --shell --app your-app-name > heroku-env.txt

# Review before using
cat heroku-env.txt

Never commit this file. It contains secrets. Use it only as a reference when configuring your new environment.

Step 3: Containerize Your Application

Heroku used buildpacks to detect your runtime. On PandaStack, you deploy Docker containers. If you don't have a Dockerfile yet, create one now.

For a Node.js app:

FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
EXPOSE 3000
CMD ["node", "src/index.js"]

For a Python app:

FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 8000
CMD ["gunicorn", "app:app", "--bind", "0.0.0.0:8000"]

Test your container locally before deploying:

docker build -t my-app .
docker run -p 3000:3000 --env-file heroku-env.txt my-app
curl http://localhost:3000/health

Step 4: Provision a New PostgreSQL Database on PandaStack

Log into [dashboard.pandastack.io](https://dashboard.pandastack.io), navigate to Databases, and create a new PostgreSQL instance. PandaStack supports PostgreSQL, MySQL, Redis, and MongoDB on its free and paid tiers (paid plans from $12/mo).

Once provisioned, copy the connection string from the dashboard, then restore your Heroku backup:

# Restore the Heroku pg_dump backup into your new PandaStack database
pg_restore   --no-acl   --no-owner   --verbose   -d "postgresql://user:password@host:5432/dbname"   latest.dump

# Verify row counts match
psql "postgresql://user:password@host:5432/dbname"   -c "SELECT schemaname, tablename, n_live_tup FROM pg_stat_user_tables ORDER BY n_live_tup DESC;"

Step 5: Deploy Your Container to PandaStack

Install the CLI and connect your GitHub repository:

npm install -g @pandastack/cli

panda login
panda init

# Link your GitHub repo (PandaStack deploys on every push)
panda deploy --image ghcr.io/your-org/your-app:latest

PandaStack integrates with GitHub only — every push to your configured branch triggers an automatic deploy. Set your environment variables in the dashboard under Settings → Environment Variables, copying them from your heroku-env.txt reference.

Step 6: Migrate Heroku Scheduler Tasks to Cronjobs

Any Heroku Scheduler tasks become PandaStack cronjobs:

# Create a cronjob for a task that ran every hour on Heroku
panda cronjob create   --name cleanup-sessions   --image ghcr.io/your-org/your-app:latest   --schedule "0 * * * *"   --command "node scripts/cleanup.js"

Step 7: DNS Cutover

Once your new deployment is verified and healthy, update your DNS records to point to PandaStack. Do this during a low-traffic window and keep your Heroku app running for at least 24 hours as a fallback until TTLs expire.

Checklist Before You Flip DNS

  • [ ] Database restored and row counts verified
  • [ ] App boots successfully in container
  • [ ] All environment variables set in new dashboard
  • [ ] Health check endpoint returns 200
  • [ ] Cronjobs created and tested
  • [ ] SSL certificate provisioned
  • [ ] Monitoring configured

Migrating from Heroku is a weekend project, not a quarter-long initiative. With a Dockerfile and your database backup in hand, you can be fully migrated in a few hours. Visit [docs.pandastack.io](https://docs.pandastack.io) for platform-specific configuration guides.

Ready to deploy?

Start free on PandaStack — no credit card required.

Start free on PandaStack

More in Guide

Browse all Guide articles →

See also