Introduction 🎯

After years of smooth sailing on Heroku, our team decided to explore a more cost-effective and flexible option: the DigitalOcean App Platform. In this deep-dive, we share lessons learned, pitfalls avoided and step-by-step guidance to help you migrate your apps with confidence.

Planning the Migration 🔍

Understanding the Differences 🤔

Heroku’s dyno model and buildpacks are rock-solid, but pricing can climb quickly as you scale. DigitalOcean App Platform replaces dynos with components (Web Services, Workers, Databases) and offers predictable billing. Before you begin, map your Heroku add-ons and dyno types to their App Platform equivalents: Component Heroku DigitalOcean App PlatformCompute Unit Dyno (Standard-1X) Web Service (Basic)Background Jobs Worker Dyno Worker ComponentManaged DB Heroku Postgres Managed Database for PostgreSQLCustom Buildpacks buildpacks URL Dockerfile or Auto-detect

Cost Analysis 💰

Carefully compare monthly costs—especially database and bandwidth fees. In our case, a moderate Rails app with 1-GB RAM dyno and 10 GB data transfer dropped from ~100/mo on Heroku to ~25/mo on App Platform.

Step-by-Step Migration Guide 🚀

1. Preparing Your Codebase 🛠️

• Consolidate buildpacks into a single Dockerfile or rely on DigitalOcean’s auto-detect builders.
• Ensure a Procfile (for older apps) or adjust your start command to match the App Platform format.

2. Setting Up the App Platform Environment 🌐

Log into the DigitalOcean control panel, navigate to App Platform gt Create App, then: • Select your code repository (GitHub, GitLab, or Bitbucket)
• Choose the branch to deploy
• Pick the region closest to your users
• Define components (Web Service, Worker), set CPU/memory and Dockerfile path if needed

3. Environment Variables Secrets 🔑

On Heroku you used heroku config:set. On App Platform, click your component, go to Settings gt Environment Variables and Secrets. Be sure to: • Copy all DATABASE_URL, API keys, OAuth secrets
• Mark sensitive variables as “Protected” to avoid exposure in build logs

4. Database Migration 🗄️

We used the following approach: • Provision a new Managed Database on App Platform with the same major Postgres version
• Dump your Heroku DB: pg_dump –format=custom –no-acl –no-owner
• Restore to DigitalOcean: pg_restore –verbose –clean –no-acl –no-owner -h lthostgt -U ltusergt ltdumpfilegt
• Update DATABASE_URL and test connectivity before switching traffic

5. Domains DNS Configuration 🌍

App Platform provides managed certificates and automatic renewals. To point your custom domain: • Add your domain under App Settings gt Domains
• Copy provided A/AAAA records and CNAME entries
• Update your DNS provider (e.g., Cloudflare)

6. Continuous Deployment 🔄

DigitalOcean integrates with Git. Every push to the chosen branch triggers a new build. You can also: • Use GitHub Actions or GitLab CI to run tests before deploying
• Leverage doctl CLI for scripted rollbacks and environment checks

Performance, Monitoring Scaling 📈

Insights Alerts 🔔

Enable Metrics Logs in App Platform. Key takeaways: • Set CPU and memory alerts to detect leaks or traffic spikes
• Stream logs to external tools like Datadog or Loggly
• Use auto-scaling (if available) for components handling unpredictable load

Lessons Learned Best Practices 📚

• Early cost modeling saved us from surprises—run a 30-day free trial on App Platform.
• Dockerfiles gave us full control over build dependencies, reducing “works on my machine” bugs.
• Beware of minor version mismatches when migrating databases—always test restores in a staging environment.
• Automate DNS changes via API to minimize human error during cutover.
• Keep an emergency rollback plan: tag your last known-good Heroku release.

Conclusion 🏁

Migrating from Heroku to DigitalOcean App Platform can lead to significant savings, more control and smoother scaling—if you plan carefully. By following these steps and internalizing the lessons we’ve shared, you’ll ensure a successful transition with minimal downtime. Happy migrating! 🚀

Leave a Reply

Your email address will not be published. Required fields are marked *