Add booking stack, client deploys, and back-office updates
- deploy/booking: shared Easy!Appointments stack with brand-matched wizard (flatpickr recolor, single-tenant provider hide, iframe auto-fit height reporter) - deploy/clients: per-client isolated nginx compose stacks with _template scaffold, new-client.sh, and happynails live site - deploy/backup: smb-db backup script - n8n: booking-sync workflow; onboarding tweaks - playbooks: lead-to-customer lifecycle + outreach - templates: nail-studio landing previews - backoffice: app/db/init/compose updates Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
# clients/ — one isolated stack per business client
|
||||
|
||||
Each signed client gets their **own Compose project** (`smb-client-<slug>`) running a
|
||||
single lightweight `nginx:alpine` container that serves *their* static site on *their*
|
||||
domain. Clients are fully separated: independent lifecycle, logs, and removal; no shared
|
||||
container or state. Booking and lead data still flow into the **shared CRM** (Postgres
|
||||
source of truth) via the n8n webhooks baked into each client's page.
|
||||
|
||||
## Why a container per client (not one shared host)
|
||||
- **Isolation** — update / restart / remove one client without touching any other.
|
||||
- **Clean billing & offboarding** — `docker compose down` removes exactly that client.
|
||||
- **Cheap** — static nginx idles at a few MB; capped at 64 MB each, so dozens fit the 16 GB box.
|
||||
|
||||
## Layout
|
||||
```
|
||||
deploy/clients/
|
||||
├── _template/ # DON'T deploy — the source template
|
||||
│ ├── docker-compose.yml (name: smb-client-${CLIENT_SLUG})
|
||||
│ ├── .env.example
|
||||
│ └── site/index.html
|
||||
├── new-client.sh # scaffolds a client folder from _template/
|
||||
└── <slug>/ # one folder per real client (created by the script)
|
||||
├── docker-compose.yml
|
||||
├── .env (CLIENT_SLUG, CLIENT_DOMAIN)
|
||||
└── site/ (the client's branded page)
|
||||
```
|
||||
|
||||
## Add a client
|
||||
```bash
|
||||
cd deploy/clients
|
||||
./new-client.sh happynails happynails.de ../../templates/landing/preview-happynails
|
||||
```
|
||||
Then follow the printed steps: add the Caddy block + reload, point DNS, and `docker compose up -d`
|
||||
on the homelab. Each client lives at `/home/mivanchenko/clients/<slug>/` on the box.
|
||||
|
||||
## How this fits the whole system (compose groups)
|
||||
```
|
||||
edge/ caddy → TLS, routing, basic-auth (one, shared)
|
||||
automation/ n8n (+ postgres, redis) → n8n.mivanchenko.de (one, shared)
|
||||
crm/ smb-db + smb-crm → onboard.mivanchenko.de/crm (one, shared)
|
||||
demos/ smb-demos → demos.mivanchenko.de (prospect previews)
|
||||
clients/ smb-client-<slug> × N → each client's domain (one per client) ← this dir
|
||||
```
|
||||
Shared infra (edge / automation / crm) stays single; only the client-facing sites multiply,
|
||||
one isolated stack each. Previews for *prospects* stay in `demos/` until they sign — then
|
||||
scaffold them a real isolated stack here.
|
||||
Reference in New Issue
Block a user