FRAMEWORK

HostSSH as our Infrastructure Framework

The tech, and how the fleet's "deploy a new app" runbook becomes HostSSH automation. Companion to the DevOps NEW-APP-DEPLOY.md (the manual runbook): that doc is the SPEC; this is the architecture that makes HostSSH own it.

What HostSSH is

A SaaS control plane + a single-binary agent that turns any VPS into managed infrastructure we (and customers) drive from one panel. 100% ours — Node + Go, zero PHP, no Coolify/Dokploy code (they're only migration sources + inspiration).

Three planes:

PlaneTechOwns
Control plane (SaaS)Next.js 16 · React 19 · Postgres (pgvector)dashboard + /api/v1/*, fleet registry, deploy jobs queue, licensing/billing, white-label, tenants, audit, observability
Agent (the universal connector)Go — one static ~7 MB binary, zero depsbuild→run→route (HostPack→Docker→Traefik), capture/restore, hardening, host metrics, claims + runs deploy jobs
Datapgvector Postgres · R2 · on-box secretsper-app DBs, object storage, secret material (never leaves the box)

The deploy model — pull-based jobs (the key decision, built + proven): control plane enqueues → agent claims on its heartbeat → runs OUR pipeline locally → streams state + logs back. No inbound connection to the box → works on any provider, behind any NAT/firewall. Hardened: license-scoped, claimed_by- fenced, 15-min reclaim lease, 30-min job timeout, jobs run off the heartbeat path.

"Connect to any VPS" + SaaS

  • Connect: curl … | sh installs the signed agent → activates (ed25519 token verified) → heartbeats in → claims jobs. Any box joins the fleet in minutes.
  • SaaS: the control plane is already multi-tenant (tenants, white-label, license codes, billing). Customer signs up → gets a license → installs the agent on their VPS → manages everything from the panel. Revenue = license codes
    • managed hosting + resold VPS margin.

The new-app deploy process → HostSSH automation mapping

Every phase of the manual fleet runbook maps to a HostSSH capability. Status is in OUR codebase today:

#Runbook phaseHostSSH capabilityStatus
1Source (git repo)deploy job + git-clone + Dockerfile autodetect✅ have
2Database (per-app)agent db create (postgres/mariadb/redis)✅ have
3Appdeployment + deploy job (jobs loop)✅ have (proven e2e)
4Env / secretsagent secrets + deployment_env (on-box custody)✅ have
5Redis/Valkeyservice template + prebuilt-image deploy✅ have
6R2 / storageBYO connector (connections)🟡 per-app wiring
7Deploy + migratedeploy job + release-phase migrate (RunOnce)✅ have
8DNS + TLSTraefik + ACME + Cloudflare DNS connector✅ have (needs CLOUDFLARE_DNS_TOKEN)
9Backupscapture/restore + restic→R2 + drills✅ have
10Image hygienekeep-last-N image reaper + daily auto-run✅ have
11Verifyhealthcheck-gated deploy (liveness)✅ have

The runbook is owned end to end as of 2026-06-23: source (git/Dockerfile) → build (HostPack/Dockerfile) → migrate → run → route → liveness-verify → DNS+TLS, with keep-last-N image hygiene. Remaining polish: per-app R2 storage wiring (#6), and a panel UI for the migrate/branch/DNS fields (the agent + actions already support them). Live use needs the owner-run steps (toolchain install, prod redeploy, the CLOUDFLARE_DNS_TOKEN).

Why this stack (the decisions)

  • Go agent, zero deps → a single static binary customers run with no runtime to install; the lightest possible "connect to any VPS" footprint, and the prerequisite for clean image→image porting.
  • Pull-based jobs → no inbound to the box; provider-agnostic; survives NAT.
  • HostPack (Railpack/MIT) for builds; prebuilt-image path for run-only.
  • Security spine first (PHASE 0): ed25519 license tokens, signed grace- refresh, TLS + cert pinning, signed reproducible binaries, hash-chained audit.
  • Migration, not dependency: migrate --from coolify|dokploy imports a customer's existing platform onto our engine — the on-ramp to the SaaS.