Heroku to SnapDeploy Migration: A Step-by-Step Guide
Heroku removed its free tier on November 28, 2022. Overnight, hundreds of thousands of hobby apps went offline. The platform that once had 13 million accounts lost the hobbyist and student demographic almost entirely — while Eco dynos ($5/month for a shared 1,000-hour pool) still sleep after 30 minutes and take 15-30 seconds to wake up.
If you're still on Heroku paying $5-25/month for a single dyno, or if you left and haven't found a permanent home yet, this guide walks you through a complete migration to SnapDeploy — with real Procfile-to-Dockerfile conversions, actual CLI commands, and an honest cost comparison.
What You're Leaving Behind (and What You're Not)
Here's what Heroku costs in 2026 for a typical small app:
| Component | Heroku Plan | Monthly Cost |
|---|---|---|
| Web dyno (always-on) | Basic | $7 |
| Postgres database | Essential-0 (1 GB, 20 conn) | $5 |
| Redis cache | Mini (25 MB, 20 conn) | $3 |
| Logging | Papertrail (free tier) | $0 |
| Total | $15/month ($180/year) |
Need more power? A Standard-1x dyno ($25/mo) with Standard-0 Postgres ($50/mo) puts you at $75/month before you've added Redis or a worker dyno. And Heroku's Performance-M dyno is $250/month — for 2.5 GB RAM.
Step 1: Export Everything from Heroku
Before touching SnapDeploy, extract your Heroku configuration and data:
Export Environment Variables
# Export all config vars to a .env file
heroku config -s --app your-app-name > .env
# Review what you exported (remove Heroku-specific vars)
cat .env
# Remove these Heroku-specific vars — they won't work on SnapDeploy:
# DATABASE_URL (will use SnapDeploy's managed database instead)
# HEROKU_SLUG_COMMIT, HEROKU_SLUG_DESCRIPTION
# PAPERTRAIL_API_TOKEN (SnapDeploy has built-in logging)
Export Your Database
# Capture a fresh backup
heroku pg:backups:capture --app your-app-name
# Download the backup locally
heroku pg:backups:download --app your-app-name
# This creates a file called "latest.dump"
# If you need a SQL file instead:
pg_restore --verbose --no-acl --no-owner -f dump.sql latest.dump
Step 2: Convert Your Procfile to a Dockerfile
Heroku uses Procfiles and buildpacks. SnapDeploy uses Dockerfiles — and will auto-generate one if you don't have one. But if you want full control, here are the conversions for the four most common stacks:
Node.js (Express)
Heroku Procfile: web: node server.js
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --production
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]
Python (Flask / Django)
Heroku Procfile: web: gunicorn app: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", "--bind", "0.0.0.0:8000", "app:app"]
Java (Spring Boot)
Heroku Procfile: web: java -jar target/*.jar
FROM eclipse-temurin:17-jdk-alpine AS build
WORKDIR /app
COPY . .
RUN ./mvnw package -DskipTests
FROM eclipse-temurin:17-jre-alpine
WORKDIR /app
COPY --from=build /app/target/*.jar app.jar
EXPOSE 8080
CMD ["java", "-jar", "app.jar"]
Ruby (Rails)
Heroku Procfile: web: bundle exec puma
FROM ruby:3.3-slim
WORKDIR /app
COPY Gemfile Gemfile.lock ./
RUN bundle install --without development test
COPY . .
EXPOSE 3000
CMD ["bundle", "exec", "puma", "-C", "config/puma.rb"]
Important port note: Heroku dynamically assigns $PORT (usually 80). In your Dockerfile, bind to a specific port (3000, 8000, 8080) and SnapDeploy will auto-detect the correct port from your framework. If auto-detection gets it wrong, you can override it in the dashboard.
Step 3: Deploy on SnapDeploy
Once your code is on GitHub with a Dockerfile (or without — SnapDeploy auto-generates one):
- Sign up at snapdeploy.dev — no credit card required.
- Connect GitHub — Install the SnapDeploy GitHub App on your repository.
- Create a container — Name it, select your repo and branch (usually
main). - Add environment variables — Paste the vars from your
.envexport. SnapDeploy encrypts them at rest. - Deploy — Build takes 2-3 minutes. Your app gets a
your-app.snapdeploy.devsubdomain with free SSL. - Enable auto-deploy — Every push to your branch triggers a new build automatically.
Step 4: Migrate Your Database
SnapDeploy offers managed database add-ons (PostgreSQL, MySQL, MongoDB) directly from the dashboard. To import your Heroku Postgres data:
# 1. Create a PostgreSQL add-on in SnapDeploy dashboard
# You'll get a connection string like:
# postgresql://user:[email protected]:5432/dbname
# 2. Restore your Heroku backup to the new database
pg_restore --verbose --no-acl --no-owner \
-d "postgresql://user:[email protected]:5432/dbname" \
latest.dump
# 3. Update your app's DATABASE_URL environment variable
# in the SnapDeploy dashboard to point to the new database
Cost Comparison: Heroku vs SnapDeploy
| Scenario | Heroku | SnapDeploy | Annual Savings |
|---|---|---|---|
| Side project (sleep OK) | $5/mo Eco (sleeps after 30 min, shared 1000 hr pool) | $0 (sleeps after 15 min, ~60s wake) | $60/year |
| Small API (always-on, 512 MB) | $7/mo Basic dyno | $12/mo Always-On | -$60/year (Heroku cheaper) |
| Production app (1 GB, always-on) | $25/mo Standard-1x | $25/mo Always-On | $0 (same price, better isolation) |
| Production app + Postgres + Redis | $25 + $50 + $15 = $90/mo | $25/mo + managed add-ons | Varies by add-on tier |
| High-memory app (2.5 GB) | $250/mo Performance-M | $45/mo Always-On (4 GB) | $2,460/year |
Honest take: At the 512 MB tier, Heroku's $7/mo Basic dyno is cheaper than SnapDeploy's $12/mo. But Heroku's Basic dynos have no horizontal scaling, no preboot, and no metrics. SnapDeploy gives you AWS Fargate isolation, real-time CPU/memory monitoring, and auto-deploy from GitHub at every tier. The value gap widens significantly at 1 GB+ where Heroku's pricing escalates fast.
Common Migration Issues (and Fixes)
1. Port binding errors
Heroku injects $PORT automatically. If your app reads process.env.PORT, set the PORT environment variable in SnapDeploy (e.g., PORT=3000) or update your code to use a hardcoded port that matches your Dockerfile's EXPOSE.
2. Buildpack-specific behavior
Heroku buildpacks sometimes run post-compile scripts or inject environment variables. If your app depends on DYNO, STACK, or buildpack-specific hooks, remove those references. Docker gives you full control over the build process.
3. File system differences
Heroku has an ephemeral filesystem that resets on every deploy. SnapDeploy containers also have ephemeral storage, but you can use S3 or managed databases for persistent data — just like you should on Heroku.
4. Custom domains
On Heroku, custom domains require paid dynos and ACM certificates. On SnapDeploy, custom domains are unlimited and free on Always-On containers — add a CNAME record pointing to proxy.snapdeploy.dev and SSL is provisioned automatically via Let's Encrypt.
What You Gain After Migration
- Container isolation: Each app runs in its own AWS Fargate task — no shared dynos, no noisy neighbors.
- Free tier that stays free: Up to 4 containers with auto-sleep/wake, no credit card, 10 free deploys per day.
- GPU compute: Heroku has no GPU option. SnapDeploy offers Tesla T4 (16 GB VRAM) at $0.50/hour for AI/ML workloads.
- Real-time monitoring: CPU, memory, and deployment logs in the dashboard — no addon required.
- Security scanning: Automated vulnerability scanning with Trivy, Semgrep, OWASP Dependency Check, and Gitleaks — built into the platform.
- Auto-deploy on push: Push to your branch, SnapDeploy builds and deploys automatically. No Heroku CLI needed.
Get DevOps Tips & Updates
Container deployment guides, platform updates, and DevOps best practices. No spam.
Unsubscribe anytime. We respect your privacy.