Deploy-as-a-Service for your own cloud
Push code.
Get infrastructure.
Keep both.
Liftoff turns a git push into running services in your own cloud account. Your GitHub Actions build the images, your registry stores them, and Pulumi provisions the rest. The one workflow file Liftoff writes into your repository is removed when you disconnect it.
No build farm. No proxy registry. No hosted runtime.
Built on stock cloud primitives
- Zero-ops compute
- Kubernetes
- Managed Postgres
- Managed cache
- Object storage
- Container registry
How it works
Repository to running app,
without leaving your account
01
Connect
Sign in with GitHub, then link your cloud account. Liftoff commits one workflow file to your repo. Nothing is provisioned yet.
02
Draw
Model services, data and connections on the canvas. The graph is the deploy spec — staged, then applied.
03
Push
Your Actions build one image per service — Dockerfile first, Nixpacks fallback — and push to your registry.
04
Deploy
Pulumi compiles the graph into your account. Migrations gate the rollout; status streams back live.
Platform
Everything an environment needs,
provisioned as one graph
The bill, before you press Deploy
Every node on the canvas carries its own monthly estimate and the environment carries the total, priced from the providers’ own published rates. A deploy shows what it changes before you run it — and a figure Liftoff cannot read is named as missing, never guessed at.
# DigitalOcean list prices, monthly estimate
# metered lines are named, never folded into the total
A vault for variables
Environment- and service-scoped, plain or secret, build-time or runtime. Encrypted at rest; value changes apply without a rebuild.
Bindings, not copy-paste
Connect a resource and its credentials resolve inside Pulumi, from live outputs. They never pass through Liftoff.
# resolved inside Pulumi, injected at runtime
DATABASE_URL=postgres://… ← managed postgres
REDIS_URL=rediss://… ← managed cache
INTERNAL_API_URL=http://api:80 ← service link
Gated migrations
Your pre-deploy command runs as its own job before traffic moves; if it fails, the deploy stops and the previous version keeps serving. Azure Container Apps is the exception — it has no pre-deploy hook, so Liftoff refuses the command rather than storing one nothing would run.
✓ job prisma migrate deploy 3.2s
● rollout web · api · worker
on failure: deploy stops, traffic untouched
Preview environments, opt-in
Off by default, per project — nobody is billed for a preview they did not ask for. Turn it on and every open pull request gets its own environment cloned from the base; closing the pull request destroys it. Not on Kubernetes yet, because nothing shares a cluster and each preview would be a whole extra one.
Four compute targets
Managed containers or a Kubernetes cluster, on either cloud. The same graph compiles to all four — but they are not interchangeable, and each one states which features it supports rather than promising them across the set.
Telemetry & rollbacks
Logs, metrics and per-service rollback on every target, streamed live over WebSocket. Uptime checks are DigitalOcean-only — where a target cannot do something, Liftoff renders the reason in place of the control.
Your team hears about it
Deploys, failures and teardowns go to Slack, Discord or a signed webhook — naming the person who pushed, not their database id. Each channel shows its live status, and every delivery is recorded once it settles, with the attempts it took.
#deploys Deploy failed · storefront / production
pushed by Dana Okafor · migration 0002_orders
✓ delivered · slack, signed webhook · 2 attempts
Projects with people in them
Four roles — owner, admin, developer, viewer — scoped per project, and the invite dialog says what each one can actually read. Invites are one-time links redeemed against an address GitHub has verified.
invite link · redeemed once, against a verified address
A CLI and an API
status, deploy, logs and env pull from your terminal, against the same REST API the dashboard uses. Personal access tokens are scoped, hashed at rest and revocable.
$liftoff status
● production 8f2c41d · 3 services · deployed 4m ago
$liftoff env pull > .env
authenticated with a scoped token · revocable
Service links across repos
One project, many repositories, one app. Internal URLs injected wherever an edge crosses.
Ownership
A control plane, not a landlord.
Liftoff orchestrates infrastructure it doesn't own — yours. The bill comes from your cloud provider, the resources answer to your token, and your running app does not stop when Liftoff does.
- 0
- resources hosted by Liftoff
- 1
- workflow file in your repo — removed on disconnect
- 100%
- stock cloud primitives, plain Pulumi
| Dimension | Liftoff | Typical PaaS |
|---|---|---|
| Compute runs in | your cloud account | their cloud, marked up |
| Images build on | your GitHub Actions | their build farm |
| Images stored in | your container registry | their registry |
| Database credentials | resolve inside Pulumi, in your account | pass through their control plane |
| When you leave | apps keep serving on your account; a teardown that fails is reported, not assumed | export, rebuild, re-platform |