从 Heroku 迁移到 Magic Containers
Migrating from Heroku to Magic Containers

原始链接: https://bunny.net/blog/migrating-from-heroku-to-magic-containers/

## 从 Heroku 迁移到 Magic Containers Heroku 作为 PaaS 的先驱,正在转向维持性工程模式,促使用户寻找替代方案。Magic Containers 提供了一条直接的迁移路径,利用了熟悉的十二要素应用原则,例如基于环境的配置和无状态进程。 迁移过程包括使用 Docker 镜像容器化您的应用程序(取代 Heroku 的 buildpacks),然后将它们推送到像 Docker Hub 这样的镜像仓库。Magic Containers 随后允许部署这些镜像,可能还会与用于服务的其他容器一起部署,例如数据库——所有这些容器都通过 localhost 进行通信。这与 Heroku 的插件方法形成对比。 主要区别包括完全的 Docker 控制、具有持久存储的多容器组合以及更广泛的网络支持(通过 Anycast 的 TCP/UDP)。部署方式从 `git push` 变为在 Magic Containers 控制面板中基于镜像的选择,并与 CI/CD 管道集成。自动缩放也更加灵活。 迁移步骤包括容器化您的应用程序、推送镜像、在 Magic Containers 中创建应用程序、添加带有环境变量的容器以及通过 CDN 暴露应用程序。还需要从 Heroku Postgres 等服务迁移数据。对于轻量级应用程序,Bunny 的 Edge Scripting 和 Bunny Database 等替代方案提供了更简单的解决方案。 Magic Containers 旨在重现 Heroku 最初的简单性,提供一个具有全球边缘网络的灵活平台。

黑客新闻 新 | 过去 | 评论 | 提问 | 展示 | 招聘 | 提交 登录 从 Heroku 迁移到 Magic Containers (bunny.net) 6 分,由 pimterry 发表于 2 小时前 | 隐藏 | 过去 | 收藏 | 讨论 帮助 指南 | 常见问题 | 列表 | API | 安全 | 法律 | 申请 YC | 联系 搜索:
相关文章

原文

I’ve been a huge fan of Heroku since the early days. They were true pioneers of platform as a service, git push heroku master was magic when it first appeared, and they made building scalable web apps and services genuinely easy at a time when the alternative was wrestling with EC2 instances and shell scripts.

A lot of us built our first production apps on Heroku, and the developer experience they created shaped how an entire generation thinks about deployment.

On February 6, 2026, Heroku announced that it is entering a sustaining engineering model. No new features, no new enterprise contracts. If you’re starting to think about what comes next, Magic Containers offers a straightforward migration path.

If you’ve been building twelve-factor apps on Heroku environment-based config, stateless processes, and backing services as attached resources, you’ll find that most of those principles translate directly to containers. The deployment model is different, but the thinking is the same.

How Heroku concepts map to Magic Containers

If you're familiar with Heroku, here's how the terminology translates:

Heroku Magic Containers
App Application
Dyno (web/worker) Container
Buildpack Docker image
Add-on (e.g. Heroku Postgres) Additional container in the same app
Procfile Container image entrypoint
Config Vars Environment variables
heroku.yml / Dockerfile deploy Docker image from Docker Hub or GitHub
Dyno scaling Autoscaling (min/max instances per region)
Pipeline (staging/production) Separate applications per environment
Region (US/EU) 40+ regions worldwide

Key differences

  • No buildpacks, just Docker images: Heroku uses buildpacks to detect your language and build your app automatically. Magic Containers runs standard Docker images, giving you full control over your runtime, dependencies, and build process. You can deploy any public or private image from Docker Hub or GitHub Container Registry in any language or framework.
  • Multi-container composition with persistent storage: Heroku apps typically run as a single dyno, with databases provided as separate add-ons connected over the network. Magic Containers allows multiple containers within the same application that communicate over localhost. This lets you run your app alongside its database without an external hosted database service. Persistent volumes provide durable storage so database files, uploads, and application state survive redeployments and restarts.
  • Low-level networking: Heroku primarily provides HTTP routing in the US or the EU. Magic Containers supports TCP and UDP via global Anycast in addition to HTTP, enabling workloads such as DNS servers, game servers, VPN endpoints, or custom protocols.
  • No git push deploys: Instead of pushing code directly, you build a Docker image locally or in CI, push it to a registry, and select it in the Magic Containers dashboard. This fits naturally into GitHub Actions or any CI/CD pipeline.
  • Flexible autoscaling and provisioning: Heroku restricts autoscaling mainly to web dynos and higher-tier plans. Magic Containers autoscales by default and allows customization of scaling behavior and replica counts.

Migration steps

1. Containerize your app

If you already have a Dockerfile, you're ready. If not, create one for your app. Most frameworks have well-documented Docker setups.

Here's a minimal example for a Node.js app:

FROM node:20-alpine

WORKDIR /app
COPY package*.json ./

RUN npm ci --production
COPY . .

EXPOSE 3000

CMD ["node", "server.js"]

On Heroku, your Procfile might define multiple process types like web and worker. With Docker, each process type becomes its own image (or the same image with a different command). For example, a worker that processes background jobs:

FROM node:20-alpine

WORKDIR /app
COPY package*.json ./

RUN npm ci --production
COPY . .

CMD ["node", "worker.js"]

It’s also possible to use a single Dockerfile and override the command per container (common with Go), if that’s your thing. On Magic Containers, you'd add both as separate containers in the same application: the web container with a CDN endpoint, and the worker container with no endpoint. They share localhost, so your worker can connect to the same database and Redis instance as your web process.

2. Push your image to a registry

Build and push your image to Docker Hub or GitHub Container Registry:

docker build -t yourusername/myapp:latest .
docker push yourusername/myapp:latest

Then connect your registry in the Magic Containers dashboard under Image Registries.

3. Create your application

In the Magic Containers dashboard, click Add App and choose your deployment strategy. For stateful apps with a database, choose Single Region. For stateless apps, Magic deployment will distribute your app globally.

4. Add your containers

Add your app container, selecting the image you just pushed. Set your environment variables. These are the same config vars you had in Heroku, such as DATABASE_URL, SECRET_KEY, and PORT.

If you were using Heroku Postgres, add a PostgreSQL container in the same application. Since containers in the same app share localhost, update your database connection to point to localhost instead of the Heroku Postgres hostname.

5. Expose your app

Add a CDN endpoint pointing to your app's container port. This gives you a public URL with automatic HTTPS, no need to configure SSL certificates. You can also use Anycast for non-HTTP protocols like TCP or WebSocket traffic.

6. Export and import your data

Export your Heroku Postgres database:

heroku pg:backups:capture --app your-app
heroku pg:backups:download --app your-app

Then restore it into your new PostgreSQL container. If your new Postgres is accessible via an Anycast endpoint, you can connect directly with pg_restore or psql.

Example deployments

We have step-by-step guides for deploying popular languages, frameworks, and databases on Magic Containers. These include guides for building APIs with:

If you’re looking to get started with a popular web framework, you can host those too:

And databases, standalone or as sidecars to your container apps:

Each guide shows how to configure multi-container apps with databases, persistent volumes, and CDN endpoints.

You might not need a container

Not every Heroku app needs to become a container. bunny.net offers two other products that can replace parts of your stack with less overhead.

Edge Scripting is a serverless runtime for JavaScript and TypeScript that runs across bunny.net’s network. If your Heroku app is a lightweight API, a webhook handler, or middleware layer, Edge Scripting can replace it without a container at all. It also works as DNS middleware, letting you intercept and modify requests at the edge before they reach your origin. There’s no infrastructure to manage, or Dynos to scale.

Bunny Database is a globally distributed, SQLite-compatible database. If you were using Heroku Postgres through a third-party add-on, or your app doesn’t need the full power of PostgreSQL, Bunny Database is a simpler alternative that runs close to your code across bunny.net’s network.

Getting started

Magic Containers is designed to be the kind of platform Heroku was at its best: simple to deploy to, with none of the complexity you don’t need. Full flexibility of Docker and a global edge network.

You bring a container image, set your environment variables, attach storage where you need it, and you’re running. No buildpack debugging, no add-on marketplace, no dyno sleep.

We’d love to see what you’re building. If you’re mid-migration, just getting started, or want to swap notes with others making the same move, come join us on Discord.

联系我们 contact @ memedata.com