Build your own Vercel on your own cloud: what it takes
Vercel is several systems behind one git push. Most of them already exist as products you can own; the work is the glue between them, and keeping that glue the same in every repository.
You can build a Vercel-like workflow on accounts you own, and in 2026 most of the parts already exist as products: GitHub Actions builds, Cloudflare Workers runs the app worldwide, Supabase holds the Postgres, Terraform creates the rest. What Vercel adds is the glue: one push that builds, deploys to the right environment, wires every resource, and shows you what happened. That glue is what you have to build, and the harder part is keeping it the same in your tenth repository as in your first.
This post breaks Vercel down into its layers, maps each one to something you can own, and is honest about what is left over.
What does Vercel do when you push?
A git push to a Vercel project sets off about ten separate jobs:
- Git integration. It notices the push, knows which branch it was, and comments on the pull request.
- Build. It detects the framework, installs dependencies, builds, and caches the result.
- Deploy. It splits the output into static files for the CDN and functions for the runtime, and uploads both.
- Environments. It decides whether this push is production or a preview, and gives each its own variables.
- Preview URLs. Every branch gets its own deployment and address.
- Domains and certificates. Your domain points at the right deployment, with TLS handled.
- Storage. Blob, a key-value store and a database (now through Marketplace partners) are attached to the project.
- Secrets. Environment variables are encrypted and given to the build and the functions.
- Logs and rollback. You can see what ran and go back to an earlier deployment.
- Templates. A new project can start from a working example.
None of this is magic, but it is a lot. Vercel's value is that you never see the seams.
Which pieces can you own?
On Cloudflare, Supabase and GitHub, every layer has a product you can run in your own account:
| Layer | On Vercel | On accounts you own |
|---|---|---|
| Build | Vercel's build machines | GitHub Actions in your repository (or Cloudflare's Workers Builds) |
| Runtime | Vercel Functions and CDN | Cloudflare Workers with Static Assets |
| Framework support | Built in | OpenNext or vinext for Next.js; Cloudflare adapters for Astro, Nuxt, SvelteKit; Hono runs natively |
| Environments | Production and Preview | One Worker per environment, such as app-stage and app-prod |
| Domains and TLS | Project domains | Custom Domains on Workers, on your Cloudflare zone |
| Files | Vercel Blob | R2 |
| Key-value | Upstash through the Marketplace | Workers KV |
| Postgres | Neon or Supabase through the Marketplace | Supabase, reached through Cloudflare Hyperdrive |
| Cron | Vercel Cron Jobs | Cron Triggers on the Worker |
| Secrets | Environment variables | Worker secrets, set by the deploy |
| Logs and rollback | Deployment logs, instant rollback | Workers Logs, wrangler rollback to an earlier version |
The runtime side is in good shape. Workers run in every Cloudflare location, bill on CPU time rather than wall-clock time, and charge nothing for egress on static assets or R2. Supabase gives you Postgres, auth and storage with a generous free tier. If all you need is "my Next.js app, running on my Cloudflare account", the migration guide gets you there in an afternoon.
What is left to build?
The products do not talk to each other on their own. Between "a push to main" and "the new version is live in production" sits glue that Vercel writes for you and you now write yourself:
- The pipeline. Which environments a pull request, a merge and a tag deploy to, and in which order. Prod should wait for stage to succeed on the same commit.
- Provisioning. An R2 bucket, a KV namespace, a Hyperdrive config and a Supabase project for each environment, created with Terraform before the app that needs them deploys.
- Wiring. Each environment's resource IDs written into that environment's Wrangler config, without anyone pasting IDs by hand.
- Credentials. A Cloudflare token for deploys that can do no more than deploy, and is not a long-lived secret copied into every repository.
- Migrations. Database migrations run before the code that needs them, and only once.
- Checks. A smoke test after each deploy, so a broken stage stops prod.
- A record. What ran, with which inputs, from which commit, so the question "what is in production?" has an answer.
For one app, this is a few hundred lines of GitHub Actions YAML, a Terraform directory and a shell script or two. That is manageable. The trouble starts with the second app.
Why does home-made glue drift?
The second repository starts as a copy of the first. Someone fixes a bug in the first pipeline and forgets the second. The third repository is copied from the second, with a small change for its database. A year later you have twelve pipelines that are each slightly different, nobody can say which is right, and a change to how you deploy means twelve pull requests that each need their own testing.
This is the real cost of building your own Vercel. The first version is a weekend; keeping every copy correct is a job. Vercel's answer is that there is only one copy, theirs. On your own cloud, the answer has to be that the glue is a versioned package every repository uses, not a file each repository owns. We call that platform discipline: the standards are code, every repository is checked against them on every change, and improving the standard is a version bump each repository reviews.
What are your options?
There are four broad ways to get a Vercel-style workflow on your own infrastructure:
| Approach | Where your app runs | You run servers? | What you maintain |
|---|---|---|---|
| Do it yourself with GitHub Actions, Wrangler and Terraform | Your Cloudflare and Supabase accounts | No | Every pipeline, in every repository |
| A self-hosted PaaS such as Coolify or Dokploy | Servers you rent | Yes | The servers, the PaaS, its upgrades |
| An infrastructure framework such as SST | Your AWS or Cloudflare account | No | Your infrastructure code, per app |
| Orunbase | Your Cloudflare and Supabase accounts | No | One file per app that names its golden path |
Each is a reasonable choice. A self-hosted PaaS suits long-running containers and teams that want one server bill. An infrastructure framework suits teams who want to write their infrastructure in TypeScript. Doing it yourself suits a single app with someone who enjoys pipelines.
How does Orunbase put it together?
Orunbase is the glue, packaged. Your repository declares its environments and its apps, and the pipeline is compiled from versioned golden paths rather than written per repository. A Next.js app on Workers is one file beside its code:
apiVersion: sourceplane.io/v1
kind: Component
metadata:
name: web
spec:
type: cloudflare-workers-assets-turbo # the golden path: build, verify, deploy, smoke
subscribe:
environments:
- name: stage
profile: verify
profileRules:
- profile: deploy
when: { triggerRef: github-push-main }
- name: prod
profile: verify
profileRules:
- profile: deploy
when: { triggerRef: github-push-main }
parameters:
workerName: my-app-web
environmentAwareWorkerName: true # my-app-web-stage, my-app-web-prod
workerEntrypoint: .open-next/worker.js
assetsDir: .open-next/assets
smokeCommand: curl -sf "${DEPLOYED_URL}/" > /dev/null
The repository's intent.yaml says that a pull request verifies every environment, a merge to main deploys stage, and prod waits for stage to succeed on the same commit. The rest comes from the golden path:
- Build and deploy run in your own GitHub Actions, through orun, an open-source CLI that compiles the repository's declarations into one plan and runs it.
- Every pull request builds the app and dry-runs the deploy. The plan lists every job the merge will run, so a reviewer sees what will ship before it ships.
- Resources for each environment are Terraform in the same repository, created before the app that needs them.
- Credentials come from the Cloudflare and Supabase connections on your workspace: each deploy gets a short-lived credential minted for it, and no token sits in the repository.
- Every run is recorded, and the console shows runs, logs and a catalog of everything your repositories declare.
- Golden paths are versioned. Each repository pins the version it uses, and an improvement to the path reaches a repository as a version bump it reviews like any other change.
You can start from one of the Vercel templates already ported to Cloudflare, which builds the app, its Terraform and its pipeline into a new repository you own, or move an app you already have.
What do you give up?
Building on your own accounts is a trade, and it is worth being clear about the other side of it:
- Preview URLs per pull request. Vercel gives every branch its own deployment. Orunbase's golden paths build and dry-run every pull request, and stage is a full deployment every merge goes to before prod, but there is no per-branch URL today.
- Zero configuration. Vercel detects your framework and asks nothing. Here, each app has a
component.yamland the repository anintent.yaml. They are short, but they are files you own. - Some Next.js features take setup. Incremental static regeneration needs an R2 cache, image optimisation goes through Cloudflare Images, and Workers have their own limits, such as 128 MB of memory per isolate. The migration guide goes through them.
- One vendor's polish. Vercel's dashboard, analytics and support are one product. On your own accounts, Cloudflare, Supabase and GitHub each have their own.
In short
- Vercel is about ten systems behind one push. Cloudflare, Supabase and GitHub have a product for each of them that runs in your own accounts.
- The part you have to build is the glue: the pipeline, provisioning, wiring, credentials, migrations, checks and a record.
- Glue copied between repositories drifts. Make it a versioned package every repository uses and is checked against.
- Orunbase is that package for Cloudflare and Supabase, with a console and agent access on top. You keep the code, the accounts and the bill.