Migrate from Heroku to DigitalOcean App Platform

Validated on 9 Feb 2026 • Last edited on 9 Feb 2026

App Platform is a fully managed Platform-as-a-Service (PaaS) that deploys applications from Git repositories or container images. It automatically builds, deploys, and scales components while handling all underlying infrastructure.

This guide walks you through migrating your Heroku-hosted applications and datastores to DigitalOcean App Platform.

You’ll learn:

  • How Heroku concepts map to DigitalOcean App Platform
  • How to model a Heroku app as one or more App Platform components
  • How to migrate your databases to DigitalOcean Managed Databases
  • How to cut over DNS and finalize your migration

Why Migrate?

DigitalOcean App Platform offers a compelling alternative to Heroku, particularly as your application scales and your infrastructure needs evolve.

Key advantages:

  • Cost savings: Granular instance sizes from 512 MB to 32 GB of RAM at significantly lower price points.

  • Flexible scaling: Autoscaling with granular plan sizes, so scaling past 2.5 GB does not require moving directly to 14 GB.

  • Growth path beyond PaaS: Grow your application into DigitalOcean’s broader ecosystem with Managed Kubernetes, Spaces Object Storage, Gradient, Droplets, and more.

  • Free support for all users: Transparent, accessible support with clear upgrade paths and no enterprise sales process required.

  • Modern developer experience: Implement your infrastructure-as-code via App Spec (YAML), integrate with GitHub/GitLab/Bitbucket, auto-deploy on push, rollback when needed, and aggregate your monitoring with built-in log forwarding and health checks.

  • Dedicated IP addresses: Take advantage of free static IP addresses for each of your applications to make accessing your application straightforward and reliable.

Concept Mapping

Most Heroku concepts map cleanly to equivalent functionality on DigitalOcean App Platform. Use this table as a quick reference throughout your migration:

Heroku DigitalOcean App Platform
App App
web process (Procfile) Service (Web Service component)
worker / non-web process Worker component
release phase Job (PRE_DEPLOY kind)
Heroku Scheduler / clock process Job (SCHEDULED kind, cron expression)
Config Vars Environment Variables / App-Level Env Vars
Dyno Container instance
Dyno type (Eco, Basic, Standard, etc.) Instance size (Basic, Professional, etc.)
Heroku Postgres DigitalOcean Managed PostgreSQL
Heroku Key-Value Store (Redis) DigitalOcean Managed Redis / Valkey
Heroku Add-ons DigitalOcean Marketplace / external services
Pipelines (review, staging, prod) App-level environments / Deploy to DO Button
Procfile App Spec (YAML) + Build/Run commands
Buildpacks Cloud-Native Buildpacks (auto-detected)
heroku.yml / Docker deploys Dockerfile-based builds
Custom domains + ACM Custom domains + auto-managed TLS certs
Heroku CLI (heroku) DigitalOcean CLI (doctl)

Step 1: Prepare to Migrate

Before making any changes, take inventory of your Heroku resources and set up your DigitalOcean account.

Create Your DigitalOcean Account

Sign up at cloud.digitalocean.com if you haven’t already, then install and configure the DigitalOcean CLI (doctl) to manage resources from your terminal.

Authenticate with doctl to log in to your account:

doctl auth init

Then validate that doctl is working:

doctl account get

Read How to Install and Configure doctl for more help with setting up doctl.

Catalog Your Heroku Resources

Identify each Heroku app you want to migrate. For each app, note the following:

  • Procfile processes: web, worker, release, clock, and any other processes defined

  • Config Vars: All environment variables (especially DATABASE_URL, REDIS_URL, and API keys)

  • Add-ons: Heroku Postgres, Heroku Key-Value Store (Redis), and any third-party add-ons

  • Custom domains: Any custom domains and their DNS configuration

  • Buildpacks: Which language buildpacks your app uses

Tip
Many third-party add-ons still work after migration. If you’re using add-ons like SendGrid, Papertrail, or New Relic via API keys and environment variables, you can continue using them on DigitalOcean by copying over the relevant config vars as environment variables.

Step 2: Create Your Datastores

Create your DigitalOcean Managed Database clusters before deploying your app. This way, your services can connect on their first deployment.

Note
We won’t move your data yet. At this stage we are only provisioning empty databases. Data migration happens in Step 4 during the final cutover.

Provision a Managed PostgreSQL Database

  1. In the DigitalOcean Control Panel, click on the Create menu, then click Databases.

  2. Select PostgreSQL as the database engine.

  3. Choose a region (select the same region you plan to deploy your app in for lowest latency).

  4. Select an instance size and storage amount. Start small for testing as you can scale up before the final migration.

  5. Click Create Database Cluster. Provisioning takes a few minutes.

  6. Once ready, navigate to the database’s Connection Details tab. Copy the connection string to add it to your app’s environment variables in the following step.

Provision a Managed Valkey (Redis) Instance

If your Heroku app uses Heroku Key-Value Store (Redis), follow the same process but select Valkey as the database engine. Copy the connection string for use as your REDIS_URL environment variable.

Tip

DigitalOcean Managed Databases support private networking via VPC. When your App Platform app is in the same region as your database, traffic stays on the private network which is faster and more secure. To take full advantage of this feature, select the VPC network option in your database’s Connection Details panel to grab the private network connection string.

Read the Postgres and Valkey best practices documentation for more information about using VPCs with managed databases.

Step 3: Recreate Your App on App Platform

Now we’ll create the App Platform resources that correspond to your Heroku app’s processes.

Understanding Your Procfile

Most Heroku apps define a Procfile in the repo root. The following code listing shows an example Node.js Procfile and how each process maps to App Platform:

# Procfile
web: npm run start
worker: npm run worker
release: db-migrate -e prod up
Procfile Entry App Platform Component Notes
web Service (Web Service) Receives HTTP traffic, gets a public URL
worker Worker Background processing, not internet-accessible
release Job (PRE_DEPLOY) Runs before each deploy (for example, DB migrations)

Create a Web Service

  1. In the DigitalOcean Control Panel, click Create → Apps.

  2. Connect your GitHub, GitLab, or Bitbucket repository and select the branch to deploy.

  3. App Platform auto-detects your language. Confirm the Resource Type is set to Web Service.

  4. Configure your Build Command (npm install, for example) and Run Command (npm run start).

  5. Select your Instance Size and Region (match your database region).

  6. Add Environment Variables: copy over your Heroku config vars. Set DATABASE_URL to your DigitalOcean database connection string.

  7. Click Next and review your configuration, then Create Resources.

Add Worker Components

For each non-web process in your Procfile, add a Worker component to the same app:

  1. From your app’s dashboard, click Create → Create Resources from Source Code.

  2. Select the same repository and branch.

  3. Change the Resource Type to Worker.

  4. Set the Run Command to your worker’s start command (for example npm run worker).

  5. Configure environment variables as needed, then save.

Add a Pre-Deploy Job (Release Phase)

To replicate Heroku’s release phase, add a Job component:

  1. From your app’s dashboard, click Create → Create Resources from Source Code.

  2. Select the same repository and branch.

  3. Change the Resource Type to Job.

  4. Set the Kind to Pre-Deploy. This ensures the job runs before each deploy and blocks deployment if it fails, the same as Heroku’s release phase.

  5. Set the Run Command to your migration command (for example db-migrate -e prod up).

Tip
If you use Heroku Scheduler or clock processes, create a Job with Kind set to “Scheduled” and provide a cron expression (such as 0 */6 * * * for every 6 hours). This runs directly on App Platform with no external scheduler needed.

For infrastructure-as-code workflows, you can define your entire app in a single YAML file and deploy it using doctl. This is the App Platform equivalent of combining your Procfile + app.json into one declarative specification.

Example App Spec translating the example Procfile

name: my-app
region: nyc
services:
  - name: web
    github:
      repo: your-org/your-repo
      branch: main
    build_command: npm install
    run_command: npm run start
    http_port: 8080
    instance_size_slug: basic-xxs
    instance_count: 1
    envs:
      - key: DATABASE_URL
        scope: RUN_TIME
        value: "${db.DATABASE_URL}"
workers:
  - name: background-worker
    github:
      repo: your-org/your-repo
      branch: main
    build_command: npm install
    run_command: npm run worker
    instance_size_slug: basic-xxs
jobs:
  - name: db-migrate
    github:
      repo: your-org/your-repo
      branch: main
    build_command: npm install
    run_command: db-migrate -e prod up
    kind: PRE_DEPLOY
    instance_size_slug: basic-xxs
databases:
  - name: db
    engine: PG
    production: true
    cluster_name: my-db-cluster

Deploy with a single doctl command:

doctl apps create --spec app-spec.yaml
Tip

To update existing apps from App Spec YAML, use the following doctl command:

doctl apps update <your-app-id> --spec app-spec.yaml

Set Environment Variables

App Platform environment variables work similarly to Heroku config vars. A few things to note:

  • Component-level vs. App-level: Environment variables can be scoped to individual components or shared across all components in an app.

  • Bindable variables: When you attach a DigitalOcean Managed Database to your app, App Platform provides bindable variables (like ${db.DATABASE_URL}) that automatically contain your connection details.

  • Build vs. Runtime scope: You can specify whether a variable is available at build time, runtime, or both.

  • Encryption: Select Encrypt for sensitive values to store them securely. Encrypted variables cannot be read back from the dashboard.

Step 4: Migrate Data and Cut Over

With your App Platform app running and connected to its new (empty) databases, it’s time to move your production data and switch traffic over.

Warning
This final migration step requires downtime for your application. Schedule the cutover for off-peak hours to minimize impact on your users.

Scale Up Your DigitalOcean Databases

Before importing data, ensure your DigitalOcean databases have enough storage and compute for your production workload. You can resize database clusters in the Control Panel at any time. To prepare for production workloads, we strongly recommend taking this time to add at least one standby node to gain automatic failover. Refer to the How to Add Standby Nodes guides (for Postgres and for Valkey).

Enable Maintenance Mode on Heroku

Put your Heroku app into maintenance mode so no new writes occur during migration:

heroku maintenance:on --app <YOUR_HEROKU_APP_NAME>
Tip
For databases larger than 1 TB, please reach out to DigitalOcean’s Migration program. Migrations of larger databases can take a long time and may need special attention and planning which DigitalOcean’s experts can help you evaluate and plan for.

Migrate Your Database into DigitalOcean Managed Database

DigitalOcean provides automated migration tools accessible from your DigitalOcean Databases panel or from our API. Our tool brings your data to DigitalOcean and keeps it in sync (for up to two weeks) with your source datastore, letting you choose when you are prepared to cutover.

  1. How to Migrate PostgreSQL Databases to DigitalOcean using Continuous Migration
  2. How to Migrate Valkey Databases to DigitalOcean

Verify Your Application

Before switching DNS, verify that everything works correctly on your App Platform deployment:

  • Visit your app’s auto-assigned .ondigitalocean.app URL

  • Test critical user flows and API endpoints

  • Verify database connectivity and data integrity

  • Check that background workers are processing jobs correctly

  • Review application logs in the App Platform dashboard

Update Your DNS Records

If your Heroku app uses a custom domain, add it to your App Platform app in the Control Panel under the Domains tab. Then update your DNS records to point to DigitalOcean instead of Heroku:

  • For apex domains: Add an A record pointing to the IP provided by App Platform.

  • For subdomains: Add a CNAME record pointing to your app’s .ondigitalocean.app hostname.

App Platform automatically provisions and manages TLS certificates for your custom domains. DNS propagation typically takes a few minutes to a few hours.

Migrate CDN Traffic

If your Heroku application uses a CDN (commonly via add-ons such as Expedited CDN or similar reverse-proxy CDNs), this functionality does not migrate automatically. You must explicitly reconfigure CDN delivery when cutting over to DigitalOcean.

Remove Heroku CDN Dependencies

Before cutover:

  • Disable or remove any Heroku CDN add-ons.
  • Remove any CDN-specific configuration that assumes Heroku headers, hostnames, or proxy behavior.
  • Confirm your application serves correct cache headers (Cache-Control, ETag, Last-Modified) for static assets.

Verify CDN Behavior on App Platform

After deploying your app to App Platform:

  • Access the default *.ondigitalocean.app URL.
  • Confirm that static assets are being served correctly.
  • Inspect response headers to ensure assets are cacheable.

App Platform respects standard HTTP caching headers. If assets are not cached, review your application or framework configuration.

Next Steps

After you’ve successfully migrated from Heroku to DigitalOcean App Platform, explore some other capabilities of the DigitalOcean platform:

  • Autoscaling: Configure horizontal autoscaling based on CPU or HTTP request metrics to handle traffic spikes automatically.

  • Log forwarding: Stream application logs to Papertrail, Datadog, Logtail, or your own OpenSearch cluster.

  • Alerts and monitoring: Set up alert policies for deployment failures, resource usage thresholds, and health check failures.

  • Rollbacks: Instantly roll back to a previous deployment if issues arise.

  • App Spec in CI/CD: Commit your app spec YAML to your repo and use doctl in your CI pipeline for GitOps-style deployments.

  • Managed Kubernetes: When you need more control, DigitalOcean Kubernetes (DOKS) provides a natural next step, no vendor change required.

  • DigitalOcean MCP Server: Integrate AI-powered coding assistants like Claude Code directly with App Platform for streamlined development workflows.

Get Support

If you need help with your migration, DigitalOcean offers several support channels:

We can't find any results for your search.

Try using different keywords or simplifying your search terms.