Appearance
Staging-Deploy für die Kunden-Demo
Legacy / historisch (Stand 2026-05)
Kanonischer Deploy-Weg ist jetzt Deployment (Deployer deploy.php + Woodpecker). Es gibt keinen separaten Staging-Server — alles läuft auf 172.16.111.40 (SSH-Alias matev-deploy); staging.matev.eu ist nur der Proxy. Dieses Dokument bleibt als historischer Demo-Pfad.
Der schnelle Demo-Pfad ohne Woodpecker — wenn die CI noch nicht steht oder ein Image lokal frisch gebaut werden muss.
Hintergrund: Forgejo-Domain
git.matev.euist aktuell nicht durchgehend erreichbar. Die Service-Submodules (admin/,shared/) liegen lokal in der Infrastruktur. Bis Forgejo + Registry stabil sind, bauen wir Images lokal und pushen sie perdocker save+scpauf den Staging-Server (oder direkt in eine erreichbare Registry).
Reihenfolge für die Demo
- admin (Filament-PIM) — Kunde sieht das Backend
- cms (Kirby) + staging (Nuxt) — Kunde sieht Marketing-Frontend mit echtem CMS-Inhalt
- storybook — Kunde sieht die CMS-Komponenten isoliert
- (später) b2b (Livewire) — Händlerportal
Voraussetzungen auf dem Staging-Server (einmalig)
bash
ssh root@staging.matev.eu
# Docker
curl -fsSL https://get.docker.com | sh
systemctl enable --now docker
# Deploy-User
adduser --disabled-password --gecos "" bengel
usermod -aG docker bengel
mkdir -p /home/bengel/.ssh
echo '<DEIN_SSH_PUB_KEY>' >> /home/bengel/.ssh/authorized_keys
chown -R bengel:bengel /home/bengel/.ssh && chmod 700 /home/bengel/.ssh
# Firewall
ufw allow 22,80,443/tcp && ufw allow 443/udp && ufw enable
# Externes Docker-Netz für alle Stacks
docker network create gateway
# Stack-Repo holen (oder per scp übertragen, solange Forgejo down)
mkdir -p /home/bengel/stacks
cd /home/bengel/stacks
git clone https://git.matev.eu/matev/server-stacks.git .
# Notfall: scp -r dev-laptop:/path/to/stacks/* bengel@staging.matev.eu:~/stacks/
chown -R bengel:bengel /home/bengel/stacks.env-Dateien händisch anlegen — Werte aus dem Passwort-Manager (1Password / Bitwarden):
bash
nano /home/bengel/stacks/proxy/.env # ggf. leer
nano /home/bengel/stacks/mgmt/.env
nano /home/bengel/stacks/git/.env
nano /home/bengel/stacks/apps/.env(Inhalt siehe Stacks-Referenz.)
Stacks initial hochfahren
bash
ssh bengel@staging.matev.eu
cd ~/stacks/proxy && docker compose up -d # Caddy zuerst
cd ~/stacks/mgmt && docker compose up -d # Portainer + Matomo
cd ~/stacks/git && docker compose up -d # Forgejo + Woodpecker (sobald nutzbar)
cd ~/stacks/apps && docker compose up -d # Apps zum SchlussCaddy hat dann automatisch SSL-Zertifikate für alle Hosts gezogen, sobald DNS auf den Server zeigt.
Demo-Pfad A — Code per rsync, Build auf dem Server (empfohlen)
So passt das zur Server-Webroot-Konvention /var/www/<service>/. Der Build läuft direkt auf dem Server, kein Image-Transfer nötig.
bash
# 1) Code vom Dev-Rechner auf den Server (admin)
rsync -av --delete \
--exclude='node_modules' --exclude='vendor' --exclude='.env' \
--exclude='storage/app/public' --exclude='storage/logs' \
/pfad/zu/matev_2026/admin/ \
bengel@staging.matev.eu:/var/www/admin/
# 1b) Dockerfile aus den Referenzen übertragen (einmalig pro Service)
scp /pfad/zu/matev_2026/home/bengel/stacks/apps/dockerfiles-reference/admin.Dockerfile \
bengel@staging.matev.eu:/var/www/admin/Dockerfile
# 2) Auf dem Server: .env eintragen + bauen + hochziehen
ssh bengel@staging.matev.eu << 'EOF'
# .env initial setzen (nur einmal)
[ -f /var/www/admin/.env ] || cp /var/www/admin/.env.example /var/www/admin/.env
nano /var/www/admin/.env # APP_KEY, DB-Passwort, Mail, Search-Keys
cd ~/stacks/apps
docker compose build admin
docker compose up -d apps-db apps-redis admin
# Migrationen + Cache
docker compose exec admin php artisan migrate --force --graceful
docker compose exec admin php artisan db:seed --force
docker compose exec admin php artisan filament:optimize
docker compose exec admin php artisan octane:reload
EOFDemo-Pfad B — Image lokal bauen + transferieren (Fallback ohne Forgejo-Registry)
Wenn der Server zu schwach für den Build ist oder kein direkter Code-Push möglich:
bash
# 1) Image lokal bauen — Build-Context lokal /pfad/zu/admin/
cd /pfad/zu/matev_2026/admin
cp ../home/bengel/stacks/apps/dockerfiles-reference/admin.Dockerfile Dockerfile
docker build -t matev/admin:demo .
# 2) Tarball + Transfer
docker save matev/admin:demo | gzip > /tmp/admin-demo.tar.gz
scp /tmp/admin-demo.tar.gz bengel@staging.matev.eu:/tmp/
# 3) Auf dem Server laden und in apps/docker-compose.yml `image: matev/admin:demo`
# eintragen statt build:, dann up -d admin
ssh bengel@staging.matev.eu "docker load < /tmp/admin-demo.tar.gz"Pimcore-Daten in den Staging-Admin importieren
bash
# Lokalen Dump hochladen
scp migration/exports/pimcore-2026-04-27.sql.gz bengel@staging.matev.eu:/tmp/
# Auf den Staging-Server
ssh bengel@staging.matev.eu
# Dump in den apps-db-Container streamen — getrennte DB für Pimcore-Quelldaten
docker exec -i apps-db mariadb -u root -p"$APPS_DB_ROOT_PASSWORD" -e \
"CREATE DATABASE IF NOT EXISTS matev_pimcore_source;"
gunzip -c /tmp/pimcore-2026-04-27.sql.gz | \
docker exec -i apps-db mariadb -u root -p"$APPS_DB_ROOT_PASSWORD" matev_pimcore_source
# Importer im admin-Container laufen lassen
cd ~/stacks/apps
docker compose exec admin php artisan import:pimcore --dry-run
docker compose exec admin php artisan import:pimcore --phase=1 # Stammdaten
docker compose exec admin php artisan import:pimcore --phase=2 # Tractor + Dealer
docker compose exec admin php artisan import:pimcore --phase=3 # Articles + Bricks
docker compose exec admin php artisan import:pimcore --phase=4 # Offers + Orders
docker compose exec admin php artisan import:pimcore --phase=5 # Konfiguration
docker compose exec admin php artisan blueprints:generateStorybook deployen (statisches Build)
Storybook ist ein statisches Build — kein PHP, kein Bun-Server zur Laufzeit nötig:
bash
# 1) Lokal bauen
cd storybook
bun install
bun run build-storybook # Output: storybook-static/
# 2) Auf den Server rsyncen — in den Webroot, der read-only ins
# storybook-Container gemountet wird:
rsync -av --delete storybook-static/ \
bengel@staging.matev.eu:/var/www/storybook/
# 3) nginx im Container muss nicht neu starten — er liest live aus dem MountCaddy-Route ist storybook.matev.eu → storybook:80 (siehe apps/docker-compose.yml).
Kirby + Nuxt-Staging-Frontend
Empfohlen: Code-Push direkt nach /var/www/<service>/, dann Build auf dem Server (analog admin).
bash
# Kirby
rsync -av --delete --exclude='vendor' /pfad/zu/cms/ bengel@staging.matev.eu:/var/www/cms/
scp /pfad/zu/home/bengel/stacks/apps/dockerfiles-reference/cms.Dockerfile \
bengel@staging.matev.eu:/var/www/cms/Dockerfile
ssh bengel@staging.matev.eu "mkdir -p /var/www/cms/.docker"
scp /pfad/zu/home/bengel/stacks/apps/dockerfiles-reference/cms.Caddyfile \
bengel@staging.matev.eu:/var/www/cms/.docker/Caddyfile
ssh bengel@staging.matev.eu "cd ~/stacks/apps && docker compose build cms && docker compose up -d cms"
# Nuxt-Staging-Frontend
rsync -av --delete --exclude='node_modules' --exclude='.output' \
/pfad/zu/staging/ bengel@staging.matev.eu:/var/www/staging/
scp /pfad/zu/home/bengel/stacks/apps/dockerfiles-reference/staging.Dockerfile \
bengel@staging.matev.eu:/var/www/staging/Dockerfile
ssh bengel@staging.matev.eu "cd ~/stacks/apps && docker compose build staging && docker compose up -d staging"Kirby-Content initial: rsync -av /pfad/zu/cms/content/ bengel@staging.matev.eu:/var/www/cms/content/.
Demo-Stand für den Kunden
| URL | Inhalt | Login |
|---|---|---|
https://admin.matev.eu/admin | Filament PIM — Stammdaten, Artikel, Tractoren, Produkte | admin@matev.eu / admin |
https://cms.matev.eu/panel | Kirby Panel — CMS-Inhalt redaktionell pflegen | initial setzen |
https://staging.matev.eu | Nuxt-Frontend — gerendertes CMS + Produkt-Listen | — |
https://storybook.matev.eu | Komponenten-Showroom — Spec-Bricks, Page-Layouts | — |
Kurz-Pitch für das Kundengespräch:
"Drei Bausteine sehen Sie heute live:
- Im Filament-PIM verwalten Sie alle Produktdaten — die Pimcore-Bestände sind über
import:pimcore1:1 übernehmbar (5.255 Hauptartikel, 524 Produkte, 362 Traktoren). Multi-Sprache (DE/EN/FR) ist Pflichtfeature, ebenso die 41 Spezifikations-Bricks.- Im Kirby-CMS pflegen Ihre Redakteure die Marketing-Seiten — Bilder, Texte, Landingpages — mit Live-Vorschau im Panel. Über GraphQL wird der Inhalt vom Nuxt-Frontend in Realtime ausgespielt.
- Im Storybook sehen Sie alle CMS-Komponenten isoliert — jede ist aus einem YAML-Schema generiert (Single Source of Truth), das gleichzeitig Filament-Validierung und Frontend-Rendering speist.
Das Händlerportal (B2B-Bestellungen, Konfigurator) folgt im nächsten Sprint als Livewire-Anwendung — die Schnittstellen (REST + GraphQL) stehen bereits."
Rollback (Demo-Notfall)
bash
ssh bengel@staging.matev.eu
docker images matev/admin # Liste aller geladenen Tags
# Image-Tag in apps/docker-compose.yml auf älteren Tag setzen, dann:
cd ~/stacks/apps && docker compose up -d adminPre-Demo-Checkliste
- [ ] DNS auf alle Demo-Hosts zeigt (admin, cms, staging, storybook):
dig +short admin.matev.eu - [ ] Caddy hat alle Zertifikate gezogen:
curl -I https://admin.matev.eu→HTTP/2 200 - [ ]
https://admin.matev.eu/adminlädt; Loginadmin@matev.eu/adminklappt - [ ] Mindestens 1 Maker, 1 MainArticle, 1 Tractor sichtbar (notfalls via Filament-UI anlegen)
- [ ]
https://cms.matev.eu/api/queryantwortet auf einen KQL-POST ({"query":"site"}) bzw. GraphQL je nach Plugin - [ ]
https://staging.matev.eurendert Startseite mit echtem CMS-Inhalt (kein 502) - [ ]
https://storybook.matev.eulädt; alle Story-Gruppen (Spec, Area, Snippet, Page) ohne JS-Fehler - [ ] Pimcore-Phase-1-Import gelaufen (Stammdaten sichtbar)
- [ ] Backup-Cron läuft (
crontab -lzeigtdb-backup.shundmatev-backup.sh)
Sobald Forgejo + Woodpecker stabil sind
Den docker save/docker load-Workflow ablösen durch:
- Forgejo-Container-Registry aktivieren (
Settings → Packages) - Woodpecker-Pipeline pushed Images automatisch (siehe Deployment)
apps/docker-compose.ymlreferenziertimage: git.matev.eu/matev/admin:developstattbuild:- Rollback per Image-Tag-Switch in
apps/docker-compose.yml(Git-tracked!)