← Work

Nani

In development

Zero-downtime, cloud-agnostic deployment for Laravel — one binary

The problem

Laravel deployment is fragmented and rented: Forge for provisioning, Envoyer for zero-downtime deploys, Vapor for serverless — three separate paid SaaS products, each opinionated about your cloud. Nani collapses all three into one static Go binary driven by a single nani.yaml. It deploys to any cloud — AWS, GCP, DigitalOcean, bare-metal — or to serverless (Lambda/Bref, Cloud Run), with no per-server subscription and no vendor lock-in.

The interesting part — deploys as a saga

A deploy is an ordered list of small Steps sharing typed state. Steps that mutate remote state implement a Compensator; when a later step fails, the runner walks the completed steps backward and compensates — so an atomic symlink swap auto-rolls back only the instances that already swapped. Side-effects (Slack/Sentry/CI callbacks) are Observers that never gate the pipeline. It’s a compensating-transaction pattern applied to infrastructure, which is what makes partial-fleet failures safe.

Engineering highlights

  • Driver-interface everywhere — storage, locks, secrets, fleet discovery, serverless, notifications: one small interface + a file per backend, selected by a YAML string. This is what makes it genuinely cloud-agnostic and trivial to extend.
  • One feature core, four frontends — a CLI, a Bubble Tea terminal dashboard, an embedded SvelteKit web dashboard with live SSE log streaming, and a native macOS app (Wails) all call the same orchestrators. Zero duplication of deploy logic.
  • Declarative failure policy — every step’s severity (fatal | warn | skip) is config-driven and overridable per environment, replacing silent error-swallowing.
  • Distributed deploy lock (S3/file, TTL) and property-based tests on the risky invariants: env-override merging, semver parsing, atomic-swap command generation.

20+ self-registering provisioning recipes over streaming SSH; preview environments; maintenance mode; release rollback. MIT-licensed.