Files
opencrm/docker/docker-compose.yml
T
duffyduckandClaude Opus 5 ee83b09ed8 Caddy-Stack (docker/) auf Stand gebracht statt entfernt
Der Stack bleibt bewusst erhalten: Er richtet sich an Betreiber OHNE eigenen
Reverse-Proxy, weil Caddy das Zertifikat selbst holt und erneuert. Er war
allerdings seit Februar stehengeblieben und reichte zehn Variablen nicht an
den Container durch - teils sicherheitsrelevant.

Behoben:
- HTTPS_ENABLED ergaenzt (Default true, Caddy terminiert TLS). Fehlte bisher
  komplett, dadurch waere der Refresh-Cookie OHNE Secure-Attribut gesetzt
  worden und trust proxy falsch gewesen.
- JWT_EXPIRES_IN Default von 7d auf 15m korrigiert - der Wert galt dem
  ACCESS-Token und stammte aus der Zeit vor dem Access-/Refresh-Pattern. Ein
  Access-Token mit einer Woche Lebensdauer im Browser-Speicher macht das
  XSS-Fenster unnoetig gross.
- JWT_REFRESH_EXPIRES_IN, CORS_ORIGINS, LISTEN_ADDR, SSRF_BLOCK_PRIVATE_IPS
  ergaenzt. JWT_REFRESH_EXPIRES_IN stand bereits in docker/.env.example,
  wurde aber nie durchgereicht - dieselbe Fehlerklasse wie beim Audit-Siegel.
- Caddyfile: gzip fuer /api/* deaktiviert (BREACH, CVE-2013-3587). Die
  Konfiguration komprimierte bisher alles, obwohl die README das fuer die
  API ausdruecklich ausschliesst. Statische Assets bleiben komprimiert.
  Mit `caddy validate` geprueft.
- docker/.env.example um die neuen Variablen erweitert, dazu ein Hinweis auf
  Sonderzeichen im DB-Passwort (dieser Stack setzt die DATABASE_URL direkt
  zusammen, anders als der Entrypoint im Projektstamm).
- README benennt jetzt, wann welcher Stack der richtige ist.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 19:36:03 +02:00

108 lines
3.4 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
version: '3.8'
services:
# ===================================
# MariaDB Database
# ===================================
db:
image: mariadb:10.11
container_name: opencrm-db
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD:-rootpassword}
MYSQL_DATABASE: ${DB_NAME:-opencrm}
MYSQL_USER: ${DB_USER:-opencrm}
MYSQL_PASSWORD: ${DB_PASSWORD:-opencrm123}
volumes:
- mariadb_data:/var/lib/mysql
networks:
- opencrm-network
healthcheck:
test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
start_period: 10s
interval: 10s
timeout: 5s
retries: 3
# ===================================
# OpenCRM Application
# ===================================
app:
build:
context: ..
dockerfile: docker/Dockerfile
container_name: opencrm-app
restart: unless-stopped
environment:
NODE_ENV: production
PORT: 3001
DATABASE_URL: mysql://${DB_USER:-opencrm}:${DB_PASSWORD:-opencrm123}@db:3306/${DB_NAME:-opencrm}
JWT_SECRET: ${JWT_SECRET:?JWT_SECRET is required}
# Access-Token kurzlebig (lebt nur im Browser-Speicher → XSS-Fenster
# klein halten), Refresh-Token lang im httpOnly-Cookie.
# Frueher stand hier 7d fuer den ACCESS-Token das war ein Ueberbleibsel
# aus der Zeit vor dem Access-/Refresh-Pattern.
JWT_EXPIRES_IN: ${JWT_EXPIRES_IN:-15m}
JWT_REFRESH_EXPIRES_IN: ${JWT_REFRESH_EXPIRES_IN:-7d}
ENCRYPTION_KEY: ${ENCRYPTION_KEY:?ENCRYPTION_KEY is required}
# Caddy terminiert TLS und steht als EIN Proxy davor. Das Flag setzt das
# Secure-Attribut am Refresh-Cookie, trust proxy = 1 Hop und
# upgrade-insecure-requests in der CSP. Nur auf false setzen, wenn der
# Stack bewusst ohne TLS laeuft (reiner Test ueber http://).
HTTPS_ENABLED: ${HTTPS_ENABLED:-true}
# Nur noetig, wenn das Frontend unter einer anderen Origin laeuft.
CORS_ORIGINS: ${CORS_ORIGINS:-}
# In der Container-Umgebung muss der Dienst fuer Caddy erreichbar sein.
LISTEN_ADDR: ${LISTEN_ADDR:-0.0.0.0}
# Cloud-Deploy: private IP-Ranges fuer Provider-/SMTP-Tests blocken.
SSRF_BLOCK_PRIVATE_IPS: ${SSRF_BLOCK_PRIVATE_IPS:-false}
# Siegel für das Audit-Log (optional, fail-safe ohne Wert)
AUDIT_HMAC_KEY: ${AUDIT_HMAC_KEY:-}
AUDIT_HMAC_KEY_OLD: ${AUDIT_HMAC_KEY_OLD:-}
RUN_SEED: ${RUN_SEED:-false}
volumes:
- uploads_data:/app/uploads
- backups_data:/app/backups
networks:
- opencrm-network
depends_on:
db:
condition: service_healthy
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3001/api/health"]
start_period: 60s
interval: 30s
timeout: 10s
retries: 3
# ===================================
# Caddy Reverse Proxy (with auto SSL)
# ===================================
caddy:
image: caddy:2-alpine
container_name: opencrm-caddy
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:ro
- caddy_data:/data
- caddy_config:/config
networks:
- opencrm-network
depends_on:
app:
condition: service_healthy
networks:
opencrm-network:
driver: bridge
volumes:
mariadb_data:
uploads_data:
backups_data:
caddy_data:
caddy_config: