feat: add Docker deployment, web installer, and local test environment

- Multi-stage Dockerfiles for API (NestJS) and Web (Next.js standalone)
- docker-compose.prod.yml: full production stack (postgres, redis, keycloak,
  api, web) with optional Caddy/Let's Encrypt via --profile ssl
- docker-compose.local.yml: identical local test stack, all ports exposed
- docker/postgres/init.sql: auto-creates tos_app DB on first start
- Caddyfile: reverse proxy for app domain + auth subdomain
- install.sh: interactive installer (domain, SSL mode, secret generation)
- NestJS SetupModule: @Public() endpoints for /setup/status, /setup/admin,
  /setup/branding, /setup/complete with setup-token guard
- Web installer: 4-step flow (system check, admin creation, branding, complete)
  at /[locale]/setup/* with public middleware bypass
- i18n: installer namespace added to de.json and en.json
- CORS: x-setup-token header allowed in main.ts

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-23 21:17:34 +01:00
parent b1238b7bb8
commit 0e8d5aef85
31 changed files with 2158 additions and 4 deletions

View File

@@ -1073,5 +1073,63 @@
"saveError": "Fehler beim Speichern der Einstellungen",
"requiresRestart": "Aenderung erfordert einen Neustart des Backends",
"save": "Speichern"
},
"installer": {
"title": "tOS Einrichtung",
"setupComplete": "Einrichtung abgeschlossen",
"notAccessible": "Nach der Einrichtung ist dieser Bereich nicht mehr zugaenglich.",
"steps": {
"systemCheck": "Systempruefung",
"adminSetup": "Admin-Account",
"branding": "Branding",
"complete": "Abschluss"
},
"systemCheck": {
"title": "Systemueberpruefung",
"description": "Alle Dienste werden auf Erreichbarkeit geprueft.",
"api": "API-Server",
"database": "Datenbank",
"keycloak": "Authentifizierung",
"online": "Online",
"offline": "Nicht erreichbar",
"checking": "Wird geprueft...",
"continue": "Weiter zur Einrichtung",
"alreadyComplete": "Die Einrichtung wurde bereits abgeschlossen.",
"redirecting": "Du wirst zum Dashboard weitergeleitet..."
},
"adminSetup": {
"title": "Admin-Account erstellen",
"description": "Erstelle den ersten Administrator-Account fuer tOS.",
"firstName": "Vorname",
"lastName": "Nachname",
"email": "E-Mail-Adresse",
"password": "Passwort",
"passwordConfirm": "Passwort bestaetigen",
"passwordMismatch": "Passwoerter stimmen nicht ueberein",
"passwordTooShort": "Mindestens 8 Zeichen erforderlich",
"createAccount": "Account erstellen",
"creating": "Wird erstellt..."
},
"branding": {
"title": "Branding konfigurieren",
"description": "Passe tOS an dein Unternehmen an.",
"appName": "App-Name",
"appNamePlaceholder": "tOS",
"companyName": "Firmenname",
"companyNamePlaceholder": "Mein Unternehmen GmbH",
"logoUrl": "Logo-URL",
"logoUrlPlaceholder": "https://example.com/logo.png",
"logoPreview": "Logo-Vorschau",
"save": "Speichern & Weiter",
"saving": "Wird gespeichert...",
"skip": "Ueberspringen"
},
"complete": {
"title": "Einrichtung abgeschlossen!",
"description": "tOS wurde erfolgreich eingerichtet und ist bereit zur Nutzung.",
"completing": "Einrichtung wird abgeschlossen...",
"toDashboard": "Zum Dashboard",
"toLogin": "Zum Login"
}
}
}