MEC Multi-Center auf Recast — Runbook (v0 + GitHub + Cockpit)
Zielgruppe: IT, v0-Entwickler, Recast-Betrieb.
Diese Seite bündelt den End-to-End-Weg für MEC-Website-Templates (Rot, Hybrid, Grooß, Grün): Layout in v0, Code in GitHub, Image in GHCR, Betrieb auf Recast, Inhalte aus dem Cockpit.
Kürzere Einstiege: v0 auf Recast (Docker) · Go-Live — MEC auf Recast · v0 Instructions Teil G
Architektur (Überblick)
Multi-Center-Prinzip: Ein Repo = ein Layout (websiteTemplate) = ein Docker-Stack auf Recast. Viele Center teilen dasselbe Image; zur Laufzeit entscheidet die Domain (GET …/api/centers/by-domain), welches Center geladen wird.
Template ↔ GitHub ↔ Recast
| Anzeigename | websiteTemplate | GitHub-Repo | GHCR-Image (Beispiel) | Recast APP_PORT |
|---|---|---|---|---|
| MEC Template Rot | mec-template-a | smg-mec-template-rot | ghcr.io/sawmuedev/smg-mec-template-rot:latest | 3001 |
| MEC Template Hybrid | mec-template-d | smg-mec-template-hybrid | ghcr.io/sawmuedev/smg-mec-template-hybrid:latest | 3002 |
| MEC Grooß | mec-template-grooss | smg-mec-template-groooss | ghcr.io/sawmuedev/smg-mec-template-groooss:latest | 3003 |
| MEC Grün | mec-template-green | smg-mec-template-green | ghcr.io/sawmuedev/smg-mec-template-green:latest | 3004 |
| MEC 2 | mec-template-c | smg-mec-template-c (falls aktiv) | ghcr.io/sawmuedev/smg-mec-template-c:latest | eigener Port |
Jedes Repo enthält lokal RECAST-DEPLOY.md und .env.recast.example — repo-spezifische Kurzreferenz.
Deploy-Dateien im Monorepo (Quelle): deployment-templates/v0-recast/ · Sync-Skript: scripts/sync-mec-recast-deploy-to-template-repos.sh
Was v0 macht — und was nicht
v0 überschreibt nicht automatisch eure Recast-Infrastruktur
v0 arbeitet per GitHub-Integration (Branches v0/…, Merge-PRs). In der Praxis ändern v0-PRs typischerweise:
app/,components/,lib/,public/— Layout, Seiten, API-Clients- gelegentlich
middleware.ts/ Multi-Center-Logik, wenn ihr das in v0 anpasst
In der Regel unangetastet bei normalen Layout-PRs (Stand Template-Repos):
Dockerfile,docker-compose.yml,.dockerignore,docker/scripts/.github/workflows/build-push-ghcr.ymlapp/api/health/,app/api/revalidate/,app/api/cockpit-register/.env.recast.example,RECAST-DEPLOY.md
Risiko: next.config.mjs
v0 setzt beim Initial-Export eine next.config.mjs ohne output: 'standalone'. Ohne diese Zeile bricht der GHCR/Docker-Build ab (.next/standalone fehlt).
Pflicht in jedem Template-Repo:
const nextConfig = {
output: 'standalone',
// … rest (images, redirects, typescript, …)
};
Nach v0-Merges next.config.mjs kurz prüfen — output: 'standalone' muss erhalten bleiben.
Empfehlung bei v0-Merges
- PR-Dateiliste ansehen — Deploy-Pfade sollten nicht gelöscht werden.
next.config.mjsaufoutput: 'standalone'prüfen.- GitHub Action Build & Publish muss grün sein, bevor Recast pullt.
- Bei Verlust: Dateien aus
deployment-templates/v0-recast/odersync-mec-recast-deploy-to-template-repos.sherneut syncen. - Multi-Center-Fixes (
force-dynamicim Root-Layout, keine fest verdrahteten Center-Namen) auch auf den offenen v0-Branch legen — sonst überschreibt der nächste v0-PRmainwieder mit ISR/Hardcodes.
v0 überschreibt also eure App-Dateien im Sinne von Layout-Updates — nicht heimlich das ganze Repo. Deploy-Dateien bleiben, solange v0 sie nicht explizit mitgeneriert und ihr sie nicht beim Merge entfernt. Cockpit-Daten (DB) werden von v0 nie überschrieben.
Einmal-Setup (pro Template-Repo)
- v0: Instructions A–J + Teil G (Multi-Center,
by-domain) — siehe v0 API Ready-to-Go. - Deploy-Paket aus
deployment-templates/v0-recast/(oder Sync-Skript) ins Repo. next.config.mjs:output: 'standalone'.- GitHub Action
build-push-ghcr.yml→ Push aufmainbautghcr.io/sawmuedev/<repo>:latest. Für MapTiler (Rot/Grün): SecretNEXT_PUBLIC_MAPTILER_KEYim GitHub-Repo (gleicher Wert wie Vercel).NEXT_PUBLIC_*wirkt erst nach Image-Build, nicht allein über Recast-.env. - Recast: Verzeichnis z. B.
/srv/docker/templates/<repo>/,docker-compose.yml+.envaus.env.recast.example. - Nginx + SSL auf Recast — siehe SETUP-NOTES-for-hoster.md.
Recast .env (Multi-Center, pro Template-Stack)
GHCR_IMAGE=ghcr.io/sawmuedev/smg-mec-template-rot:latest
APP_PORT=3001
COMPOSE_PROJECT_NAME=smg-mec-template-rot
COCKPIT_MULTI_CENTER_MODE=shared
EXPECTED_WEBSITE_TEMPLATE=mec-template-a
DEFAULT_CENTER_SLUG=beispiel-center-slug
NEXT_PUBLIC_DASHBOARD_URL=https://dashboard.cockpit-os.de
COCKPIT_DASHBOARD_URL=https://dashboard.cockpit-os.de
COCKPIT_FRONTEND_CHANNEL=website
REVALIDATION_SECRET=<gleich wie Cockpit-Dashboard>
# Karten (Rot/Grün): gleicher Wert wie Vercel. Wirkt im Browser erst nach GHCR-Rebuild
# mit GitHub Secret NEXT_PUBLIC_MAPTILER_KEY (Next.js backt NEXT_PUBLIC_* beim Build ein).
# NEXT_PUBLIC_MAPTILER_KEY=
COCKPIT_REGISTER_ON_START=false
Nicht setzen (Multi-Center): COCKPIT_CENTER_SLUG, COCKPIT_REGISTER_TOKEN, COCKPIT_DEPLOY_ORIGIN als feste Container-Env.
Alltag: Code-Update (alle Center eines Templates)
v0 ändern → GitHub push/merge → GHCR Action (grün) → Watchtower zieht :latest (ca. 5 Min)
Betrifft alle Center mit demselben websiteTemplate — kein neues Repo, kein neuer Container.
Watchtower (Recast, Prod-Pfad): Stack unter /srv/docker/templates/watchtower/ (smg-mec-watchtower + smg-mec-docker-socket-proxy). Poll alle 5 Minuten, nur Container mit Label com.centurylinklabs.watchtower.enable=true (die vier MEC-Template-Stacks).
Sicherheit (kurz): Watchtower spricht nicht den Docker-Socket direkt an, sondern einen Proxy auf 127.0.0.1:2375 (nicht öffentlich). Images von Watchtower/Proxy sind per Digest gepinnt und aktualisieren sich nicht selbst. Es überwacht fest die vier Template-Container-Namen (nicht nur das Enable-Label — das reicht hinter dem Proxy bei Watchtower 1.20 nicht). EXEC/BUILD/Swarm sind gesperrt. Compose: deployment-templates/v0-recast/watchtower.docker-compose.yml.
Manuell falls der Stack steht: docker compose pull && docker compose up -d im Template-Verzeichnis.
Neues Center (gleiches Template)
| Schritt | Wo |
|---|---|
Center anlegen, websiteTemplate passend setzen | Cockpit |
| Inhalte pflegen | Dashboard-Reiter / MCP |
| Custom Domain eintragen | Center → Website → Aktivierung |
| DNS A → Recast-IP | Domain-Provider / UD (manuell — keine UD-Automatik wie bei Vercel) |
| SSL | Recast (certbot) |
| Register Production-URL | Frontend-Kanäle oder MCP cockpit_register_frontend_deployment |
| Verbindung testen | Frontend-Kanäle → Verbindung prüfen |
Kein neuer GHCR-Build nötig.
Cockpit vs. Recast vs. Monorepo center-website
| Recast + v0-Repo | Cockpit Render (cockpit-render) | |
|---|---|---|
| Frontend-Quelle | v0-GitHub-Repo | apps/center-website im Monorepo |
| Preview | Staging-Domain / ?center=slug | preview.cockpit-os.de/{slug} |
| MEC Rot/Hybrid/Grooß/Grün Live | Recast (Zielbild) | Legacy, wenn noch nicht umgestellt |
Inhalte kommen in beiden Fällen aus dem Cockpit — nur das Layout-Repo unterscheidet sich.
Troubleshooting
| Symptom | Ursache | Fix |
|---|---|---|
| Alias-Host (*.cockpit-os.de) lädt Startseite teilweise, Unterseiten 404 / falsches Center | Middleware mappt Subdomain blind auf Slug (degasperipassage ≠ de-gasperi-passage-norderstedt). by-domain findet Center in customDomains, Routing nutzt aber Subdomain als Slug | Kurz: Primary-DNS auf DB-Slug setzen (de-gasperi-passage-norderstedt.cockpit-os.de). Dauerhaft: Middleware-Patch — bei *.cockpit-os.de zuerst by-domain, dann auf echten Slug umschreiben (apps/center-website/middleware.ts, gleiches Muster in MEC-Template-Repos) |
GHCR-Build: .next/standalone not found | output: 'standalone' fehlt | In next.config.mjs ergänzen, push |
| Falsches Center / falsches Layout | Domain nicht in Cockpit oder falscher Stack | customDomain + websiteTemplate prüfen; Nginx Host weiterleiten |
| Hybrid zeigt überall ORO (Logo, Footer, Teaser, Anfahrt) | Template ist noch der ORO-v0-Export: Hardcodes + ISR ohne Host-Vary. Nginx-Mapping und by-domain sind dann oft richtig (Titel/Shops vom Host, Rest ORO) | Kein Recast-vHost-Fix. Im Hybrid-Repo ORO-Fallbacks entfernen, Texte/Socials aus Center-Surface, Root-Layout force-dynamic. Danach 3–4 Hosts spot-checken — nicht jede Domain einzeln mit Recast durchgehen |
| 404 Template-Guard | Center-Template ≠ EXPECTED_WEBSITE_TEMPLATE | Cockpit-Template oder Recast-Env anpassen |
| Keine Auto-Aktualisierung nach Publish | Revalidate | REVALIDATION_SECRET + websitePublicUrlProduction |
| Karte leer / „MapTiler Key fehlt“ | NEXT_PUBLIC_MAPTILER_KEY nur auf Vercel, nicht im GHCR-Build | GitHub Secret setzen, Image neu bauen; Watchtower oder Recast pull && up -d |
| Layout nach Merge nicht auf Recast | Action rot, Proxy/Watchtower aus, oder Label fehlt | GHCR-Action prüfen; docker logs smg-mec-watchtower; ss -lntp | grep 2375 muss 127.0.0.1 zeigen |
Siehe auch
- v0 auf Recast (Docker)
- Go-Live — MEC auf Recast
- Public Center Website API —
by-domain,public-visitor-surface - Frontend-Kanäle / v0 Hosting
- Monorepo:
deployment-templates/v0-recast/README.md
Nutzungsstatistik: Seitenaufrufe werden anonymisiert erfasst. Im Umami-Dashboard nach diesem Pfad filtern: /developer-guide/mec-recast-multi-center-runbook