Skip to content

Dploy

Launch ephemeral Kubernetes environments instantly — a Kubernetes operator and a thin API on top of Flux.

Dploy turns a Helm chart into a self-service, time-boxed environment. A user picks a template from the catalog, and Dploy spins up an isolated, per-user deployment with its own namespace and URL — then tears it down automatically when its TTL expires.

Dploy is split into two cooperating pieces:

  • The operator binds DployInstanceClaims to environments, reconciles DployTemplate and DployInstance custom resources into Flux sources + HelmReleases, manages warm pools, and enforces TTLs and quotas.
  • The API (GoFiber + OIDC) is a thin, stateless server that authenticates users, lists the catalog, and files environment requests. The only thing it writes is a claim — it never touches Flux, and every decision about what happens next belongs to the operator.

Operator + API

A clean split: the API files a request, the operator decides what to do about it. Which instance, for how long, whether the quota allows it — none of that is the API’s call, and its RBAC makes sure of it.

GitOps-native

Charts are pulled from Git or Helm repositories by Flux. Every instance is a real HelmRelease you can inspect with flux and kubectl.

Warm pools

Pre-provision instances so users get an environment instantly — no cold-start wait.

TTL & quotas

The clock starts when your environment is handed over, not when you asked — so queueing for a warm instance costs you nothing. Extensions are capped by the template, quotas by the owner.

OIDC auth

JWT/OIDC authentication via JWKS. The claims you choose to forward flow into your chart values for per-user customization — the raw token never leaves the API server.

Templated values

Render Helm values and connection URLs with Go templates + sprig, using the owner, UUID and request params.

Dploy architecture overview: the API writes DployInstanceClaim custom resources; the operator binds each claim to a DployInstance it owns and reconciles it into Flux resources that deploy the environment.

Asking for an environment means writing one object — a DployInstanceClaim — and watching it:

Terminal window
kubectl apply -f claim.yaml
kubectl get dclaim -w
# NAME TEMPLATE OWNER PHASE INSTANCE URL
# john-doe-webterm webterm john-doe Pending
# john-doe-webterm webterm john-doe Bound webterm-pool-x9 https://webterm-a1b2c3d4.env.dploy.dev

DployInstanceClaim lifecycle: a claim is Pending until the operator binds an instance to it, then Bound; it is Rejected when it cannot be satisfied, and Expired once its TTL elapses.

Behind that, each environment:

  1. Gets an immutable 8-character UUID.
  2. Is deployed into its own namespace <owner>-<name>-<uuid>.
  3. Is exposed at a URL derived from connectionURLTemplate (default <name>-<uuid>.<baseDomain>).
  4. Is owned by the claim, so deleting the claim tears it down — and so does its TTL.