leistungsbilanz-ts/compose.dev.yaml
Grovy311 c56cfb30ad Add login-required user management (admin/user roles, Config->Benutzer)
No self-signup: admins create every account in Config -> Benutzer with a
typed start password; a forced password change gates first use. Session-
cookie auth protects all /api/* routes; /api/users additionally requires
the admin role. See docs/authentication.md.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-28 19:51:47 +02:00

103 lines
3 KiB
YAML

# Entwicklungs-Stack: Quellcode-Mounts, laufende Dev-Server, Hot Reload.
# docker compose -f compose.dev.yaml up --build
#
# Die Polling-Watcher unten sind fuer Bind-Mounts unter Windows und macOS
# noetig, weil inotify-Events die VM-Grenze nicht passieren. Sie kosten
# dauerhaft CPU; genau deshalb laufen im Server-Stack (compose.yaml) gar
# keine Watcher.
#
# Der Projektname muss sich von dem des Server-Stacks unterscheiden, damit
# "docker compose down" in diesem Verzeichnis niemals einen laufenden
# Server-Stack abraeumen kann.
name: leistungsbilanz-dev
x-service-defaults: &service-defaults
init: true
restart: unless-stopped
stop_grace_period: 20s
logging:
driver: json-file
options:
max-size: "20m"
max-file: "10"
services:
api:
<<: *service-defaults
build:
context: .
target: dev
command:
- sh
- -c
- npm run db:migrate && npm run db:verify:circuit-schema && exec npm run dev:api
environment:
PORT: "3000"
CHOKIDAR_USEPOLLING: "true"
LOG_LEVEL: "${LOG_LEVEL:-debug}"
AUTH_BOOTSTRAP_USERNAME: "${AUTH_BOOTSTRAP_USERNAME:-}"
AUTH_BOOTSTRAP_PASSWORT: "${AUTH_BOOTSTRAP_PASSWORT:-}"
AUTH_SESSION_HOURS: "${AUTH_SESSION_HOURS:-12}"
# Nur auf dem Loopback: die API darf nicht aus dem LAN erreichbar sein.
ports:
- "127.0.0.1:3000:3000"
# Kein memswap_limit wie im Server-Stack: beim Entwickeln ist Swap als
# Puffer erwuenscht, die Grenze soll nur den Host vor Dauerlast schuetzen.
mem_limit: 1g
volumes:
- ./src:/app/src
- ./scripts:/app/scripts
- ./data:/app/data
- ./drizzle.config.ts:/app/drizzle.config.ts:ro
- ./tsconfig.json:/app/tsconfig.json:ro
healthcheck:
test:
- CMD
- node
- -e
- fetch('http://127.0.0.1:3000/health').then(response=>{if(!response.ok)process.exit(1)}).catch(()=>process.exit(1))
interval: 30s
timeout: 3s
retries: 5
start_period: 20s
web:
<<: *service-defaults
build:
context: .
target: dev
command:
- npm
- run
- dev:web
- --
- --hostname
- 0.0.0.0
environment:
API_INTERNAL_URL: http://api:3000
WATCHPACK_POLLING: "true"
NEXT_TELEMETRY_DISABLED: "1"
LOG_LEVEL: "${LOG_LEVEL:-debug}"
depends_on:
api:
condition: service_healthy
ports:
- "127.0.0.1:3001:3001"
# "next dev" haelt Kompilierzustand und waechst im Dauerbetrieb stetig;
# die Grenze macht daraus einen Container-Neustart statt Host-Swapping.
mem_limit: 2g
volumes:
- ./src:/app/src
- ./next.config.mjs:/app/next.config.mjs:ro
- ./tsconfig.json:/app/tsconfig.json:ro
- ./tsconfig.next.json:/app/tsconfig.next.json:ro
healthcheck:
test:
- CMD
- node
- -e
- fetch('http://127.0.0.1:3001/web-health').then(response=>{if(!response.ok)process.exit(1)}).catch(()=>process.exit(1))
interval: 30s
timeout: 3s
retries: 5
start_period: 20s