Files
qrcode-generator/docker-compose.yml
T
Florian Wilde 1e0d04d0db Befunde der Sicherheitspruefung abarbeiten
S1 (hoch): Die OIDC-Rueckkehr verknuepft eine Identitaet mit einem
bestehenden Konto nur bei bestaetigter E-Mail — geprueft wurde das auch,
nur war die Bestaetigung als `email_verified !== false` berechnet. Damit
galt auch ein fehlender Claim als bestaetigt, und genau den schicken
manche Anbieter gar nicht. Jetzt zaehlt allein ein ausdrueckliches `true`.

S2 (hoch): `isAuthEnabled()` verlangte den Wert "true"; alles andere hiess
"aus". Eine vergessene Variable ergab eine Anwendung, in der jeder
Besucher alles darf, und nichts sah danach aus. Umgedreht: Abgeschaltet
wird nur, wer ausdruecklich "false" setzt. Die Vorgaben in Compose und
.env.example stehen auf true, und der Container warnt beim Start
mehrzeilig, solange die Anmeldung aus ist.

S5 (mittel): Der OIDC-Bootstrap las `user.count()` und legte danach an —
zwei gleichzeitige erste Anmeldungen konnten beide Administrator werden.
Jetzt in einer serialisierbaren Transaktion, wie die lokale
Ersteinrichtung es laengst tut.

S6 (niedrig): Die Herkunftspruefung verglich nur den Host, nicht das
Schema. Das Schema kommt jetzt aus BASE_URL — die eine Angabe zum
Ursprung, ueber die der Aufrufer nicht mitbestimmt.

S3, S4 und S7 bleiben offen und stehen begruendet in docs/sicherheit.md.
Bei S3 wurde der naheliegende Ausweg geprueft und verworfen: Waehrend der
Sperre weiter Passwoerter zu pruefen kostet 128 MiB je Versuch und
tauschte eine Sperre gegen ein Konto gegen eine gegen alle.

Refs #20
2026-08-24 01:02:03 +02:00

62 lines
2.3 KiB
YAML

services:
db:
image: postgres:18-alpine
restart: unless-stopped
environment:
POSTGRES_USER: ${POSTGRES_USER:-qrcode}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?POSTGRES_PASSWORD fehlt — bitte .env aus .env.example anlegen}
POSTGRES_DB: ${POSTGRES_DB:-qrcode}
volumes:
# Ab PostgreSQL 18 liegt das Datenverzeichnis in einem Unterordner mit
# Versionsnummer — der Mountpunkt ist deshalb /var/lib/postgresql und
# nicht mehr /var/lib/postgresql/data.
- db-data:/var/lib/postgresql
healthcheck:
# Die App startet erst, wenn die Datenbank wirklich Anfragen annimmt.
test:
["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-qrcode} -d ${POSTGRES_DB:-qrcode}"]
interval: 5s
timeout: 5s
retries: 12
start_period: 10s
app:
build:
context: .
restart: unless-stopped
depends_on:
db:
condition: service_healthy
environment:
# Achtung beim Ergänzen: Compose liest die .env nur, um Platzhalter wie
# ${BASE_URL} zu ersetzen. In den Container gelangt ausschließlich, was
# hier aufgeführt ist — eine neue Variable in der .env allein bleibt
# wirkungslos.
#
# Öffentliche Adresse der App — landet in jedem dynamischen QR-Code.
BASE_URL: ${BASE_URL:-http://localhost:3000}
DATABASE_URL: ${DATABASE_URL}
# Anmeldung mit Benutzern, Gruppen und Rollen.
# Ohne Angabe: an. Abgeschaltet wird nur, wer ausdruecklich
# AUTH_ENABLED=false setzt — siehe .env.example.
AUTH_ENABLED: ${AUTH_ENABLED:-true}
MAX_UPLOAD_MB: ${MAX_UPLOAD_MB:-10}
SESSION_IDLE_DAYS: ${SESSION_IDLE_DAYS:-30}
SESSION_MAX_DAYS: ${SESSION_MAX_DAYS:-90}
OIDC_ENABLED: ${OIDC_ENABLED:-false}
OIDC_ISSUER: ${OIDC_ISSUER:-}
OIDC_CLIENT_ID: ${OIDC_CLIENT_ID:-}
OIDC_CLIENT_SECRET: ${OIDC_CLIENT_SECRET:-}
OIDC_BUTTON_LABEL: ${OIDC_BUTTON_LABEL:-Mit Authentik anmelden}
OIDC_SCOPES: ${OIDC_SCOPES:-openid email profile}
OIDC_ONLY: ${OIDC_ONLY:-false}
OIDC_DEFAULT_ROLE: ${OIDC_DEFAULT_ROLE:-VIEWER}
OIDC_ADMIN_GROUP: ${OIDC_ADMIN_GROUP:-}
OIDC_GROUPS_CLAIM: ${OIDC_GROUPS_CLAIM:-groups}
ports:
# Direktes Port-Mapping, bewusst ohne Reverse Proxy.
- "${APP_PORT:-3000}:3000"
volumes:
db-data: