Git-Deploy per Tag, Betriebsüberwachung und Release-Seeder für den Livegang

- dev/betrieb/deploy.sh: Deploy nur per Tag, mit --seed (Seeder im Wartungsmodus)
  und --initial (Vorschau/Live einmalig an Ort und Stelle auf Git umstellen)
- dev/betrieb/vorschau-auffrischen.sh: Live-DB und Live-Medien in die Vorschau (Generalprobe)
- InteriorReleaseSeeder: alle Inhaltsschritte des Relaunchs in einem Lauf, idempotent;
  Displays, Playlists und Mediathek bleiben unberührt
- DisplayInteriorBrandingSeeder überschreibt keinen inzwischen gepflegten Claim mehr
- Monitoring: GlitchTip (Server + Browser), /health mit Token, Scheduler-Herzschlag,
  Alarme per Mail und ntfy, Version in about und /health
- public/build versioniert; .gitignore: macOS-Muster Icon traf resources/views/flux/icon/
- Runbook: dev/betrieb/README.md

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Kevin Adametz 2026-10-09 08:56:23 +00:00
parent fcb10be120
commit b5ed756d67
98 changed files with 3947 additions and 82 deletions

View file

@ -1,14 +1,25 @@
<?php
use App\Http\Controllers\HealthController;
use App\Http\Middleware\ReportErrorSignals;
use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Exceptions;
use Illuminate\Foundation\Configuration\Middleware;
use Illuminate\Support\Facades\Route;
use Sentry\Laravel\Integration;
use Symfony\Component\Console\Exception\CommandNotFoundException;
return Application::configure(basePath: dirname(__DIR__))
->withRouting(
web: __DIR__.'/../routes/domains.php',
commands: __DIR__.'/../routes/console.php',
health: '/up',
then: function (): void {
// Tiefer Health-Check für den externen Monitor (Uptime Kuma), auf jeder Domain
Route::get('/health', HealthController::class)
->middleware('throttle:30,1')
->name('health.deep');
},
)
->withMiddleware(function (Middleware $middleware) {
// Traefik Reverse-Proxy vertraut die X-Forwarded-Proto/For Headers
@ -27,11 +38,20 @@ return Application::configure(basePath: dirname(__DIR__))
'partner.setup' => \App\Http\Middleware\EnsurePartnerSetupCompleted::class,
]);
// Fehler ohne Exception (toter interner Link, 403/429 für Angemeldete, 419) –
// global, weil 404 vor dem Routing entsteht
$middleware->append(ReportErrorSignals::class);
// BasicAuth ganz am Ende, nach Session-Middleware
if (env('BASIC_AUTH_ENABLED', true)) {
$middleware->append(\App\Http\Middleware\BasicAuthMiddleware::class);
}
})
->withExceptions(function (Exceptions $exceptions) {
//
// Gemeldete Exceptions an GlitchTip (ohne DSN ein No-op);
// Laravels dontReport (404, Validierung, Auth) gilt weiter
Integration::handles($exceptions);
// Vertippte artisan-Befehle sind kein Anwendungsfehler
$exceptions->dontReport(CommandNotFoundException::class);
})->create();