Zum Hauptinhalt springen

Konfiguration

Die Anwendung wird über Umgebungsvariablen konfiguriert. Erstellen Sie eine .env-Datei im selben Verzeichnis wie die docker-compose.yml.

Pflichtangaben

VariableBeschreibung
DJANGO_SECRET_KEYGeheimer Schlüssel für Django (zufällig generieren)
DJANGO_DB_HOSTHostname der Datenbank (z.B. resource-planning-db)
DJANGO_DB_NAMEName der Datenbank
DJANGO_DB_USERDatenbank-Benutzer
DJANGO_DB_PASSWORDDatenbank-Passwort

Anwendung

VariableStandardBeschreibung
DJANGO_DEBUGFalseDebug-Modus aktivieren (True/False)
DJANGO_ALLOWED_HOSTSlocalhostErlaubte Hostnamen (Leerzeichen-getrennt)
DJANGO_USE_X_FORWARDED_HOSTFalseX-Forwarded-Host Header verwenden (bei Reverse Proxy)
DJANGO_NUM_PROXIES1Wie viele Proxys vor der Anwendung stehen. Entscheidet, welcher Eintrag aus X-Forwarded-For als Client gilt — und damit, gegen wen ein Rate Limit zählt. Ein nginx davor: 1; nginx hinter Cloudflare: 2; direkt erreichbar: 0.
WEB_CONCURRENCY1Anzahl Uvicorn Worker-Prozesse

E-Mail

Für Passwort-Reset und E-Mail-Änderungen muss ein SMTP-Server konfiguriert werden.

VariableStandardBeschreibung
DJANGO_EMAIL_HOSTlocalhostSMTP-Server
DJANGO_EMAIL_PORT25SMTP-Port
DJANGO_EMAIL_HOST_USERSMTP-Benutzer
DJANGO_EMAIL_HOST_PASSWORDSMTP-Passwort
DJANGO_EMAIL_USE_TLSFalseTLS verwenden
DJANGO_EMAIL_USE_SSLFalseSSL verwenden
DJANGO_DEBUG_EMAILFalseE-Mails auf die Konsole ausgeben statt senden

Frontend-URLs

Diese URLs werden in E-Mail-Vorlagen verwendet (z.B. Passwort-Reset-Links).

VariableBeschreibung
DJANGO_CONFIG_FRONTEND_URL_LOGINURL der Login-Seite
DJANGO_CONFIG_FRONTEND_URL_PASSWORD_RESETURL der Passwort-Reset-Seite
DJANGO_CONFIG_FRONTEND_URL_EMAIL_CHANGEURL der E-Mail-Änderungsseite

JWT-Authentifizierung

VariableStandardBeschreibung
DJANGO_ACCESS_TOKEN_LIFETIME300Access-Token Gültigkeit in Sekunden (5 Min)
DJANGO_REFRESH_TOKEN_LIFETIME1209600Refresh-Token Gültigkeit in Sekunden (14 Tage)
DJANGO_ROTATE_REFRESH_TOKENSTrueRefresh-Token bei Erneuerung rotieren
DJANGO_BLACKLIST_AFTER_ROTATIONTrueAlten Refresh-Token nach Rotation sperren
DJANGO_REFRESH_TOKEN_COOKIE_SECUREFalseSecure-Flag für Refresh-Token-Cookie (bei HTTPS: True)
DJANGO_REFRESH_TOKEN_COOKIE_SAMESITELaxSameSite-Attribut (Strict oder Lax)

CSRF

VariableStandardBeschreibung
DJANGO_CSRF_COOKIE_SECUREFalseSecure-Flag für CSRF-Cookie (bei HTTPS: True)
DJANGO_CSRF_COOKIE_SAMESITELaxSameSite-Attribut
DJANGO_CSRF_COOKIE_HTTPONLYFalseHttpOnly-Flag
DJANGO_CSRF_TRUSTED_ORIGINShttp://localhost:8000Vertrauenswürdige Origins (Leerzeichen-getrennt)

HTTPS

VariableStandardBeschreibung
DJANGO_SECURE_PROXY_SSL_HEADERhttpsDer Wert von X-Forwarded-Proto, der eine verschlüsselte Anfrage bedeutet.
DJANGO_SESSION_COOKIE_SECUREFalseSession-Cookie nur über HTTPS senden. Django-Admin und DRF-Session-Authentifizierung nutzen dieses Cookie — bei TLS einschalten.
DJANGO_SECURE_HSTS_SECONDS0Dauer des Strict-Transport-Security-Headers in Sekunden; 0 schaltet ihn ab. Beispiel: 31536000 (ein Jahr).
DJANGO_SECURE_PROXY_SSL_HEADER nicht auf http setzen

Der Wert ist derjenige, der eine verschlüsselte Anfrage kennzeichnet. Steht dort http, gilt jede unverschlüsselte Anfrage als sicher und jede HTTPS-Anfrage als unsicher — genau verkehrt herum. Der Standard ist https; ändern Sie ihn nur, wenn Ihr Proxy nachweislich einen anderen Wert sendet.

HSTS wirkt lange nach

Browser merken sich den Header für seine volle Dauer. Setzen Sie DJANGO_SECURE_HSTS_SECONDS erst, wenn die Anwendung dauerhaft über HTTPS erreichbar ist und bleiben soll.

Rate Limits

Die Anmeldung und das Zurücksetzen des Passworts sind mengenmäßig begrenzt. Ein leerer Wert schaltet das jeweilige Limit ab.

VariableStandardBeschreibung
DJANGO_THROTTLE_LOGIN120/minAnmeldeversuche je Client-IP. Muss eine ganze Schule verkraften, die sich gleichzeitig anmeldet — nicht eine einzelne Person.
DJANGO_THROTTLE_LOGIN_ACCOUNT10/minAnmeldeversuche je Benutzername, unabhängig von der Adresse. Das Limit gegen das Durchprobieren eines Passworts.
DJANGO_THROTTLE_PASSWORD_RESET20/hourAnforderungen einer Passwort-Reset-Mail je Client-IP.
Das Fenster kurz halten

Ein langes Fenster bei DJANGO_THROTTLE_LOGIN_ACCOUNT erlaubt es, ein Konto absichtlich auszusperren, indem sein Budget aufgebraucht wird. Der Standard von einer Minute ist bewusst kurz gewählt.

Mehrere Worker zählen getrennt

Die Limits werden im lokalen Cache gezählt. Mit mehreren Worker-Prozessen (WEB_CONCURRENCY über 1) zählt jeder für sich, das tatsächliche Limit ist also entsprechend höher. Für exakte Limits konfigurieren Sie einen gemeinsamen Cache.

DJANGO_NUM_PROXIES muss stimmen

Die IP-basierten Limits zählen gegen die Adresse, die aus X-Forwarded-For ermittelt wird. Ist die Zahl der Proxys falsch, zählt entweder alles gegen den Proxy — dann sperrt ein Nutzer alle anderen aus — oder gegen eine vom Client frei wählbare Adresse, dann wirkt das Limit gar nicht.

CORS

VariableStandardBeschreibung
DJANGO_CORS_ALLOWED_ORIGINShttp://localhost:4000Erlaubte Origins (Leerzeichen-getrennt)
DJANGO_CORS_ALLOW_CREDENTIALSTrueCredentials (Cookies) erlauben

Internationalisierung

VariableStandardBeschreibung
DJANGO_LANGUAGE_CODEde-deStandardsprache
DJANGO_TIME_ZONEUTCZeitzone

Timeouts

VariableStandardBeschreibung
DJANGO_CONFIG_USERTOKEN_EXPIRATION15Gültigkeit Benutzer-Token für Passwort-Reset/E-Mail-Änderung (Minuten)

Schuljahreskalender

VariableStandardBeschreibung
DJANGO_SCHOOL_FINAL_GRADE3Höchstes Ausbildungsjahr der Schule. Wer darüber hinaus vorrücken würde, hat die Ausbildung beendet.
DJANGO_ACADEMIC_YEAR_SEEDNur für die einmalige Umstellung auf den Schuljahreskalender. JSON-Liste der historischen Schuljahre, siehe unten.

DJANGO_ACADEMIC_YEAR_SEED

Bei der Migration auf den datumsbasierten Schuljahreskalender werden die zurückliegenden Schuljahre aus dem alten Protokoll der Schuljahreswechsel rekonstruiert. Dieses Protokoll kennt aber nur den Tag, an dem der Wechsel ausgelöst wurde — nicht den tatsächlichen Stichtag.

Setzen Sie diese Variable vor der Migration, um die Stichtage exakt vorzugeben:

DJANGO_ACADEMIC_YEAR_SEED='[{"label": "2023/24", "start_date": "2023-08-01"}, {"label": "2024/25", "start_date": "2024-08-01"}, {"label": "2025/26", "start_date": "2025-08-01"}]'

Ist die Variable nicht gesetzt, werden die Stichtage geschätzt. Das kann dazu führen, dass alte Stundeneinträge um einige Tage neben der tatsächlichen Schuljahresgrenze liegen. Nach der Migration wird die Variable nicht mehr verwendet und kann entfernt werden.

warnung

Ist der Inhalt kein gültiges JSON in der oben gezeigten Form, bricht die Migration mit einer Fehlermeldung ab. Sie fällt bewusst nicht stillschweigend auf geschätzte Daten zurück.

Beispiel .env

# Sicherheit
DJANGO_SECRET_KEY=ihr-geheimer-schluessel-hier
DJANGO_DEBUG=False
DJANGO_ALLOWED_HOSTS=api.example.com

# Datenbank
DJANGO_DB_HOST=resource-planning-db
DJANGO_DB_NAME=resource_planning
DJANGO_DB_USER=rp_user
DJANGO_DB_PASSWORD=sicheres-passwort

# E-Mail
DJANGO_EMAIL_HOST=smtp.example.com
DJANGO_EMAIL_PORT=587
DJANGO_EMAIL_HOST_USER=noreply@example.com
DJANGO_EMAIL_HOST_PASSWORD=email-passwort
DJANGO_EMAIL_USE_TLS=True

# Frontend-URLs
DJANGO_CONFIG_FRONTEND_URL_LOGIN=https://app.example.com/login
DJANGO_CONFIG_FRONTEND_URL_PASSWORD_RESET=https://app.example.com/reset-password
DJANGO_CONFIG_FRONTEND_URL_EMAIL_CHANGE=https://app.example.com/account/change-email

# Schuljahreskalender
DJANGO_SCHOOL_FINAL_GRADE=3

# HTTPS-Einstellungen
DJANGO_REFRESH_TOKEN_COOKIE_SECURE=True
DJANGO_CSRF_COOKIE_SECURE=True
DJANGO_SESSION_COOKIE_SECURE=True
DJANGO_SECURE_PROXY_SSL_HEADER=https
DJANGO_USE_X_FORWARDED_HOST=True
DJANGO_NUM_PROXIES=1
DJANGO_CSRF_TRUSTED_ORIGINS=https://api.example.com
DJANGO_CORS_ALLOWED_ORIGINS=https://app.example.com