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:
2026-07-14 16:10:15 +02:00
parent 4257bd3e55
commit 156166b4e5
25 changed files with 2900 additions and 23 deletions
+70
View File
@@ -0,0 +1,70 @@
# booking/ — self-hosted appointment scheduler (Easy!Appointments) + its DB.
#
# One shared instance serves all clients; each client = a provider/service with
# its own booking-page URL. Lightweight (PHP + MariaDB) to fit the 16 GB box.
# Booking events fire a webhook -> n8n "booking-sync" -> CRM `bookings` + notify.
# Routed by Caddy: booking.mivanchenko.de { reverse_proxy easyappointments:80 }
name: smb-booking
services:
ea-db:
image: mariadb:11
container_name: ea-db
restart: unless-stopped
environment:
MARIADB_DATABASE: easyappointments
MARIADB_USER: ea
MARIADB_PASSWORD: ${EA_DB_PASSWORD}
MARIADB_ROOT_PASSWORD: ${EA_DB_ROOT_PASSWORD}
volumes:
- ea-db-data:/var/lib/mysql
networks: [booking-net]
mem_limit: 512m
healthcheck:
test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
interval: 10s
timeout: 5s
retries: 6
easyappointments:
image: alextselegidis/easyappointments:latest
container_name: easyappointments
restart: unless-stopped
environment:
BASE_URL: https://booking.mivanchenko.de
DEBUG_MODE: "FALSE"
DB_HOST: ea-db
DB_NAME: easyappointments
DB_USERNAME: ea
DB_PASSWORD: ${EA_DB_PASSWORD}
# Email is optional — booking notifications go via webhook -> n8n. Fill to
# also send customers EA's own confirmation emails.
MAIL_PROTOCOL: mail
MAIL_FROM_ADDRESS: info@booking.mivanchenko.de
MAIL_FROM_NAME: Buchung
volumes:
# Brand-matched booking wizard: recolours the flatpickr datepicker to the
# client's --bs-primary and compacts the layout so the embed fits its
# iframe without an outer scrollbar. (Wizard chrome colour itself comes
# from the EA "company colour" setting.) Re-sync from upstream on EA upgrade.
# NOTE: production (DEBUG_MODE=FALSE) serves the .min.* bundles, so those
# are the ones that must be overridden — the plain files are dev-only.
- ./frontend.css:/var/www/html/assets/css/frontend.css:ro
- ./frontend.css:/var/www/html/assets/css/frontend.min.css:ro
# Reports the wizard's rendered height to the embedding page so the iframe
# auto-fits to its content (no inner scrollbar). Re-sync on EA upgrade.
- ./booking_layout.js:/var/www/html/assets/js/layouts/booking_layout.js:ro
- ./booking_layout.js:/var/www/html/assets/js/layouts/booking_layout.min.js:ro
depends_on:
ea-db:
condition: service_healthy
networks: [booking-net, proxy] # proxy: reached by Caddy as easyappointments:80
mem_limit: 256m
volumes:
ea-db-data:
networks:
booking-net:
proxy:
external: true