156166b4e5
- 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>
54 lines
1.7 KiB
Bash
Executable File
54 lines
1.7 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Scaffold a new ISOLATED client stack from _template/.
|
|
#
|
|
# Usage: ./new-client.sh <slug> <domain> [source-site-dir]
|
|
# ./new-client.sh happynails happynails.de ../../templates/landing/preview-happynails
|
|
#
|
|
# Creates deploy/clients/<slug>/ with its own .env + site/, then prints the
|
|
# Caddy block and the deploy command. Run it from deploy/clients/.
|
|
set -euo pipefail
|
|
cd "$(dirname "$0")"
|
|
|
|
SLUG="${1:?usage: new-client.sh <slug> <domain> [source-site-dir]}"
|
|
DOMAIN="${2:?domain required (e.g. happynails.de)}"
|
|
SRC="${3:-}"
|
|
|
|
[[ "$SLUG" =~ ^[a-z0-9-]+$ ]] || { echo "slug must be lowercase letters/digits/dashes"; exit 1; }
|
|
[ -e "$SLUG" ] && { echo "client '$SLUG' already exists at deploy/clients/$SLUG"; exit 1; }
|
|
|
|
cp -r _template "$SLUG"
|
|
cat > "$SLUG/.env" <<EOF
|
|
CLIENT_SLUG=$SLUG
|
|
CLIENT_DOMAIN=$DOMAIN
|
|
EOF
|
|
|
|
if [ -n "$SRC" ]; then
|
|
[ -d "$SRC" ] || { echo "source dir '$SRC' not found"; exit 1; }
|
|
rm -f "$SLUG"/site/*.html
|
|
cp -r "$SRC"/. "$SLUG"/site/
|
|
echo "Seeded site/ from $SRC"
|
|
fi
|
|
|
|
cat <<EOF
|
|
|
|
✓ Created deploy/clients/$SLUG
|
|
|
|
1) Add this block to the homelab Caddyfile, then reload Caddy:
|
|
docker exec caddy caddy reload --config /etc/caddy/Caddyfile
|
|
|
|
$DOMAIN {
|
|
reverse_proxy client-$SLUG:80
|
|
encode zstd gzip
|
|
}
|
|
|
|
2) DNS: a *.mivanchenko.de subdomain already resolves (wildcard) — nothing to do.
|
|
For a client-owned domain, add their A record $DOMAIN -> 188.193.49.3.
|
|
|
|
3) Deploy the stack:
|
|
scp -r $SLUG mivanchenko@mivanchenko.de:/home/mivanchenko/clients/
|
|
ssh mivanchenko@mivanchenko.de 'cd ~/clients/$SLUG && docker compose up -d'
|
|
|
|
Remove this client later (isolated — touches nothing else):
|
|
ssh mivanchenko@mivanchenko.de 'cd ~/clients/$SLUG && docker compose down'
|
|
EOF
|