Appearance
Architektur
Multi-Service-Ansatz
MATEV 2026 ist eine Multi-Service-Architektur: Filament-PIM (admin), Kirby-CMS (cms), Nuxt-Frontend (staging), Inertia/Vue-B2B-Portal (b2b) und Tooling (Storybook, VitePress-Docs, Penpot, Taiga, Matomo) laufen als eigenständige Container hinter einem zentralen Caddy-Reverse-Proxy. PHP-Workloads nutzen FrankenPHP im Worker-Mode (Octane für Laravel admin/b2b, nativer FrankenPHP-Mode für Kirby); JS-Workloads (staging/docs/storybook) laufen über Bun.
Lokal läuft die Entwicklung in DDEV, auf dem Server liegen alle Stacks als docker-compose.yml in ~/stacks/<stack>/.
Repos (Forgejo: git.matev.eu)
matev/matev-2026 → Monorepo: admin, b2b, cms, staging, storybook, docs, shared, tools,
deploy.php, .woodpecker.yml
matev/infra → Server-Stack-Config (~/stacks/git: Forgejo + Woodpecker Compose)Ein flaches Monorepo, keine Submodules — die pfadbasierte .woodpecker.yml (admin/**, b2b/**, …) braucht alle Services im selben Repo. Branch-Flow development → staging → main, siehe Git-Strategie.
Verzeichnisstruktur
Lokal (Dev)
matev_2026/ (= Monorepo matev/matev-2026)
├── admin/ → Laravel 13 + Filament 5 (PIM)
├── cms/ → Kirby 4 + KQL
├── staging/ → Nuxt 4 (Marketing-Frontend)
├── b2b/ → Laravel 13 + Inertia 2 + Vue 3 (Händlerportal)
├── shared/ → YAML-Schemas, Vue-Komponenten
├── storybook/ → Storybook (Design System)
├── docs/ → VitePress (diese Doku)
├── tools/ → Python-Skripte (Taiga-/Lastenheft-Automatisierung)
├── deploy.php → Deployer-Config (Deploy auf Production)
├── .woodpecker.yml → CI/CD-Pipeline
├── setup.sh → Onboarding (DDEV-Start)
└── ddev-all.sh → Service-Orchestrierung lokalDie Server-Stack-Definitionen (~/stacks/) sind kein Teil dieses Repos; die Forgejo/Woodpecker-Config liegt in matev/infra.
Auf dem Server (172.16.111.40)
~/stacks/ ← Compose + .env + persistente Volumes
├── apps/ → admin, cms, b2b, staging, storybook, docs, search-stack, …
└── git/ → forgejo (+db), woodpecker (+agent) (= matev/infra)
proxy: vorgelagerter Caddy/Apache routet *.matev.eu
/var/www/ ← Source-Code pro Service (Webroot, bengel:www-data)
├── admin/ cms/ b2b/ staging/ docs/ storybook/ shared/ …Der Build-Context im apps/docker-compose.yml zeigt auf /var/www/<service>/ — Code wird per Deployer dorthin rsynct und direkt aus dem Webroot gebaut. Siehe Deployment.
Service-Topologie (Server)
┌──────────────────────────┐
│ Browser / Internet │
└─────────────┬────────────┘
│ HTTPS / HTTP/3
┌─────────────▼────────────┐
│ Caddy (proxy) │
│ Auto-SSL, alle Hosts │
└─────┬──────┬────┬────┬───┘
│ │ │ │
┌─────────────────┘ │ │ └────────────┐
│ │ │ │
┌──────────▼────────┐ ┌──────────▼─┐ ┌▼───────────┐ ┌▼──────────┐
│ admin (Filament) │ │ cms (Kirby)│ │ b2b (Iner- │ │ staging │
│ FrankenPHP │ │ FrankenPHP │ │ tia + Vue) │ │ (Nuxt 4) │
│ + Octane │ │ │ │ FrankenPHP │ │ Bun │
└────┬─────┬────────┘ └─────┬──────┘ │ + Octane │ └────┬───────┘
│ │ │ └────┬───────┘ │
│ │ REST + Sanctum │ KQL │ REST + Sanctum │ KQL (nuxt-kql)
│ └───────────────────┼─────────────┼─────────────────┘
│ │ │
┌────▼────────┐ ┌──────▼─────────────▼────┐ ┌──────────┐
│ apps-db │ │ │ │ apps- │
│ (MariaDB 11)│◄────────┤ shared by admin + b2b │◄────────┤ redis │
│ matev_admin │ │ │ │ (cache/ │
│ matev_b2b │ └─────────────────────────┘ │ queue/ │
└─────────────┘ │ session) │
└──────────┘
(Storybook, Docs, Meilisearch/OpenSearch/Ollama, Forgejo,
Woodpecker analog hinter dem Proxy — siehe Stacks-Referenz)Datenfluss
- Filament (
admin) ist die zentrale Datenquelle (PIM): Stammdaten, Artikel, Tractoren, Bilder, B2B-Kunden, Bestellungen. - Kirby (
cms) verwaltet redaktionellen Content (Marketing-Seiten, Landingpages) und exponiert ihn per KQL (Kirby Query Language,getkirby/kql). - Nuxt-Staging (
staging) ist die öffentliche Marketing-Site — kombiniert Kirby-Content (per KQL vianuxt-kql) und PIM-Daten (per REST/api/v1) auf gerenderte Seiten. - B2B-Portal (
b2b) ist eine Laravel + Inertia 2 + Vue 3-Anwendung (Laravel Vue Starter Kit), kein Nuxt — Händler loggen sich ein und arbeiten gegenmatev_admin(eigenematev_b2b-DB nur für portal-spezifische Tabellen). (Stand: Starter-Kit-Basis; ein Custom-Dealer-Portal-Layout ist noch nicht eingebaut.) - Sanctum sichert Cross-Domain-Auth zwischen
admin↔staging/b2b(Stateful Domains). - Storybook zeigt die
shared/-Vue-Komponenten isoliert — wird im CI als statisches Build erzeugt und vianginx:alpineausgeliefert.
Shared-Verzeichnis
shared/
├── schemas/ → YAML-Schemas (Single Source of Truth für PIM-Bricks)
├── components/ → Wiederverwendbare Vue-Komponenten (Frontend + Storybook)
├── composables/
│ ├── useApi.ts → REST-Client für admin
│ └── useCms.ts → KQL-Client für cms
└── styles/ → Design Tokens (Brand, Typography, Spacing)Die YAML-Schemas in shared/schemas/ sind die Quelle für Filament-Form-Validierung, Vue-Renderer im Storybook und Frontend-Rendering im Nuxt-Staging.
Lokale Port-Belegung (DDEV)
| Service | HTTP | HTTPS | Beschreibung |
|---|---|---|---|
| admin (Filament) | 33000 | 33001 | DDEV-Router (geteilt) |
| cms (Kirby) | 33000 | 33001 | DDEV-Router (geteilt, Routing per Hostname) |
| design (Penpot) | 33002 | 33003 | Penpot UI |
| staging (Nuxt) | 33004 | 33005 | Nuxt Dev-Server |
| b2b (Laravel/Inertia/Vue) | 33000 | 33001 | DDEV-Router (geteilt), b2b.matev.ddev.site |
| b2b Vite-Dev-Server | 33006 | 33007 | nur bei ddev exec bun run dev |
| storybook | 33008 | 33009 | Storybook Dev-Server |
| docs (VitePress) | 33010 | 33011 | VitePress Dev-Server |
| tracking (Matomo) | 33012 | 33013 | Matomo UI |
| project (Taiga) | 33014 | 33015 | Taiga UI |
CI (Woodpecker) und Git-Hosting (Forgejo) laufen nur auf dem Server (ci.matev.eu / git.matev.eu, Stack: home/bengel/stacks/git/). Es gibt bewusst keine lokale DDEV-Definition dafuer: Woodpecker startet ohne konfigurierte Forge gar nicht (forge not configured) und kennt keine lokalen Logins — Auth laeuft immer ueber Forgejo-OAuth. Ein lokaler Stack waere also nur mit einer echten OAuth-App gegen git.matev.eu lauffaehig. Die Ports 33016/33017 sind damit frei.
Qualitätssicherung
| Tool | Bereich |
|---|---|
| Pest | Testing (admin + b2b) |
| Pint | Code-Style PHP (Laravel-Preset) |
| PHPStan / Larastan | Statische Analyse |
| Bun-Build | Vite/Nuxt/Storybook-Builds müssen durchlaufen |
| Woodpecker CI | .woodpecker.yml (eine Pipeline, pfadbasiert) |
Technologie-Entscheidungen
| Entscheidung | Begründung |
|---|---|
| FrankenPHP + Octane statt php-fpm | Worker-Mode → schneller, kein Boot pro Request, Caddy-integriert |
| Caddy statt Nginx | Auto-SSL, HTTP/3, deklaratives Caddyfile |
| Docker Compose pro Stack statt Kubernetes | Single-Host-Setup; k8s wäre Overkill |
Kirby + KQL (getkirby/kql) | Editor-UX für redaktionelle Inhalte; KQL liefert Content headless ans Nuxt-Frontend |
| Inertia 2 + Vue 3 (Vue Starter Kit) fürs B2B-Portal | Reaktive SPA-UX ohne separates Nuxt; deployt im selben Container-Workflow wie admin (Laravel/Octane) |
Deployer (rsync + docker compose build) statt Registry-Pull | Ein Server, kein Registry-Overhead; baut direkt aus dem rsync'ten Webroot |
| Monorepo statt Multi-Repo+Submodules | Eine pfadbasierte Pipeline, atomare Cross-Service-Commits, kein Submodul-Overhead |
| Bun statt npm | Schnellere Installs/Builds; blockt zudem nicht-allowlistete Lifecycle-Scripts per Default (Supply-Chain) |
| Tailwind 4 (admin/b2b) · Pico CSS + Open Props (staging) | Filament-Standard bzw. minimalistisch fürs Marketing |
| Forgejo + Woodpecker statt GitHub/GitLab | Self-hosted, leichtgewichtig; CI direkt am Git |
| Taiga | Scrum/Kanban out-of-the-box mit klarem Docker-Layout |
Verwandte Themen
- Git-Strategie — Branches + Protection
- Deployment — Deployer-Pfad + CI/CD
- Server-Setup / Stacks-Referenz
- Backup — Disaster-Recovery