Files
FireAdministration/docker-compose.override.yml
T
Florian WildeandClaude Opus 5 845942f36c Phase 0: Fundament der Feuerwehr-Verwaltungsplattform
Legt den kompletten Unterbau an, auf dem die Fachmodule aufsetzen.

Betrieb:
- docker-compose.yml mit Traefik, App, Worker, PostgreSQL 17 + PostGIS,
  Redis, MinIO und Gotenberg; Entwicklungs-Override ohne Traefik, dafuer
  mit Mailpit und Adminer
- Mehrstufiges Dockerfile: eigener Benutzer, tini als PID 1, Healthcheck
- .env.example mit einem Kommentar zu jeder Variable

Mandantentrennung:
- Row Level Security auf allen mandantenpflichtigen Tabellen
- Zwei getrennte Datenbankverbindungen: florian_app mit aktiver RLS fuer
  die Anwendung, Eigentuemer-Zugang nur fuer Migration, Seed und Anmeldung
- fuerOrganisation() als einziger Weg zu Fachdaten

Nachvollziehbarkeit:
- AuditLog append-only per Trigger; UPDATE ist dauerhaft gesperrt, DELETE
  nur im gekennzeichneten Aufbewahrungslauf
- Geheimnisse werden vor dem Schreiben entfernt

Anmeldung:
- OIDC gegen ein extern betriebenes authentik, Rollen aus Gruppen nur als
  Vorbelegung beim ersten Login
- Lokaler E-Mail/Passwort-Login als Rueckfallweg
- Terminal per PIN und RFID mit zwei Schranken (Geraet, dann Person)

Weiteres:
- lib/authz.ts mit 9 Rollen und 38 Einzelrechten
- lib/storage.ts (MinIO), lib/audit.ts, lib/warteschlange.ts (BullMQ)
- Integrationen fuer Mail, Telegram und LLM hinter abschaltbaren Interfaces
- tRPC v11, Basis-Layout mit Seitenleiste und dunkler Darstellung
- Seed mit einer Beispielwehr: 16 Personen, 3 Fahrzeuge, 40 Geraete
- 32 Vitest-Tests (davon 8 gegen eine echte Datenbank), 10 Playwright-Tests
- README, Anleitung mit Screenshots, Roadmap, Aufwandsschaetzung, Devlog,
  Versionierungsregeln und Changelog

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-03 00:13:53 +02:00

117 lines
3.6 KiB
YAML

# =============================================================================
# Entwicklungs-Override. Docker Compose lädt diese Datei automatisch zusätzlich
# zu docker-compose.yml — für den Produktionsbetrieb daher explizit nur die
# Hauptdatei angeben:
# docker compose -f docker-compose.yml up -d
#
# Unterschiede zur Produktion:
# - kein Traefik (die Dienste hängen direkt an localhost-Ports)
# - Quellcode als Bind-Mount, Hot Reload über "next dev"
# - Mailpit als lokaler SMTP-Auffangkorb
# - Adminer zum Draufschauen auf die Datenbank
# =============================================================================
services:
traefik:
# Wird in der Entwicklung nicht gebraucht. Mit dem Profil "proxy" trotzdem
# startbar: docker compose --profile proxy up -d
profiles: ["proxy"]
postgres:
ports:
- "${POSTGRES_PORT:-5432}:5432"
redis:
ports:
- "${REDIS_PORT:-6379}:6379"
minio:
ports:
- "${MINIO_API_PORT:-9000}:9000"
- "${MINIO_CONSOLE_PORT:-9001}:9001"
environment:
# Ohne TLS-Terminierung zeigt die Konsole auf localhost.
MINIO_BROWSER_REDIRECT_URL: http://localhost:${MINIO_CONSOLE_PORT:-9001}
MINIO_SERVER_URL: http://localhost:${MINIO_API_PORT:-9000}
labels:
- traefik.enable=false
gotenberg:
ports:
- "${GOTENBERG_PORT:-3101}:3000"
app:
build:
target: builder
command: ["npm", "run", "dev"]
ports:
# "next dev" laeuft im Container auf 3100 (siehe package.json).
- "${APP_PORT:-3100}:3100"
environment:
NODE_ENV: development
# Datei-Watching funktioniert über Bind-Mounts von Windows aus nur mit
# Polling zuverlässig.
WATCHPACK_POLLING: "true"
CHOKIDAR_USEPOLLING: "true"
volumes:
- ./src:/app/src
- ./prisma:/app/prisma
- ./public:/app/public
- ./tests:/app/tests
- ./next.config.ts:/app/next.config.ts
- ./tsconfig.json:/app/tsconfig.json
- ./postcss.config.mjs:/app/postcss.config.mjs
# Anonyme Volumes: node_modules und .next bleiben im Container.
- /app/node_modules
- /app/.next
labels:
- traefik.enable=false
worker:
build:
target: builder
command: ["npm", "run", "worker:dev"]
environment:
NODE_ENV: development
ROLLE: worker
volumes:
- ./src:/app/src
- ./prisma:/app/prisma
- /app/node_modules
# ---------------------------------------------------------------------------
# Nur Entwicklung: SMTP-Auffangkorb. Alle Mails landen hier statt beim
# Empfänger. Weboberfläche: http://localhost:${MAILPIT_UI_PORT:-8125}
# ---------------------------------------------------------------------------
mailpit:
image: axllent/mailpit:latest
container_name: florian-mailpit
restart: unless-stopped
environment:
MP_MAX_MESSAGES: 500
TZ: ${TZ:-Europe/Berlin}
ports:
- "${MAILPIT_UI_PORT:-8125}:8025"
- "${MAILPIT_SMTP_PORT:-1125}:1025"
networks:
- intern
# ---------------------------------------------------------------------------
# Nur Entwicklung: schlanke Datenbankoberfläche. http://localhost:${ADMINER_PORT:-8081}
# Anmeldung: System PostgreSQL, Server "postgres", Benutzer/Passwort aus .env
# ---------------------------------------------------------------------------
adminer:
image: adminer:latest
container_name: florian-adminer
restart: unless-stopped
environment:
ADMINER_DEFAULT_SERVER: postgres
ADMINER_DESIGN: dracula
ports:
- "${ADMINER_PORT:-8081}:8080"
depends_on:
postgres:
condition: service_healthy
networks:
- intern