Files
kalendartool/docker-compose.yml

78 lines
2.8 KiB
YAML

services:
db:
image: postgres:16-alpine
restart: unless-stopped
environment:
POSTGRES_USER: calendar
POSTGRES_PASSWORD: calendar
POSTGRES_DB: calendar
# KEIN Port-Mapping: Die DB ist nur im internen Compose-Netz
# erreichbar (App verbindet ueber den Hostnamen "db"). Fuer
# lokalen Zugriff bei Bedarf: docker compose exec db psql ...
volumes:
- pgdata:/var/lib/postgresql/data
# Legt den least-privilege-App-User an (nur bei initialer
# Volume-Initialisierung; siehe Script fuer Bestands-Volumes).
- ./docker/postgres/init:/docker-entrypoint-initdb.d:ro
healthcheck:
test: ["CMD-SHELL", "pg_isready -U calendar -d calendar"]
interval: 5s
timeout: 5s
retries: 10
# Taeglicher DB-Backup-Service: erstellt um 02:00 Uhr ein
# pg_dump-Backup im Named Volume "pgbackups". Aeltere Backups werden
# automatisch nach 7 Tagen geloescht (Retention). Die Backups
# ueberleben Neustarts des Stacks, da sie im Volume liegen.
db-backup:
image: prodrigestivill/postgres-backup-local:16-alpine
restart: unless-stopped
depends_on:
db:
condition: service_healthy
environment:
POSTGRES_HOST: db
POSTGRES_DB: calendar
POSTGRES_USER: calendar
POSTGRES_PASSWORD: calendar
# Taeglich um 02:00 Uhr (Cron).
SCHEDULE: "@daily"
# Backups nach 7 Tagen automatisch loeschen.
BACKUP_KEEP_DAYS: 7
# Zusaetzlich die letzten 4 Wochensicherungen behalten.
BACKUP_KEEP_WEEKS: 4
# Monats-Sicherungen der letzten 3 Monate behalten.
BACKUP_KEEP_MONTHS: 3
# Kompression aktivieren (platzsparend).
POSTGRES_EXTRA_OPTS: "-Z6"
TZ: Europe/Berlin
volumes:
- pgbackups:/backups
app:
build: .
restart: unless-stopped
depends_on:
db:
condition: service_healthy
environment:
DATABASE_URL: postgresql://calendar_app:calendar_app@db:5432/calendar?schema=public
# KEIN Fallback-Secret: Ohne gesetztes SESSION_SECRET failt die
# App hart beim Start (lib/config.ts), statt JWTs mit einem
# oeffentlich bekannten Secret zu signieren.
SESSION_SECRET: ${SESSION_SECRET:?SESSION_SECRET muss gesetzt sein (z. B. in .env, siehe .env.example)}
APP_URL: ${APP_URL:-http://localhost:3000}
ALLOW_OPEN_REGISTRATION: ${ALLOW_OPEN_REGISTRATION:-true}
# Optional: Admin-Account beim ersten Start anlegen (First-Run).
# Nicht-destruktiv: Legt den Admin nur an, wenn noch keiner
# existiert. Bestehende User werden niemals geloescht.
# Wenn NICHT gesetzt, laeuft das Seed-Script ohne Nebeneffekte durch.
SEED_ADMIN_EMAIL: ${SEED_ADMIN_EMAIL:-}
SEED_ADMIN_PASSWORD: ${SEED_ADMIN_PASSWORD:-}
NODE_ENV: production
ports:
- "3000:3000"
volumes:
pgdata:
pgbackups: