b2in/dev/2026-08-28/preview-deployment.md
Kevin Adametz c8899e2d7d Markenlogos einbinden: Seitenkopf und alle Kacheln
Zulieferung dev/2026-08-28/markenlogos/ (CABINET und Rotpunkt als SVG, Februe
als PNG). Die Dateien liegen unter public/img/assets/marken/ und haengen als
`logo` an der jeweiligen Marke.

- Kopf der Markenseite: Logo anstelle des Schriftzugs, im <h1>, damit die
  Ueberschrift erhalten bleibt – den Text liefert das alt-Attribut. Ohne Logo
  erscheint weiterhin der Schriftzug.
- Logo zusaetzlich auf der Startseiten-Kachel, im Block auf /marken und in den
  „Weitere Marken“-Kacheln am Seitenfuss.
- Feste Box (Hoehe + Maximalbreite + object-contain) statt fester Hoehe: die
  Seitenverhaeltnisse gehen weit auseinander (Februe 2,3:1, Rotpunkt 1,2:1),
  mit reiner Hoehenangabe waere Februe doppelt so breit erschienen. Konvention
  aus der Sponsoring-Sektion.
- Februe-Logo auf seinen Inhalt beschnitten: im Original waren knapp drei
  Viertel der Flaeche leerer Rand, in einer Box haette es winzig gewirkt.
  53 KB → 15 KB.
- BrandLogoSeeder traegt die Logos auf bestehenden Installationen nach –
  CmsBrandSeeder ueberspringt vorhandene Marken. Setzt nur `logo` und nur bei
  leerem Feld, ein im Admin hochgeladenes Logo bleibt stehen.

Tests: 871 gruen (3215 Assertions), Pint sauber, alle Themes gebaut.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-03 11:16:41 +00:00

12 KiB
Raw Blame History

Vorschau-Instanz auf dem Live-Server einrichten

Ziel: https://preview.b2in.eu zeigt den neuen Stand zur Abstimmung. Die Live-Seite bleibt unangetastet – es wird keine einzige Datei im Live-Verzeichnis überschrieben und keine Zeile in der Live-Datenbank geändert.

Prinzip: zweites, eigenständiges Verzeichnis · eigene .env · eigene Datenbank.

/var/www/b2in/          ← Live, bleibt wie es ist
/var/www/b2in-preview/  ← Kopie davon, darauf das Update

Pfade unten sind Beispiele. Ersetze /var/www/b2in durch das echte Live-Verzeichnis und b2in_live / b2in_preview durch die echten Datenbanknamen.


0. Warum nicht einfach die Live-Dateien tauschen

Zwei Gründe, die diesen Aufwand rechtfertigen:

  1. Der Relaunch-Seeder überschreibt CMS-Sektionen. InteriorRelaunchCmsSeeder schreibt 23 Sektionen mit den neuen Texten. Auf der Live-Datenbank ausgeführt wäre der alte Stand weg.
  2. Migrationen sind nicht umkehrbar. cms_brands und die beiden Spalten summary / highlights kommen neu dazu.

Mit einer eigenen Datenbank kann beim Testen nichts passieren, was die Live-Seite betrifft.


1. Voraussetzungen

  • DNS-Eintrag preview.b2in.eu → dieselbe Server-IP wie b2in.eu
  • SSL-Zertifikat für die Subdomain (Let's Encrypt genügt)
  • vhost mit DocumentRoot /var/www/b2in-preview/public
  • Zweite MySQL-Datenbank plus Benutzer
  • Genug Plattenplatz für eine Kopie des Live-Verzeichnisses (vor allem storage/)

2. Sicherung ziehen

Auch wenn wir live nichts anfassen – der Dump ist zugleich die Grundlage für die Vorschau-DB.

cd /var/www/b2in
mysqldump -u USER -p b2in_live > ~/b2in_live_$(date +%F_%H%M).sql
ls -lh ~/b2in_live_*.sql   # Größe prüfen, darf nicht 0 sein

3. Vorschau-Verzeichnis anlegen

Kopie des Live-Standes, inklusive vendor/. Das erspart ein composer install auf dem Server – für livewire/flux-pro bräuchte es sonst die Zugangsdaten aus auth.json.

cp -a /var/www/b2in /var/www/b2in-preview
cd /var/www/b2in-preview

# Laufzeit-Reste der Kopie entfernen
rm -rf bootstrap/cache/*.php
rm -f  public/storage            # Symlink wird in Schritt 7 neu gesetzt

Zu storage/app/public (Medienbibliothek, Display-Videos): Durch cp -a liegt eine echte Kopie in der Vorschau – sauber getrennt, kostet aber den Speicherplatz. Wenn das zu groß ist:

rm -rf storage/app/public
ln -s /var/www/b2in/storage/app/public storage/app/public

⚠️ Mit dem Symlink landen Uploads aus der Vorschau in den Live-Dateien. Zum Anschauen in Ordnung, zum Testen von Uploads nicht. Im Zweifel kopieren.


4. .env der Vorschau anpassen

Der wichtigste Schritt. Der ThemeServiceProvider sucht den aufgerufenen Host in config/domains.php und setzt URL::forceRootUrl() samt Asset-Origin auf die dort hinterlegte URL. Fehlt DOMAIN_B2IN_URL, greift der Vorgabewert https://b2in.test – eine Domain, die es im Internet nicht gibt. Dann laden Bilder, Favicon und livewire.min.js nicht mehr.

cd /var/www/b2in-preview
nano .env

Diese Werte ändern:

APP_ENV=preview
APP_DEBUG=false
APP_URL=https://preview.b2in.eu
APP_DOMAIN_NAME=preview.b2in.eu

# Vorschau-Domain, damit Routing, Links und Assets stimmen
DOMAIN_B2IN=preview.b2in.eu
DOMAIN_B2IN_URL=https://preview.b2in.eu

# Assets ebenfalls auf die Vorschau-Domain, sonst laedt der Browser sie von woanders
ASSET_URL=https://preview.b2in.eu

# Eigene Datenbank
DB_DATABASE=b2in_preview
DB_USERNAME=…
DB_PASSWORD=…

# Eigener Cache-/Session-Namensraum, damit sich Live und Vorschau nicht ins Gehege kommen
CACHE_PREFIX=b2in_preview
SESSION_COOKIE=b2in_preview_session

# Keine Mails aus der Vorschau verschicken
MAIL_MAILER=log

APP_ENV=preview sorgt automatisch für noindex, nofollow in jeder Seite (config/app.php → app.indexable). Wer ganz sichergehen will, setzt zusätzlich SITE_INDEXABLE=false.

Nicht ändern: APP_KEY – sonst sind verschlüsselte Werte in der kopierten Datenbank nicht mehr lesbar.


5. Datenbank der Vorschau befüllen

mysql -u USER -p -e "CREATE DATABASE b2in_preview CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
mysql -u USER -p b2in_preview < ~/b2in_live_JJJJ-MM-TT_HHMM.sql

Gegenprobe, dass die Vorschau wirklich auf ihrer eigenen DB steht:

cd /var/www/b2in-preview
php artisan tinker --execute="echo config('database.connections.mysql.database');"
# muss b2in_preview ausgeben – wenn hier b2in_live steht: STOPP

6. Update einspielen

Das Archiv dev/2026-08-28/deploy/b2in-interior-update.tar.gz enthält genau die geänderten und neuen Dateien plus die gebauten Assets (public/build/b2in, public/build/portal). Node wird auf dem Server nicht gebraucht. Die enthaltene Dateiliste steht in deploy/dateiliste.txt.

# Archiv hochladen, dann:
cd /var/www/b2in-preview
tar xzf ~/b2in-interior-update.tar.gz

Das Archiv enthält bewusst keine .env, kein vendor/ und nichts aus storage/.


7. Artisan-Schritte

cd /var/www/b2in-preview

php artisan config:clear
php artisan storage:link

php artisan migrate --force        # legt cms_brands an, ergänzt summary/highlights

# Kernmarken anlegen – überschreibt nichts, was schon gepflegt ist
php artisan db:seed --class=CmsBrandSeeder --force

# Die neuen Texte ins CMS: genau die 23 umgetexteten Sektionen
php artisan db:seed --class=InteriorRelaunchCmsSeeder --force

# Magazin: die zwei neuen Beiträge plus Reihenfolge
php artisan db:seed --class=CmsArticleSeeder --force

# Markenseiten CABINET, Rotpunkt und Febrü – nur Textfelder, Bilder und Galerie bleiben
php artisan db:seed --class=BrandPageTextSeeder --force

# Entfernt den Vermerk „BEISPIEL – “ aus vorhandenen Bildunterschriften (Nachtrag 5).
# Nur nötig, wenn die Demogalerien schon eingespielt sind. Mehrfach ausführbar.
php artisan db:seed --class=BrandGalleryCaptionNormalizerSeeder --force

# Markenlogos nachtragen. Setzt `logo` nur, wenn das Feld leer ist.
php artisan db:seed --class=BrandLogoSeeder --force

# Display-Branding auf das Interior-Logo
php artisan db:seed --class=DisplayInteriorBrandingSeeder --force

# Medien-URLs host-unabhängig (sonst zeigen vier Playlists auf b2in.test)
php artisan db:seed --class=DisplayMediaUrlNormalizerSeeder --force

php artisan config:cache
php artisan route:cache
php artisan view:clear

Assets: Das Archiv bringt public/build/b2in fertig mit. Wird auf dem Server selbst gebaut, gilt: npm run build:web baut nur die vier Frontend-Themes, nicht das Portal. Ohne npm run build:portal liefert das Admin-Portal danach 500.

Optional, nur für die Abstimmung: Beispielbilder in die Markengalerien, damit Galerie, Referenzen-Seite und Lightbox nicht leer sind.

⚠️ Es sind Stockmotive und KI-Renderings, kein einziges echtes Projekt. Der frühere Vermerk „BEISPIEL" in der Bildunterschrift ist auf Kundenwunsch entfallen – die Bilder der Rubrik „Realisiertes Projekt" geben sich damit als echte Referenzen aus. Für die Abstimmung in Ordnung, vor dem Livegang zwingend ersetzen.

php artisan db:seed --class=DemoBrandGallerySeeder --force

Wieder entfernen:

php artisan tinker --execute="App\Models\CmsBrand::query()->update(['gallery' => null]);"

8. Vorschau abschirmen

Suchmaschinen – noindex kommt schon aus APP_ENV=preview, die robots.txt gehört zusätzlich umgestellt:

printf 'User-agent: *\nDisallow: /\n' > /var/www/b2in-preview/public/robots.txt

Passwortschutz (empfohlen, damit die Vorschau nicht zufällig gefunden wird):

htpasswd -c /etc/apache2/.htpasswd-preview vorschau

Apache:

<Directory /var/www/b2in-preview/public>
    AuthType Basic
    AuthName "B2in Vorschau"
    AuthUserFile /etc/apache2/.htpasswd-preview
    Require valid-user
</Directory>

Nginx:

auth_basic "B2in Vorschau";
auth_basic_user_file /etc/nginx/.htpasswd-preview;

9. Prüfen

Seite Erwartung
/ Hero → Marken-Teaser → Vision → Sponsoring → Showroom-Display → Immobilien → CTA
/marken Grauer Seitenkopf mit Bild, drei gerahmte Markenblöcke
/marken/cabinet Detailseite, Galerie mit den zwei Rubriken (falls Demo-Seeder lief)
/marken/rotpunkt Neun Abschnitte, vier davon mit aufklappbarer Vertiefung; Button unten rechts heißt „Persönliche Küchenberatung vereinbaren"
/marken/februe Elf Abschnitte, Zitat von Marcel; Button heißt „Persönliche Arbeitsplatzberatung vereinbaren"
/referenzen Realisierte Projekte, darunter das Showroom-Display im Hochformat
/magazin Die zwei Interior-Beiträge stehen oben
/faq Rubriken „Für Ihr Zuhause" und „Für Projekte und Objekte"
/about Werte: Beratung statt Verkauf, Maßarbeit, …
/contact Betreffliste beginnt mit Beratungstermin
/immobilien unverändert

Und diese vier Punkte:

  • Terminanfrage-Widget unten rechts öffnet sich, Absenden zeigt die Bestätigung
  • Alle Links bleiben auf preview.b2in.eu – springt einer auf b2in.eu, stimmt Schritt 4 nicht
  • Seitenquelltext enthält <meta name="robots" content="noindex, nofollow">
  • Die Live-Seite https://b2in.eu sieht unverändert aus

10. Aufräumen

Vorschau wieder abbauen:

rm -rf /var/www/b2in-preview
mysql -u USER -p -e "DROP DATABASE b2in_preview;"
# vhost und DNS-Eintrag entfernen

Beim späteren echten Livegang gilt Abschnitt 8 des Entwicklungsplans, nicht dieses Dokument. Vorher offen: Rechtstexte, OG-Bild, Seeder-Passwort rotieren.


Wenn etwas nicht stimmt

Symptom Ursache
„Kein Server mit dem angegebenen Hostnamen gefunden" für Bilder, Favicon, livewire.min.js DOMAIN_B2IN_URL fehlt oder ist falsch geschrieben → Vorgabewert https://b2in.test. Siehe Diagnose unten.
Links springen auf b2in.eu DOMAIN_B2IN / DOMAIN_B2IN_URL in Schritt 4 nicht gesetzt, oder config:cache fehlt
Seite ohne Styles public/build/b2in fehlt – Archiv nicht vollständig entpackt
„Vite manifest not found" dasselbe, oder build/portal fehlt für das Admin-Panel
Bilder fehlen php artisan storage:link vergessen, oder storage/app/public nicht mitkopiert
Display-Kachel bleibt leer Kein aktives Display mit veröffentlichter Playlist – dann wird die Sektion bewusst gar nicht angezeigt
Änderungen wirken nicht php artisan config:clear && php artisan config:cache

Diagnose: Assets zeigen auf den falschen Host

cd /var/www/b2in-preview

# 1. Was steht in der .env?
grep -E '^(APP_ENV|APP_URL|APP_DOMAIN_NAME|ASSET_URL|DOMAIN_B2IN|DOMAIN_B2IN_URL)=' .env

# 2. Was macht die Anwendung daraus? (zeigt den zwischengespeicherten Stand)
php artisan tinker --execute="echo config('domains.domains.b2in.domain_name').' -> '.config('domains.domains.b2in.url').PHP_EOL;"

# 3. Liegt ein alter Config-Cache herum?
ls -l bootstrap/cache/config.php 2>/dev/null

Steht in Zeile 2 etwas mit .test, fehlen die beiden DOMAIN_B2IN*-Zeilen. Beheben:

cd /var/www/b2in-preview
php artisan config:clear     # zuerst den Cache weg, sonst wirkt die .env nicht
nano .env                    # DOMAIN_B2IN, DOMAIN_B2IN_URL, ASSET_URL, APP_URL setzen
php artisan config:cache
php artisan view:clear

Sicherheitsnetz seit dieser Runde: Findet der ThemeServiceProvider den aufgerufenen Host nicht in der Konfiguration, verwendet er außerhalb von APP_ENV=production den tatsächlich aufgerufenen Origin – die Vorschau verlinkt sich dann auf sich selbst statt auf eine fremde Domain. In production bleibt es bei der konfigurierten URL, damit ein gefälschter Host-Header keine Links auf fremde Domains erzeugen kann. Die .env sollte trotzdem stimmen.