Setzt die vier Punkte aus dev/2026-08-28/umsetzung-03-09-2026.md um.
1. Markenseiten
- Rotpunkt und Febrü auf die korrigierten Fassungen (*_FINAL.md) gebracht:
bei Rotpunkt sind die beiden Nachhaltigkeitsabschnitte zusammengefuehrt,
bei Febrü behaelt der Blaue-Engel-Satz seinen Produktbezug ohne den
erklaerenden Zusatz.
- CABINET nach demselben Muster neu verfasst: 8 Abschnitte, 3 Vertiefungen,
eigener Abschlussblock und eigene Widget-Beschriftung. Bewusst ohne Zahlen,
Zertifizierungen oder Herstelleraussagen – dafuer gibt es keine Quelle.
Braucht Marcels Freigabe.
- Febrü-Claim korrigiert: „Arbeiten, wo man gerne bleibt.“
2. „BEISPIEL“-Vermerk aus den Bildunterschriften entfernt. Weil die Demobilder
auf Vorschau und Live bereits in der Datenbank stehen, entfernt
BrandGalleryCaptionNormalizerSeeder ihn dort in-place – nur der Text, Bild,
Kategorie und Reihenfolge bleiben unberuehrt.
3. Hinweise zu Visualisierungen neu formuliert (Markengalerie und /referenzen).
Die Trennung bleibt, sie laeuft nur nicht mehr ueber eine Verneinung.
4. Abschluss-CTA der Markenseiten ueberarbeitet: weiche Lichtflaechen statt
Vollton, gesetzter Hauptbutton mit Pfeil, Herstellerseite als gleichwertiger
Outline-Button, Showroom als Fusszeile.
Ein Pruefskript hat jeden veroeffentlichten Satz gegen die abgestimmten
Markdown-Fassungen gehalten: keine Abweichung.
Tests: 859 gruen (3180 Assertions), Pint sauber, npm run build:b2in gebaut.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
336 lines
11 KiB
Markdown
336 lines
11 KiB
Markdown
# 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.
|
||
|
||
```bash
|
||
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`.
|
||
|
||
```bash
|
||
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:
|
||
|
||
```bash
|
||
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.
|
||
|
||
```bash
|
||
cd /var/www/b2in-preview
|
||
nano .env
|
||
```
|
||
|
||
Diese Werte ändern:
|
||
|
||
```dotenv
|
||
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
|
||
|
||
```bash
|
||
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:
|
||
|
||
```bash
|
||
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`.
|
||
|
||
```bash
|
||
# 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
|
||
|
||
```bash
|
||
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
|
||
|
||
# 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
|
||
```
|
||
|
||
**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**.
|
||
|
||
```bash
|
||
php artisan db:seed --class=DemoBrandGallerySeeder --force
|
||
```
|
||
|
||
Wieder entfernen:
|
||
|
||
```bash
|
||
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:
|
||
|
||
```bash
|
||
printf 'User-agent: *\nDisallow: /\n' > /var/www/b2in-preview/public/robots.txt
|
||
```
|
||
|
||
**Passwortschutz** (empfohlen, damit die Vorschau nicht zufällig gefunden wird):
|
||
|
||
```bash
|
||
htpasswd -c /etc/apache2/.htpasswd-preview vorschau
|
||
```
|
||
|
||
Apache:
|
||
|
||
```apache
|
||
<Directory /var/www/b2in-preview/public>
|
||
AuthType Basic
|
||
AuthName "B2in Vorschau"
|
||
AuthUserFile /etc/apache2/.htpasswd-preview
|
||
Require valid-user
|
||
</Directory>
|
||
```
|
||
|
||
Nginx:
|
||
|
||
```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:
|
||
|
||
```bash
|
||
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
|
||
|
||
```bash
|
||
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:
|
||
|
||
```bash
|
||
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.
|