Devpipe / Run your own

Apache-2.0

Run your own. It is the same thing we run.

Devpipe is a control plane for persistent agent machines. DigitalOcean, Runpod, and local Docker share one adapter contract. Machine operations are journalled, so an API restart does not turn a half-finished provider call into an invisible resource.

Nothing is sold and nothing is charged. There is no payment processor in this and no billing code — Devpipe creates machines in the provider account you connect, and that provider bills you. What the software adds is durable lifecycle control, cost visibility, and a cap that stops new machines when you say stop.

Choose the backing

BackendStatusUse it for
DigitalOceanProductionPublic VMs, persistent volumes, provider firewall and DNS, usage metering, and GPUs.
Local DockerDeveloper previewLifecycle development and contract tests on one host. Named volumes persist; it is not a multi-tenant security boundary.
RunpodPreviewCPU Pods using a published OCI image, trusted HTTPS proxy endpoints, and persistent network volumes. No per-box DNS or provider firewall is claimed.

What to do at DigitalOcean

Do these four in the DigitalOcean console before you start the wizard. Each takes a minute, and the wizard checks all of them against the API rather than taking your word for it — because every one has a failure that shows up hours later looking like something else.

  1. Make an API token

    API → Tokens → Generate New Token. Give it a name you will recognise a year from now, set the expiry you are willing to live with, and tick Write as well as Read — without write it can list droplets and not create one.

    This token creates and destroys droplets, attaches and detaches volumes, and writes DNS records. It is worth its own DigitalOcean account rather than one shared with unrelated infrastructure, because anything that gets hold of it can delete everything that account can see. You paste it once, into the wizard; it is encrypted at rest and never leaves your instance.

  2. Put a domain on the account

    Networking → Domains → Add a domain. Then, at whoever you registered the name with, point its nameservers at DigitalOcean:

    ns1.digitalocean.com
    ns2.digitalocean.com
    ns3.digitalocean.com

    This is the step people get wrong. Owning the domain is not enough — DigitalOcean has to be answering for it, because every box gets an A record written under it and that record is what makes its Let's Encrypt certificate possible. Point it anywhere else and you get boxes that build perfectly, never resolve, never get TLS, and fail in ways that all look like something else. Nameserver changes take anywhere from minutes to a day to propagate; the wizard will refuse the domain until DigitalOcean is actually serving it.

  3. Upload an SSH key

    Settings → Security → Add SSH Key. Paste your public key — ~/.ssh/id_ed25519.pub, not the private one.

    The wizard puts this on every box it builds. It is the only way onto a machine that wedges partway through setup, which is exactly the moment you need to look at one and the moment nothing else works. Skippable, and you will wish you had not.

  4. Check what the account will let you make

    A new account is usually limited to 10 droplets and has no GPU access at all. Both are raised by asking support, and both are worth knowing before you plan around them rather than after. The wizard shows the droplet limit it sees as soon as the token is connected.

    GPU machines — RTX 4000 Ada at $0.76/hr through H100 at $4.41/hr — have to be enabled on the account and exist in only a couple of regions. Devpipe reads the live list from your account, so it offers exactly what you can actually create and nothing else.

Using Runpod instead

Build the same box image, publish it to a registry Runpod can read, and select the Runpod adapter before starting the API. The setup wizard then validates a Runpod API key; DigitalOcean DNS and SSH-key steps are not required.

docker build -f deploy/docker/box.Dockerfile -t registry.example/devpipe-box:latest .
docker push registry.example/devpipe-box:latest
export DEVPIPE_MACHINE_PROVIDER=runpod
export DEVPIPE_RUNPOD_IMAGE=registry.example/devpipe-box:latest
export RUNPOD_API_KEY=…
bun run dev

The stock image includes the daemon, shells, Git, and search tools. Publish a derived image when your agents need additional runtimes or CLIs.

And two things outside the provider

Postgres

Anywhere the control plane can reach — a managed database, or one on the same host. It holds the sessions, the boxes, the audit trail and the encrypted provider token, so it wants a backup, and the backup wants to live somewhere the database does not.

A host to run it on

A small droplet is plenty; it provisions and proxies, it does not compile anything. Give it a name under the same domain — that is the address people sign in at.

Installing it

  1. Clone it and give it a database

    git clone https://github.com/wess/devpipe
    cd devpipe && bun install
    export DATABASE_URL=postgres://…

    Migrations run at startup. There is no separate migrate step to forget.

  2. Give it a key to encrypt credentials with

    openssl rand -base64 32   # → DEVPIPE_SECRET_KEY in /etc/devpipe.env

    This is the one secret that cannot live in the database, because it is what encrypts the database's secrets. Without it the DigitalOcean token is stored as readable text and a copy of a backup is a copy of it — the wizard will generate one and say so plainly rather than let that pass quietly.

  3. Start it and claim it

    Set DEVPIPE_SETUP_TOKEN before making a fresh instance public. The first account must present it and becomes the only owner; remove the token after that claim succeeds.

  4. Answer five questions

    The wizard opens by itself: the encryption key, the provider token, the domain, an SSH key, a spending cap. Two of them are optional and say what you give up by skipping them. The domain is checked against your DigitalOcean account before it is accepted, and the token is checked before it is stored.

Local Docker

docker build -f deploy/docker/box.Dockerfile -t devpipe-box:local .
export DEVPIPE_MACHINE_PROVIDER=docker
export DEVPIPE_SECRET_KEY="$(openssl rand -base64 32)"
bun run dev

Each box is a constrained container whose daemon is published on a random loopback port and reached through the control plane. Workspaces are named Docker volumes. This path currently supplies the terminal runtime and basic development tools; the selectable cloud tool catalogue remains a DigitalOcean bootstrap feature.

Deploy without guessing

The production deploy requires DATABASE_URL and DEVPIPE_SECRET_KEY, takes a timestamped database backup, retains the previous binaries, and waits for the API's database-backed readiness endpoint. Provider mutations are written to an operation journal before they start and unfinished provisioning resumes after a process restart.

One owner, and a team under them

The line between the roles is money and irreversibility. It exists because the alternative — letting somebody help run the instance meant handing them the token that can destroy every box on the account.

RoleCanCannot
Owner
exactly one
Everything. The provider token, the spending cap, GPU machines, and who else administers the instance. Be two people. Promoting somebody is a transfer — you become an admin in the same breath.
Admin Invite people, suspend an abuser, read the audit log, see every box and what the instance is spending. Start a GPU machine. See the provider token, change the spending cap, promote anyone, or suspend another admin.
Member Their own boxes, workspaces, vault entries and terminal sessions, and see what they have cost. Anything administrative at all.

A cap, because the bill is yours

There is nothing to sell here and nobody to charge. DigitalOcean invoices the account the machines are on, which is yours, so the only money question the software can usefully answer is what it has cost you so far — and that is the question a cap is built on.

Asleep, never deleted. Sleeping releases the droplet and keeps the workspace, so the files come back when you raise the cap. A box carrying no workspace is never touched by any sweep in this product — that is the difference between reclaiming a machine and destroying somebody's afternoon.

What the hosted instance does that you would have to

Said plainly, because the honest list is short and none of it is code.