Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
GitHub Copilot for Azure plugin providing Azure service management and development assistance inside Claude Code and IDEs.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
references/services/app-service/heroku-to-app-service.md
1# Heroku to Azure App Service Migration23Detailed guidance for migrating Heroku applications to Azure App Service.45## Service Mapping67| Heroku Service | Azure Equivalent |8|---------------|------------------|9| Heroku App | Azure App Service |10| Dynos (Web) | App Service instances |11| Dynos (Worker) | WebJobs (continuous) or Azure Functions |12| Procfile | Startup command / Docker entrypoint |13| Buildpacks | Docker or App Service runtime stacks |14| Config Vars | App Settings / App Configuration / Key Vault |15| Heroku Postgres | Azure Database for PostgreSQL Flexible Server |16| Heroku Redis | Azure Cache for Redis |17| Heroku Kafka | Azure Event Hubs (Kafka-compatible) |18| Add-ons (general) | Azure managed services |19| Heroku Pipelines | GitHub Actions / Azure DevOps |20| Review Apps | Deployment Slots |21| Heroku CI | GitHub Actions |22| Heroku Scheduler | WebJobs (triggered) or Azure Functions Timer |23| Heroku ACM (SSL) | App Service Managed Certificate |24| Custom Domains | App Service Custom Domains |25| Heroku Logs / Logplex | Application Insights / Azure Monitor |26| Heroku Metrics | Azure Monitor Metrics |27| Heroku Connect | Azure Data Factory or Logic Apps |28| Private Spaces | App Service Environment (ASE) |2930## Dyno → App Service Plan Mapping3132| Heroku Dyno Type | App Service Plan | Notes |33|-------------------|------------------|-------|34| Free / Eco | Free (F1) | Dev/test only — F1 has shared compute with quota limits (CPU minutes), not equivalent to Heroku's 60 min/day cap. See [App Service Free SKU limits](https://learn.microsoft.com/azure/app-service/overview-hosting-plans#how-much-do-i-pay-for-the-free-and-shared-tiers) |35| Basic | Basic (B1) | No auto-scale, no slots |36| Standard-1X (512 MB) | Standard (S1) | Auto-scale, slots, custom domains |37| Standard-2X (1 GB) | Standard (S2) | More memory |38| Performance-M (2.5 GB) | Premium v3 (P1v3) | VNet, more instances |39| Performance-L (14 GB) | Premium v3 (P3v3) | High-memory workloads |40| Private-M / Private-L | App Service Environment (ASE) | Network-isolated |4142## Procfile → Startup Configuration4344### Web Process4546| Procfile Entry | Azure Equivalent |47|---------------|------------------|48| `web: node server.js` | Startup command: `node server.js` |49| `web: gunicorn app:app` | Startup command: `gunicorn --bind=0.0.0.0 --timeout 600 app:app` |50| `web: java -jar target/app.jar` | Startup command: `java -jar app.jar` |51| `web: bundle exec puma -C config/puma.rb` | Custom container with Dockerfile |5253### Worker Process5455Heroku worker dynos have no direct App Service equivalent. Migration paths:5657| Heroku Worker Pattern | Azure Equivalent |58|----------------------|------------------|59| `worker: node worker.js` | WebJob (continuous) |60| `worker: celery -A tasks worker` | Container App or AKS |61| `clock: node scheduler.js` | Azure Functions Timer trigger |62| `release: rake db:migrate` | Deployment slot swap scripts |6364## Add-ons → Azure Managed Services6566| Heroku Add-on | Azure Equivalent | Migration Notes |67|--------------|------------------|-----------------|68| Heroku Postgres | PostgreSQL Flexible Server | Use Azure DMS for data migration |69| Heroku Redis | Azure Cache for Redis | Export/import RDB or use replication |70| Heroku Kafka | Azure Event Hubs (Kafka API) | Compatible Kafka protocol |71| Papertrail | Application Insights | Structured logging migration |72| New Relic | Application Insights | APM feature parity |73| SendGrid | Azure Communication Services or SendGrid on Azure | SendGrid available via Azure Marketplace |74| Cloudinary | Azure Blob Storage + CDN | Media storage + delivery |75| Memcachier | Azure Cache for Redis | Redis supports memcache patterns |76| Bonsai (Elasticsearch) | Azure AI Search or Elastic on Azure | Search service migration |77| Heroku Scheduler | Azure Functions Timer trigger | Cron-based scheduling |78| Bucketeer (S3) | Azure Blob Storage | Object storage migration |7980## Config Vars → App Configuration / Key Vault8182| Config Var Type | Azure Target | Implementation |83|----------------|--------------|----------------|84| `DATABASE_URL` | App Setting (managed identity) | Use Entra auth, not connection string |85| `REDIS_URL` | App Setting | Azure Cache connection string or managed identity |86| `SECRET_KEY` | Key Vault reference | `@Microsoft.KeyVault(SecretUri=...)` |87| `API_KEY` (third-party) | Key Vault reference | Store in Key Vault |88| `NODE_ENV` / `RAILS_ENV` | App Setting | Add as a regular App Setting (e.g., `NODE_ENV=production`) — controls runtime behavior. Do NOT confuse with `WEBSITES_NODE_DEFAULT_VERSION`, which controls the Node.js engine version on Windows App Service. |89| `PORT` | Auto-injected | App Service sets `PORT` automatically |90| Feature flags | App Configuration | Feature management support built-in |9192> ⚠️ **Warning:** Heroku's `DATABASE_URL` includes credentials. On Azure, use managed identity authentication instead. Never migrate connection strings with embedded passwords.9394## Buildpacks → Docker9596For apps using standard runtimes, use App Service runtime stacks directly. For custom buildpacks, migrate to Docker:9798| Buildpack Scenario | Azure Approach |99|-------------------|----------------|100| Official Node.js buildpack | App Service Node.js runtime stack |101| Official Python buildpack | App Service Python runtime stack |102| Official Java buildpack | App Service Java runtime stack |103| Multi-buildpack (e.g., Node + Python) | Custom Dockerfile |104| Custom buildpack (apt packages) | Custom Dockerfile |105| Heroku CNB (Cloud Native Buildpack) | Azure Container Apps with CNB |106107## Heroku Pipelines → GitHub Actions108109| Pipeline Feature | Azure Equivalent |110|-----------------|------------------|111| Pipeline stages (dev → staging → prod) | GitHub Actions environments |112| Auto-deploy on push | GitHub Actions `on: push` trigger |113| Review Apps | Deployment slots with PR-based deploy |114| Pipeline promotion | Slot swap (staging → production) |115| Heroku CI test runner | GitHub Actions test job |116| Release phase | Pre-swap slot scripts |117118### Example: GitHub Actions Deployment119120```yaml121name: Deploy to App Service122on:123push:124branches: [main]125jobs:126deploy:127runs-on: ubuntu-latest128permissions:129id-token: write # Required for azure/login@v2 OIDC token request130contents: read # Required to checkout the repo131steps:132- uses: actions/checkout@v4133- uses: azure/login@v2134with:135client-id: ${{ secrets.AZURE_CLIENT_ID }}136tenant-id: ${{ secrets.AZURE_TENANT_ID }}137subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}138- uses: azure/webapps-deploy@v3139with:140app-name: '<app-name>'141slot-name: 'staging'142```143144> ⚠️ Without the `permissions:` block, `azure/login@v2`'s OIDC token request fails with HTTP 403.145146## Review Apps → Deployment Slots147148| Heroku Review Apps | App Service Deployment Slots |149|-------------------|------------------------------|150| Auto-create per PR | Create via GitHub Actions per PR |151| Unique URL per PR | `<app>-<slot>.azurewebsites.net` |152| Auto-destroy on PR close | Delete slot in PR close workflow |153| Shared pipeline config | Slot-specific App Settings |154| `app.json` postdeploy scripts | Slot swap pre/post actions |155156## Reference Links157158- [Heroku to Azure migration guide](https://learn.microsoft.com/en-us/azure/app-service/overview)159- [App Service deployment slots](https://learn.microsoft.com/en-us/azure/app-service/deploy-staging-slots)160- [GitHub Actions for App Service](https://learn.microsoft.com/en-us/azure/app-service/deploy-github-actions)161- [App Service managed identity](https://learn.microsoft.com/en-us/azure/app-service/overview-managed-identity)162