Blog Post

Apps on Azure Blog
7 MIN READ

Heroku Entered Maintenance Mode — Here's Your Next Move

simonjj's avatar
simonjj
Icon for Microsoft rankMicrosoft
Mar 19, 2026

A real Node.js + Redis migration in 90 minutes — plus the serverless GPUs and AI-native

Heroku has entered sustaining engineering — no new features, no new enterprise contracts. If you're running production workloads on the platform, you're probably thinking about what comes next.

Azure Container Apps is worth a serious look. Scale-to-zero pricing, event-driven autoscaling, built-in microservice support, serverless GPUs, and an active roadmap — it's a container platform that handles everything from a simple web app to AI-native workloads, and you only pay for what you use.

I migrated a real Heroku app to Container Apps to pressure-test the experience. Here's what I learned, what to watch out for, and how you can do it in an afternoon.

 

Why Container Apps is the natural next chapter

The philosophy carries over directly. Where Heroku had git push, Container Apps has:

az containerapp up --name my-app --source . --environment my-env

One command. If you have a Dockerfile, it builds and deploys your app directly. No local Docker install, no manual registry push — code in, URL out. That part didn't change.

The concept mapping is tight:

HerokuAzure Container Apps
DynoContainer App replica
Procfile process typesSeparate Container Apps
Heroku add-onsAzure managed services
Config varsEnvironment variables + secrets
heroku run one-off dynosContainer Apps Jobs
Heroku PipelinesGitHub Actions
Heroku SchedulerScheduled Container Apps Jobs

Container Apps also includes capabilities you'd need to piece together separately on Heroku — KEDA-powered autoscaling from any event source, Dapr for service-to-service communication, traffic splitting across revisions for safe rollouts, and scale to zero so you stop paying when nothing's running.

Simplest path? If your app is a straightforward web server and you don't want containers at all, Azure App Service (az webapp up) is also available. But for most Heroku workloads — especially anything with workers, background jobs, or variable traffic — Container Apps is the better fit.

 

What a real migration looks like

I took a Node.js + Redis todo app from Heroku and moved it to Container Apps. The app is intentionally boring — Express server, Redis for storage, one web process. This is roughly what a lot of Heroku apps look like, and the migration took about 90 minutes end-to-end (most of that waiting for Redis to provision).

 

Step 1: Export what you have

heroku config --json --app my-heroku-app > heroku-config.json
heroku apps:info --app my-heroku-app
heroku addons --app my-heroku-app

You want three things: your environment variables, your add-on list, and your app metadata. The config export is the most important one — it's every secret and connection string your app needs.

Step 2: Create the Azure backing services

For each Heroku add-on, create the Azure equivalent. Here are the common ones:

Heroku add-onAzure serviceCLI command
Heroku PostgresAzure Database for PostgreSQLaz postgres flexible-server create
Heroku RedisAzure Cache for Redisaz redis create
Heroku SchedulerContainer Apps Jobsaz containerapp job create
SendGridSendGrid via Marketplace(Portal)
Papertrail / LogDNAAzure Monitor + Log Analytics(Enabled by default)

For my todo app, I needed Redis:

az redis create \
  --name my-redis \
  --resource-group my-rg \
  --location swedencentral \
  --sku Basic --vm-size c0

One thing to know: Azure Cache for Redis takes 10–20 minutes to provision. Heroku's Redis add-on takes about two minutes. Budget the time.

Step 3: Containerize

If you don't have a Dockerfile, write one. For a Node app this is about 10 lines:

FROM node:20-slim
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY . .
EXPOSE 8080
CMD ["node", "server.js"]

Don't have a Dockerfile? Point GitHub Copilot at the migration repo and it will generate one for your stack — Node, Python, Ruby, Java, or Go. The repo includes templates and a containerization skill that inspects your app and produces a production-ready Dockerfile.

Step 4: Build, push, deploy

I used Azure Container Registry (ACR) for the build. No local Docker install needed.

az acr create --name myacr --resource-group my-rg --sku Basic
az acr build --registry myacr --image my-app:v1 .

Then create the Container App:

az containerapp create \
  --name my-app \
  --resource-group my-rg \
  --environment my-env \
  --image myacr.azurecr.io/my-app:v1 \
  --registry-server myacr.azurecr.io \
  --target-port 8080 \
  --ingress external \
  --min-replicas 1

Step 5: Wire up the config

This is where Heroku's config:get maps to Container Apps' secrets and environment variables. One gotcha I hit: you have to set secrets before you reference them in environment variables. If you try to do both at once, the deployment fails.

# Set the secret first
az containerapp secret set \
  --name my-app \
  --resource-group my-rg \
  --secrets redis-url="rediss://:ACCESS_KEY@my-redis.redis.cache.windows.net:6380"

# Then reference it
az containerapp update \
  --name my-app \
  --resource-group my-rg \
  --set-env-vars "REDIS_URL=secretref:redis-url"

Step 6: Verify and cut over

Hit the Azure URL, test your routes, check that data flows through the new Redis instance. When you're satisfied, update your DNS CNAME to point at the Container Apps FQDN.

Total time: ~90 minutes, and most of that was waiting for Redis to provision. The actual migration work was about 30 minutes of CLI commands.

 

Lessons from the field

I want to be upfront about what to watch for — these are the things that would waste your time if you hit them unprepared.

📌 Register Azure providers first. If your subscription has never used Container Apps, you need to register the resource providers before creating anything:

az provider register --namespace Microsoft.App --wait
az provider register --namespace Microsoft.OperationalInsights --wait

This takes a minute or two. Without it, resource creation fails with confusing error messages.

📌 Set secrets before referencing them in env vars. The CLI doesn't warn you — it just fails the deployment. Always az containerapp secret set first, then az containerapp update --set-env-vars.

📌 Budget time for Azure resource provisioning. Azure Cache for Redis takes 10–20 minutes vs Heroku's ~2 minutes. Enterprise-grade infrastructure takes a bit longer to spin up — plan accordingly and provision backing services in parallel.

None of these are blockers. They're the kind of things a migration guide should tell you upfront — and ours does.

 

Migrate today, build intelligent apps tomorrow

Once your app is on Container Apps, you're on a platform built for AI-native workloads too. No second migration required:

  • Serverless GPU — attach GPU compute to your Container Apps for inference workloads. Run models alongside your app, same environment, same deployment pipeline. No separate ML infrastructure to manage.
  • Dynamic Sessions — spin up isolated, sandboxed code execution environments on demand. Build AI agents that execute tools, run LLM-generated code safely, or offer interactive coding experiences — all within your existing Container Apps environment.

These aren't separate services you bolt on — they're configuration changes on the platform you're already running on.

Building AI-native? Container Apps pairs naturally with Azure AI Foundry — one place to access state-of-the-art models from both OpenAI and Anthropic, manage prompts, evaluate outputs, and deploy endpoints. Your app runs on Container Apps; your intelligence runs on Foundry. Same subscription, same identity, no glue code between clouds.

The applications being migrated today won't look the same in two years. A platform that grows with you — from web app to intelligent service — means you make this move once.

 

You don't have to figure this out alone

We've built the resources to make this migration fast and repeatable:

  • 📖 Official Migration Guide — End-to-end walkthrough covering assessment, containerization, service mapping, and deployment. Start here.
  • 🤖 Agent-Assisted Migration Repo — An open-source repository designed to work with GitHub Copilot and other AI coding assistants. It includes an AGENTS.md file and six migration skills that walk you through the entire process — from Heroku assessment to DNS cutover — with real CLI commands, Dockerfile templates for five languages, Bicep IaC, and GitHub Actions workflows.

Point Copilot at the repo alongside your app's source code, and it becomes a migration pair-programmer: running the right commands, generating Dockerfiles, setting up CI/CD, and flagging things you might miss. This isn't a magic migrate my app button. It's more like having a colleague who has done this migration twenty times sitting next to you while you do it.

 

The cost math works

Let's talk numbers.

Heroku planMonthly costContainer Apps equivalentMonthly cost
Standard-1X (idle most of the day)$25/moConsumption plan (scale to zero)~$0–5/mo
Performance-L (steady traffic)$500/moDedicated plan with autoscalingMeaningfully less
10 low-traffic apps across dev/staging/prod$250+/moConsumption plan with free grantsNear zero

Container Apps' monthly free grant covers 180,000 vCPU-seconds and 2 million requests. For apps that idle most of the day, that's often enough to pay nothing at all. The biggest savings come from workloads that don't run 24/7. Heroku charges for every hour a dyno is running, period. Container Apps charges for actual compute consumption and scales to zero when there's no traffic.

 

Get started

  1. Inventory — Run heroku apps and heroku addons to see what you have.
  2. Pick a pilot — Choose a non-critical app for your first migration.
  3. Migrate — Follow the official migration guide, or point GitHub Copilot at the migration repo and let it pair with you.

Azure Container Apps gives you a production-grade container platform with scale-to-zero economics, an active roadmap, and a path to AI-native workloads — all from a single az containerapp up command. If you're evaluating what comes after Heroku, start here.

👉 Start your migration · Clone the migration repo · Explore Azure Container Apps

Updated Mar 20, 2026
Version 2.0
No CommentsBe the first to comment