2026-07-31 16:13:14 +02:00
|
|
|
# Deploy auf All-Inkl (Shared Hosting, SSH + Cronjobs)
|
|
|
|
|
|
|
|
|
|
Schritt für Schritt vom leeren Webspace zur Live-Seite. Die Reihenfolge ist Absicht:
|
|
|
|
|
**die alte CMS-Seite bleibt online, bis die neue auf einer geschützten Test-Subdomain
|
|
|
|
|
nachweislich läuft.** Umgeschaltet wird erst am Ende, und das Umschalten ist in einer
|
|
|
|
|
Minute rückgängig.
|
|
|
|
|
|
|
|
|
|
Der Kern des Plans: die Test-Subdomain läuft mit **derselben** `config.php`, die
|
|
|
|
|
später live geht. Es gibt keinen Config-Wechsel beim Umschalten, also auch keinen
|
|
|
|
|
Fehler, der sich dabei einschleichen kann. Möglich ist das, weil die
|
|
|
|
|
Host-Weiterleitung in `public/.htaccess` nur beim exakten Host `tsv08kulmbach.de`
|
|
|
|
|
greift; eine Subdomain läuft unbehelligt durch. Einzige Abweichung: Canonical, OG
|
|
|
|
|
und Sitemap nennen auf der Test-Subdomain schon die echte Domain. Genau richtig für
|
|
|
|
|
den Umschaltmoment, und dank Verzeichnisschutz sieht es ohnehin keine Suchmaschine.
|
|
|
|
|
|
|
|
|
|
Legende: `[lokal]` auf deinem Mac, `[SSH]` in der Server-Shell, `[KAS]` im
|
|
|
|
|
All-Inkl-Kundenmenü.
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## Teil A — Vorbereitung lokal
|
|
|
|
|
|
|
|
|
|
### A1 [lokal] Die zwei offenen Werte in `config/config.production.php` setzen
|
|
|
|
|
|
|
|
|
|
`php bin/preflight.php` bricht sonst auf dem Server ab. Beides betrifft nur die
|
|
|
|
|
Dateiablage `/dateien`, nicht die Website selbst.
|
|
|
|
|
|
|
|
|
|
**Passwörter für die zwei Zugänge.** Als Hash, nicht als Klartext:
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
php -r 'echo password_hash("DEIN-PASSWORT", PASSWORD_DEFAULT), "\n";'
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Ausgabe (beginnt mit `$2y$…`) in `dateien.users.verein.password_hash` bzw.
|
|
|
|
|
`dateien.users.admin.password_hash` eintragen. Zwei verschiedene Passwörter: `verein`
|
|
|
|
|
gibt der Verein weiter, `admin` behältst du.
|
|
|
|
|
|
|
|
|
|
**Lizenzschlüssel** der Files Gallery in `dateien.license_key`. Fehlt er, läuft die
|
|
|
|
|
Ablage trotzdem, zeigt aber den Hinweis der unlizenzierten Version (nur eine Warnung
|
|
|
|
|
in `preflight`, kein Blocker).
|
|
|
|
|
|
|
|
|
|
Bereits erledigt: `cron.key` ist auf `''` gesetzt und der Endpoint `public/cron.php`
|
|
|
|
|
damit zu. Der Takt kommt ab jetzt aus echten Cronjobs (Teil D), der Endpoint war nur
|
|
|
|
|
der Ersatz für den fehlenden Cron.
|
|
|
|
|
|
|
|
|
|
### A2 [lokal] Alles gepusht?
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
git status --porcelain # muss leer sein
|
|
|
|
|
git push origin main
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## Teil B — Server einrichten
|
|
|
|
|
|
|
|
|
|
### B1 [SSH] Umgebung feststellen und notieren
|
|
|
|
|
|
|
|
|
|
```bash
|
2026-07-31 16:28:58 +02:00
|
|
|
ssh ssh-w01ca75d@SERVER # SERVER = Hostname oder IP aus dem KAS
|
2026-07-31 16:21:09 +02:00
|
|
|
pwd # das Verzeichnis, in dem SSH startet
|
2026-07-31 16:13:14 +02:00
|
|
|
which php; php -v # PHP muss >= 8.1 sein
|
|
|
|
|
git --version
|
|
|
|
|
```
|
|
|
|
|
|
2026-07-31 16:19:22 +02:00
|
|
|
**Ergebnis vom 31.07.2026 auf diesem Webspace:**
|
|
|
|
|
|
|
|
|
|
| | |
|
|
|
|
|
|---|---|
|
2026-07-31 16:21:09 +02:00
|
|
|
| Webspace-Wurzel | `/www/htdocs/w01ca75d` |
|
2026-07-31 16:19:22 +02:00
|
|
|
| SITE | `/www/htdocs/w01ca75d/tsv08kulmbach-website` |
|
|
|
|
|
| PHP (CLI, für Cron) | `/usr/bin/php` — 8.3.29 |
|
|
|
|
|
| Composer | 2.9.8, global vorhanden |
|
|
|
|
|
| Alte CMS-Seite (Rückweg) | `/www/htdocs/w01ca75d/tsv08kulmbach.de` |
|
|
|
|
|
|
2026-07-31 16:21:09 +02:00
|
|
|
**Falle: `~` ist hier `/`, nicht der Webspace.** Das SSH-Konto hat die Systemwurzel
|
|
|
|
|
als Home-Verzeichnis, `cd ~` führt also aus dem Webspace heraus und `~/…`-Pfade
|
|
|
|
|
existieren nicht. Alle Pfade in dieser Anleitung sind deshalb absolut — auch das
|
|
|
|
|
`scp`-Ziel und die Cron-Zeilen.
|
|
|
|
|
|
|
|
|
|
All-Inkl legt pro Domain einen Ordner unter `/www/htdocs/<user>/` an, dieses
|
|
|
|
|
Verzeichnis selbst ist also kein Docroot. Der Ordnername `tsv08kulmbach.de` ist von der alten Seite belegt, deshalb
|
2026-07-31 16:19:22 +02:00
|
|
|
heißt der neue `tsv08kulmbach-website`. Die anderen TSV-Ordner
|
|
|
|
|
(`2024.`, `hall-of-fame.`, `kabinendienst.`, `kreisliga-reise.`) sind eigene
|
|
|
|
|
Subdomains und vom Umschalten nicht betroffen.
|
|
|
|
|
|
|
|
|
|
Achtung: das ist die **CLI**-Version. Welches PHP der Webserver nimmt, stellt KAS pro
|
|
|
|
|
Domain getrennt ein (Schritt C1).
|
2026-07-31 16:13:14 +02:00
|
|
|
|
|
|
|
|
### B2 [SSH] Repo klonen
|
|
|
|
|
|
|
|
|
|
```bash
|
2026-07-31 16:21:09 +02:00
|
|
|
cd /www/htdocs/w01ca75d
|
2026-07-31 16:19:22 +02:00
|
|
|
git clone https://onion.breadcrumb-online.de/fs/tsv08kulmbach-website.git tsv08kulmbach-website
|
|
|
|
|
cd tsv08kulmbach-website && pwd # diesen Pfad notieren: das ist SITE
|
2026-07-31 16:13:14 +02:00
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Der Klon lädt gut 460 MB (Website plus das Vereinsmaterial der Dateiablage), das
|
|
|
|
|
dauert ein paar Minuten. Die alte CMS-Seite liegt in einem anderen Verzeichnis und
|
|
|
|
|
wird nicht angefasst.
|
|
|
|
|
|
|
|
|
|
### B3 [SSH] `config.php` platzieren
|
|
|
|
|
|
|
|
|
|
Die Datei ist gitignored, also nicht im Klon. Vom Mac hochladen:
|
|
|
|
|
|
|
|
|
|
```bash
|
2026-07-31 16:28:58 +02:00
|
|
|
# [lokal], in einem zweiten Terminal.
|
|
|
|
|
# SERVER = derselbe Host wie beim ssh-Login (hier die Server-IP des Webspace).
|
2026-07-31 16:13:14 +02:00
|
|
|
scp config/config.production.php \
|
2026-07-31 16:28:58 +02:00
|
|
|
ssh-w01ca75d@SERVER:/www/htdocs/w01ca75d/tsv08kulmbach-website/config/config.php
|
2026-07-31 16:13:14 +02:00
|
|
|
```
|
|
|
|
|
|
2026-07-31 16:28:58 +02:00
|
|
|
Platzhalter bewusst ohne spitze Klammern: `<host>` liest die zsh als
|
|
|
|
|
Eingabe-Umleitung und bricht mit „no such file or directory" ab.
|
|
|
|
|
|
2026-07-31 16:13:14 +02:00
|
|
|
Wichtig: Ziel heißt `config.php`, nicht `config.production.php`. Danach [SSH]:
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
chmod 600 config/config.php # enthält SMTP-Passwort und app_secret
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### B4 [SSH] Composer-Abhängigkeiten
|
|
|
|
|
|
|
|
|
|
```bash
|
2026-07-31 16:21:09 +02:00
|
|
|
cd /www/htdocs/w01ca75d/tsv08kulmbach-website
|
2026-07-31 16:13:14 +02:00
|
|
|
composer install --no-dev --optimize-autoloader
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Kennt die Shell `composer` nicht, hol ihn dir lokal ins Verzeichnis:
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
curl -sS https://getcomposer.org/installer | php
|
|
|
|
|
php composer.phar install --no-dev --optimize-autoloader
|
|
|
|
|
rm composer.phar
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Es wird nur PHPMailer installiert.
|
|
|
|
|
|
|
|
|
|
### B5 [SSH] Schreibrechte prüfen
|
|
|
|
|
|
|
|
|
|
PHP läuft unter deinem Benutzer, meist passt es also schon. `preflight` sagt es dir
|
|
|
|
|
in Teil C4 verbindlich. Falls dort etwas fehlt:
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
chmod -R u+rwX storage
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Schreiben muss die Seite in `storage/logs`, `storage/cache`, `storage/ratelimit`,
|
|
|
|
|
`storage/dateien/uploads` und `storage/dateien/system`.
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## Teil C — Auf der Test-Subdomain prüfen
|
|
|
|
|
|
|
|
|
|
### C1 [KAS] Subdomain anlegen und schützen
|
|
|
|
|
|
|
|
|
|
1. **Domains** → Subdomain `neu.tsv08kulmbach.de` anlegen.
|
2026-07-31 16:19:22 +02:00
|
|
|
2. Als Verzeichnis **`/tsv08kulmbach-website/public`** eintragen, nicht das Repo-Root.
|
2026-07-31 16:13:14 +02:00
|
|
|
Damit liegen `app/`, `config/`, `data/`, `storage/` und `vendor/` außerhalb des
|
|
|
|
|
Docroots und sind grundsätzlich nicht per URL erreichbar. (Die Root-`.htaccess`
|
|
|
|
|
ist nur ein Notnagel für Hoster, die das nicht können.)
|
|
|
|
|
3. **PHP-Version** für die Subdomain auf 8.1 oder neuer stellen.
|
|
|
|
|
4. **SSL** aktivieren (Let's Encrypt). Ohne Zertifikat läuft die Seite in eine
|
|
|
|
|
Endlosweiterleitung, denn `public/.htaccess` erzwingt HTTPS.
|
|
|
|
|
5. **Verzeichnisschutz** für die Subdomain einschalten (Basic Auth). Das ist der
|
|
|
|
|
Grund, warum hier nichts indexiert werden kann. Nicht weglassen.
|
|
|
|
|
|
|
|
|
|
### C2 Erreichbarkeit
|
|
|
|
|
|
|
|
|
|
`https://neu.tsv08kulmbach.de` aufrufen. Nach der Passwortabfrage muss die
|
|
|
|
|
Startseite kommen. Weißes Blatt oder 500er? Dann [SSH]
|
|
|
|
|
`tail -30 storage/logs/php-errors.log`.
|
|
|
|
|
|
|
|
|
|
### C3 [SSH] Datenstände erzeugen
|
|
|
|
|
|
|
|
|
|
`data/matchcenter.json` und `data/instagram.json` sind bewusst nicht im Repo, die
|
|
|
|
|
holen die Syncs. Vor dem ersten Lauf fehlen Tabellen, Spiele und der
|
|
|
|
|
Instagram-Block (die Seite bricht deswegen nicht, sie zeigt Ersatzinhalte).
|
|
|
|
|
|
|
|
|
|
```bash
|
2026-07-31 16:21:09 +02:00
|
|
|
cd /www/htdocs/w01ca75d/tsv08kulmbach-website
|
2026-07-31 16:13:14 +02:00
|
|
|
php bin/matchcenter-sync.php # Spiele, Ergebnisse, Tabellen, Wappen
|
|
|
|
|
php bin/instagram-sync.php # Posts und Bilder
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**Der Instagram-Lauf ist der Wackelkandidat des ganzen Deploys.** Instagram sperrt
|
|
|
|
|
Rechenzentrums-IPs; bisher lief der Scraper nur über einen privaten Anschluss.
|
|
|
|
|
Schlägt er hier fehl, ist das kein Fehler im Deploy: dann bleibt der Weg, ihn von
|
|
|
|
|
zu Hause laufen zu lassen und `data/instagram.json` samt Bildern hochzuladen, oder
|
|
|
|
|
der Block wird redaktionell gepflegt. Die Website funktioniert in jedem Fall.
|
|
|
|
|
|
|
|
|
|
### C4 [SSH] `preflight` bis null Fehler
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
php bin/preflight.php; echo "Exit: $?"
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Ziel ist **Exit 0**. Warnungen darfst du bewerten, Fehler nicht. Erwartbare
|
|
|
|
|
Warnungen hier: der Hinweis, dass `cron.key` leer ist (richtig so, siehe A1) und
|
|
|
|
|
die Uploadgrenze, die erst ein echter Upload beweist (C6).
|
|
|
|
|
|
|
|
|
|
### C5 Durchklicken
|
|
|
|
|
|
|
|
|
|
Die Seiten, die eigene Datenquellen haben:
|
|
|
|
|
|
|
|
|
|
- [ ] Startseite: Banner-Slider, Termin-Karte im Hero, Instagram-Block
|
|
|
|
|
- [ ] `/matchcenter`: Tabellen und nächste Spiele mit Wappen
|
|
|
|
|
- [ ] `/termine`, `/news`, `/veranstaltungen` plus eine Detailseite
|
|
|
|
|
- [ ] `/stadionzeitung` und die Ausgabe durchswipen — **alle Wappen und
|
|
|
|
|
Instagram-Bilder da?** (Sie liegen im Repo, sollten also stimmen.)
|
|
|
|
|
- [ ] `/stadionzeitung/aktuell` landet auf der neuesten Ausgabe
|
|
|
|
|
- [ ] Die Druckfassung einer Ausgabe (`?druck=1`)
|
|
|
|
|
- [ ] `/impressum`: Webadresse zeigt `www.tsv08kulmbach.de`, nicht die Subdomain
|
|
|
|
|
|
|
|
|
|
### C6 Dateiablage und Mailversand
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
php bin/dateien-init.php # Jahr/Abteilung-Ordner, MUSS auf dem Server laufen
|
|
|
|
|
php bin/smtp-test.php # nur Verbindung und Login, kein Versand
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
`dateien-init.php` gehört auf den Server, weil Umlaute per FTP zu Doppelordnern
|
|
|
|
|
führen (macOS NFD gegen Linux NFC).
|
|
|
|
|
|
|
|
|
|
- [ ] `/dateien` mit beiden Zugängen anmelden
|
|
|
|
|
- [ ] Eine große Datei hochladen (>10 MB) — beweist die 250-MB-Grenze
|
|
|
|
|
- [ ] Ein Formular abschicken (z. B. `/kontakt`) und die Mail im Postfach prüfen
|
|
|
|
|
- [ ] `php bin/logs.php` zeigt keine Fehler
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## Teil D — Cronjobs
|
|
|
|
|
|
|
|
|
|
Erst jetzt, damit ab dem Umschalten schon frische Daten liegen. `SITE` und der
|
|
|
|
|
PHP-Pfad kommen aus B1/B2.
|
|
|
|
|
|
|
|
|
|
[KAS] → **Cronjobs** → eigener Cronjob (Shell), vier Einträge:
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
# Instagram 2x/Tag
|
|
|
|
|
17 6,18 * * * cd SITE && PHP bin/instagram-sync.php >> storage/logs/instagram.log 2>&1
|
|
|
|
|
|
|
|
|
|
# Matchcenter Grundtakt 2x/Tag
|
|
|
|
|
37 7,19 * * * cd SITE && PHP bin/matchcenter-sync.php >> storage/logs/matchcenter.log 2>&1
|
|
|
|
|
|
|
|
|
|
# Matchcenter am Spieltag halbstuendlich (Sa+So 13-21 Uhr)
|
|
|
|
|
7,37 13-21 * * 6,0 cd SITE && PHP bin/matchcenter-sync.php >> storage/logs/matchcenter.log 2>&1
|
|
|
|
|
|
|
|
|
|
# Logpflege sonntags nachts
|
|
|
|
|
23 3 * * 0 cd SITE && PHP bin/log-rotate.php > /dev/null 2>&1
|
|
|
|
|
```
|
|
|
|
|
|
2026-07-31 16:19:22 +02:00
|
|
|
`SITE` und `PHP` durch die echten absoluten Pfade ersetzen, auf diesem Webspace also
|
|
|
|
|
`cd /www/htdocs/w01ca75d/tsv08kulmbach-website && /usr/bin/php bin/…`. Die Minuten sind
|
2026-07-31 16:13:14 +02:00
|
|
|
versetzt, damit sich zwei Läufe nicht überlappen. Alle Skripte sind CLI-only,
|
|
|
|
|
sperren sich per Lock gegen Parallelläufe und lassen bei Fehlern den letzten guten
|
|
|
|
|
Cache stehen — ein fehlgeschlagener Lauf schadet nie.
|
|
|
|
|
|
|
|
|
|
Am Tag nach dem ersten Cron-Lauf einmal `php bin/logs.php` ansehen. Läuft nichts,
|
|
|
|
|
ist fast immer der PHP-Pfad falsch oder relativ.
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## Teil E — Umschalten auf die Hauptdomain
|
|
|
|
|
|
|
|
|
|
Ab hier ist die Seite öffentlich. Alles davor muss sitzen.
|
|
|
|
|
|
|
|
|
|
### E1 Sicherheitsnetz
|
|
|
|
|
|
|
|
|
|
Notiere, auf welches Verzeichnis `www.tsv08kulmbach.de` **jetzt** zeigt (die alte
|
|
|
|
|
CMS-Seite). Das ist dein Rückweg. Verzeichnis und Datenbank der alten Seite bleiben
|
|
|
|
|
unangetastet, nicht löschen.
|
|
|
|
|
|
|
|
|
|
### E2 [KAS] Domain umstellen
|
|
|
|
|
|
|
|
|
|
**Domains** → `tsv08kulmbach.de` und `www.tsv08kulmbach.de` auf
|
2026-07-31 16:19:22 +02:00
|
|
|
**`/tsv08kulmbach-website/public`** zeigen lassen. PHP-Version prüfen, SSL muss für beide
|
2026-07-31 16:13:14 +02:00
|
|
|
aktiv sein.
|
|
|
|
|
|
|
|
|
|
### E3 Sofort danach prüfen
|
|
|
|
|
|
|
|
|
|
- [ ] `https://www.tsv08kulmbach.de` lädt
|
|
|
|
|
- [ ] `http://tsv08kulmbach.de` (ohne www, ohne s) landet per 301 auf
|
|
|
|
|
`https://www.tsv08kulmbach.de`
|
|
|
|
|
- [ ] `/sitemap.xml` und `/robots.txt` erreichbar
|
|
|
|
|
- [ ] `curl -sI https://www.tsv08kulmbach.de | head` — Statuszeile 200, kein
|
|
|
|
|
Redirect-Loop
|
|
|
|
|
- [ ] Ein Formular live abschicken
|
|
|
|
|
- [ ] **Einen gedruckten QR-Code mit dem Handy scannen.** Der Code der
|
|
|
|
|
Stadionzeitung zeigt auf `www.tsv08kulmbach.de/stadionzeitung/aktuell`.
|
|
|
|
|
Scannen ist die einzige echte Prüfung: die QR-Bibliothek arbeitet nicht
|
|
|
|
|
reproduzierbar, ein Bildvergleich beweist nichts.
|
|
|
|
|
|
|
|
|
|
### E4 Verzeichnisschutz der Test-Subdomain lassen
|
|
|
|
|
|
|
|
|
|
Nicht entfernen. Sonst steht die Seite zweimal im Netz und Google sieht doppelten
|
|
|
|
|
Inhalt. Wenn du die Subdomain nicht mehr brauchst, in KAS löschen.
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## Teil F — Danach
|
|
|
|
|
|
|
|
|
|
### F1 Der Update-Ablauf ab jetzt
|
|
|
|
|
|
|
|
|
|
**Die Reihenfolge ist nicht verhandelbar**, weil `storage/dateien/uploads/` im Repo
|
|
|
|
|
liegt und andere Menschen dort hochladen:
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
# 1. [SSH] auf dem Server: neue Uploads sichern
|
2026-07-31 16:21:09 +02:00
|
|
|
cd /www/htdocs/w01ca75d/tsv08kulmbach-website
|
2026-07-31 16:13:14 +02:00
|
|
|
git add -A storage/dateien/uploads && git commit -m "Uploads vom Server" && git push
|
|
|
|
|
|
|
|
|
|
# 2. [lokal] holen, dann entwickeln
|
|
|
|
|
git pull
|
|
|
|
|
|
|
|
|
|
# 3. [lokal] fertig, gepusht → [SSH] ausrollen
|
2026-07-31 16:21:09 +02:00
|
|
|
cd /www/htdocs/w01ca75d/tsv08kulmbach-website && git pull && php bin/preflight.php
|
2026-07-31 16:13:14 +02:00
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Nie in der anderen Reihenfolge. Details und Begründung in CLAUDE.md, Abschnitt
|
|
|
|
|
Dateiablage.
|
|
|
|
|
|
|
|
|
|
Ändert sich `composer.json`, gehört ein `composer install --no-dev
|
|
|
|
|
--optimize-autoloader` dazu. Neue Formularfelder heißen: Datenschutzerklärung
|
|
|
|
|
mitziehen.
|
|
|
|
|
|
|
|
|
|
### F2 Rückweg, falls etwas Grundlegendes bricht
|
|
|
|
|
|
|
|
|
|
[KAS] Domain zurück auf das alte Verzeichnis aus E1. Nach ein paar Minuten ist die
|
|
|
|
|
alte Seite wieder da. Kein Datenverlust, weil die neue Seite in einem eigenen
|
|
|
|
|
Verzeichnis liegt und die alte Datenbank nicht anfasst.
|
|
|
|
|
|
|
|
|
|
### F3 Offen, nach dem Livegang
|
|
|
|
|
|
|
|
|
|
- **301-Weiterleitungen der alten URLs.** Die neue Seite hat andere Slugs; alte
|
|
|
|
|
Google-Treffer und fremde Links laufen ins Leere. Die alten Adressen stehen im
|
|
|
|
|
DB-Dump unter `.context_db`. Aufwand lohnt für die paar wichtigen Seiten, nicht
|
|
|
|
|
für alle.
|
|
|
|
|
- **Google Search Console:** Property anlegen, `sitemap.xml` einreichen.
|
|
|
|
|
- **Instagram-Sync** beobachten, siehe C3.
|
|
|
|
|
- Nach dem Sportfest (ab 07.09.2026) fallen zwei Anzeigen per `bis`-Datum aus dem
|
|
|
|
|
Bestand, die Stadionzeitung hat dann 38 Seiten statt 40 und ist nicht mehr durch
|
|
|
|
|
4 teilbar. `bin/stadionzeitung-add.php` warnt beim nächsten Lauf.
|