Aller au contenu
use-cases / one-sandbox-per-customer / hero
CONTAINERS · MULTI-TENANT SAAS

One sandbox per customer, automatically

Arrêtez de disperser tenant_id à travers chaque table. Quand un client s'inscrit, un script exec copie un conteneur fresh-customer et leur remet leur propre URL, leur propre système de fichiers, leur propre SQLite. L'isolation est le système d'exploitation entre eux, pas une clause WHERE.

Lire la doc de copie
use-cases / one-sandbox-per-customer / trigger

What that single API call provisions

Each POST to /api/v1/projects/{id}/containers spins up an isolated environment. One call, one tenant, one URL handed back to your app.

01 · WEBHOOK

Signup triggers the container POST

Your Stripe (or any billing) webhook hits a Hoody Exec script. No Express, no server config — just a file in scripts/.

02 · ISOLATION

Linux namespaces, not a WHERE clause

The new container has its own filesystem, its own SQLite, its own ramdisk. Tenant A literally cannot see tenant B's data.

03 · URL

A unique URL back to your app

The response includes a container URL. Your app redirects the user into their own sandbox in the same deploy window.

04 · FIREWALL

Per-tenant network rules cloned

Container network and firewall rules are copied from your template. Every new tenant starts from the same security baseline.

05 · IDLE

Zero cost when idle

Stop the container and it costs nothing. BTRFS keeps only the delta from your template — disk stays cheap even at scale.

06 · OFFBOARD

DELETE container = forget tenant

One DELETE call removes the container and all their data. GDPR offboarding is not a script, it is a single HTTP call.

The whole flow is one webhook handler. No Kubernetes operator, no namespace YAML, no cluster admin. Three HTTP calls: webhook in, container out, URL to user.

use-cases / one-sandbox-per-customer / compare

Multi-tenancy partagée vs conteneur-par-client

Les choix traditionnels étaient une colonne sur chaque table ou une flotte de VMs que vous ne pouviez pas vous permettre. Hoody est une troisième forme : des conteneurs assez bon marché pour en donner un à chaque client.

DIMENSION
DB PARTAGÉE · TENANT_ID
HOODY · CONTENEUR PAR CLIENT
  • ISOLATIONWHERE tenant_id = $1 — et vous espérez que chaque requête s'en souvientNamespaces Linux. Le locataire A ne peut littéralement pas voir le système de fichiers du locataire B.
  • SURFACE DE FUITE DE DONNÉESchaque JOIN, chaque hook ORM, chaque script de reportingla frontière du conteneur. Un seul artefact à auditer, pas 200 sites de requêtes.
  • CONFIG PAR LOCATAIREtable de feature flags, fragile, à moitié testée en devéditez l'environnement d'un conteneur. Les 399 autres sont inchangés.
  • VOISIN BRUYANTun client lourd peut verrouiller la DB partagéequotas CPU et disque par conteneur ; la charge d'un locataire reste dans sa box.
  • OFFBOARDINGDELETE … WHERE tenant_id … plus 12 autres tables que vous avez oubliéesDELETE le conteneur. Ses données partent avec. Le RGPD, c'est un appel HTTP.
  • COÛT À L'INACTIVITÉchaque ligne coûte du stockage même quand le client dortarrêtez le conteneur — zéro CPU, zéro RAM. BTRFS ne garde que le delta.
  • pas de colonnes tenant_id
  • pas d'audits row-level security
  • pas de YAML de namespace
  • supprimer = oublier
use-cases / one-sandbox-per-customer / punchline

La multi-tenancy cesse d'être un problème d'architecture. Elle devient une commande `cp`.

ONBOARDINGPOST /containers/$TEMPLATE/copy
OFFBOARDINGDELETE /containers/$CID
AJUSTEMENT PAR LOCATAIREPATCH /containers/$CID [ env_vars ]
  • isolation de qualité namespace
  • suppression RGPD en un appel
  • un conteneur par compte
use-cases / one-sandbox-per-customer / replaces

Ce que cela remplace

L'isolation par locataire a historiquement signifié soit une clause WHERE astucieuse, soit un cluster coûteux. Le conteneur-par-client déplace les contournements habituels :

  • Multi-tenancy partagée (colonne tenant_id)Une mauvaise requête expose tout le monde
  • Middleware d'isolation locataire personnaliséGarde-fou bricolé que vous maintenez à vie
  • Politiques row-level security PostgresLa bonne réponse, coûteuse à auditer par table
  • Namespace Kubernetes par locataireSurcoût au niveau cluster, équipe ops requise
  • Schémas / bases par clientMultiplicateur de migrations, douleur du connection-pool
  • Lignes de metering Stripe dans une table partagéeSuivi d'usage collé sur la même box partagée
use-cases / one-sandbox-per-customer / cta

Les clients inactifs ne coûtent rien. Les actifs scalent à la demande. Tout tourne sur 49 $ de bare metal jusqu'à des centaines d'utilisateurs payants.

use-cases / one-sandbox-per-customer / related

Découvrez les autres