Dritte Login-Methode neben Passwort und Passkey, konfiguriert über OIDC_ISSUER/OIDC_CLIENT_ID/OIDC_CLIENT_SECRET (optional, Button bleibt ohne diese Vars ausgeblendet). Authorization-Code-Flow mit PKCE, ID-Token-Signaturprüfung gegen das JWKS des Providers via neuer Abhängigkeit "jose" (RS256 fest gepinnt gegen Algorithm-Confusion), State/Nonce kurzlebig und einmalig verwendbar in neuer Tabelle oidc_states (Migration 0003, analog zu webauthn_challenges). Funktioniert ausschließlich für bereits angelegte Benutzer (Abgleich per E-Mail) – kein Auto-Provisioning, keine Rollenübernahme aus Claims, beides bleibt exklusiv über die bestehende Benutzerverwaltung steuerbar. app/login/page.tsx zu Server-Component-Wrapper reduziert (prüft isConfigured(), liest ?error= aus searchParams), bisheriger Inhalt nach components/LoginForm.tsx verschoben. Version 1.9.0. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
103 lines
3.9 KiB
YAML
103 lines
3.9 KiB
YAML
# =============================================================
|
||
# Canteen Menu – Docker-Setup
|
||
#
|
||
# Produktion (App + PostgreSQL):
|
||
# docker compose --env-file .env.local up -d --build
|
||
#
|
||
# Entwicklung (Dev-Server mit Hot-Reload, kein lokales Node nötig):
|
||
# docker compose --env-file .env.local --profile dev up dev
|
||
#
|
||
# "name" fixiert den Compose-Projektnamen explizit auf "canteen-menu" –
|
||
# ohne diese Angabe leitet Compose ihn aus dem Ordnernamen ab.
|
||
# =============================================================
|
||
|
||
name: canteen-menu
|
||
|
||
services:
|
||
# ---------- Next.js-App (Produktions-Build) ----------
|
||
app:
|
||
build:
|
||
context: .
|
||
image: canteen-menu-app
|
||
container_name: canteen-menu-app
|
||
environment:
|
||
DATABASE_URL: postgres://postgres:${LOCAL_PG_PASSWORD:-canteen_menu}@db:5432/canteen_menu
|
||
# Öffentliche URL der App (Domain hinter dem Reverse-Proxy).
|
||
# Wird für den CSRF-Origin-Check genutzt; dieselbe URL ist auch die
|
||
# Passkey-Domain (RP-ID/Origin werden direkt daraus abgeleitet).
|
||
APP_URL: ${APP_URL:-http://localhost:3000}
|
||
# Titel im Browser-Tab und Überschrift, solange kein Logo hochgeladen ist.
|
||
SITE_TITLE: ${SITE_TITLE:-Canteen Menu}
|
||
# Optional: E-Mail des automatisch angelegten Admin-Erstnutzers.
|
||
ADMIN_EMAIL: ${ADMIN_EMAIL:-}
|
||
# Optional: DeepL-API-Key für automatische Übersetzung von Gerichten
|
||
# (Essenszeiten, Kürzel-Erklärungen) nach Englisch/Polnisch. Ohne Key
|
||
# bleibt "Automatisch übersetzen" inaktiv, manuelle Eingabe geht immer.
|
||
DEEPL_API_KEY: ${DEEPL_API_KEY:-}
|
||
# Optional: SSO-Login per OpenID Connect (z. B. Authentik). Ohne
|
||
# diese drei Werte bleibt der SSO-Button ausgeblendet. Funktioniert
|
||
# nur für bereits angelegte Benutzer (Abgleich per E-Mail), legt nie
|
||
# neue Konten an.
|
||
OIDC_ISSUER: ${OIDC_ISSUER:-}
|
||
OIDC_CLIENT_ID: ${OIDC_CLIENT_ID:-}
|
||
OIDC_CLIENT_SECRET: ${OIDC_CLIENT_SECRET:-}
|
||
# Muss auf das "volumes:"-Ziel unten UND das im Dockerfile per
|
||
# "mkdir/chown" vorbereitete Verzeichnis zeigen – ohne diese
|
||
# Variable würde lib/branding.ts auf ${PWD}/data/branding
|
||
# zurückfallen, das weder gemountet noch für den nicht-root
|
||
# App-Nutzer beschreibbar ist (Upload schlägt mit 500 fehl).
|
||
BRANDING_DIR: /data/branding
|
||
ports:
|
||
- "0.0.0.0:3000:3000"
|
||
volumes:
|
||
- branding_data:/data/branding
|
||
- ./ZUGANGSDATEN.md:/app/ZUGANGSDATEN.md
|
||
depends_on:
|
||
- db
|
||
restart: unless-stopped
|
||
|
||
# ---------- PostgreSQL (primäre Datenbank) ----------
|
||
db:
|
||
image: postgres:17-alpine
|
||
container_name: canteen-menu-db
|
||
environment:
|
||
POSTGRES_DB: canteen_menu
|
||
POSTGRES_PASSWORD: ${LOCAL_PG_PASSWORD:-canteen_menu}
|
||
# Bewusst kein "ports:"-Mapping: die Datenbank ist nur innerhalb des
|
||
# Compose-Netzwerks unter "db:5432" erreichbar (für app/dev), nicht
|
||
# vom Host oder von außen. Zugriff für Debugging/Backups über
|
||
# "docker compose exec db psql -U postgres canteen_menu".
|
||
volumes:
|
||
- pgdata:/var/lib/postgresql/data
|
||
restart: unless-stopped
|
||
|
||
# ---------- Dev-Server (nur mit --profile dev) ----------
|
||
dev:
|
||
image: node:24-alpine
|
||
container_name: canteen-menu-dev
|
||
profiles: ["dev"]
|
||
working_dir: /app
|
||
command: sh -c "npm install && npm run dev"
|
||
environment:
|
||
DATABASE_URL: postgres://postgres:${LOCAL_PG_PASSWORD:-canteen_menu}@db:5432/canteen_menu
|
||
APP_URL: ${APP_URL:-http://localhost:3000}
|
||
SITE_TITLE: ${SITE_TITLE:-Canteen Menu}
|
||
ADMIN_EMAIL: ${ADMIN_EMAIL:-}
|
||
DEEPL_API_KEY: ${DEEPL_API_KEY:-}
|
||
OIDC_ISSUER: ${OIDC_ISSUER:-}
|
||
OIDC_CLIENT_ID: ${OIDC_CLIENT_ID:-}
|
||
OIDC_CLIENT_SECRET: ${OIDC_CLIENT_SECRET:-}
|
||
ports:
|
||
- "0.0.0.0:3000:3000"
|
||
volumes:
|
||
- .:/app
|
||
- dev_node_modules:/app/node_modules
|
||
- branding_data:/app/data/branding
|
||
depends_on:
|
||
- db
|
||
|
||
volumes:
|
||
pgdata:
|
||
dev_node_modules:
|
||
branding_data:
|