- docker-compose.coolify(.prebuilt).yml: Service craftvia-worker (Target worker, Chromium, shm_size 1gb, gleiche Härtung), Craftvia-Variablen für app und worker. - Dockerfile: worker-Stage mit HOME=/home/app (Chromium-Profil für non-root); lokaler docker build der Targets runner und worker erfolgreich, PDF-Erzeugung im Image geprüft. - .env.example/.env.prod.example/.env.coolify.example: alle Craftvia-Variablen inkl. RLS, KI-Provider, PDF_CHROMIUM_PATH, OFFLINE_MAX_DAYS, API_RATE_LIMIT_*, AI_GENERATION_RETENTION_DAYS, AI_MONTHLY_TOKEN_LIMIT. - CI (.github, .gitea): Job gate mit Postgres (pgvector) und Redis als Service: migrate deploy, seed, Passwort für craftvia_app, tsc, lint, build, npm run test. - docs/craftvia/DEPLOY.md (aus den Certvia-Deploy-Docs abgeleitet): Architektur, Domains, Secrets, Worker, Migrationen, RLS-Aktivierung, Backup/Restore, KI, Rate Limits, Aufbewahrung, Smoke, Update/Rollback. build-and-push-images.sh baut craftvia-worker. - Certvia-/ISMS-Dokumente aus docs/ nach docs/_certvia-archiv/ (mit README); Verweise in README.md und Skript-Kommentaren angepasst. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
145 lines
6.8 KiB
Bash
145 lines
6.8 KiB
Bash
# --- Datenbank ---
|
||
POSTGRES_USER=craftvia
|
||
POSTGRES_PASSWORD=craftvia
|
||
POSTGRES_DB=craftvia
|
||
DATABASE_URL=postgresql://craftvia:craftvia@localhost:5432/craftvia?schema=public
|
||
|
||
# --- Row Level Security (F-04) – lokal AUS (Owner-Betrieb) ---
|
||
# Lokal bleibt RLS aus: Der Owner craftvia ist Superuser/BYPASSRLS und sieht trotz
|
||
# FORCE alle Daten. Zum scharfen Testen die beiden Zeilen aktivieren (die Rolle
|
||
# craftvia_app zuvor mit LOGIN+Passwort versehen, s. scripts/test-rls-enforcement.ts):
|
||
# RLS_ENFORCED=true
|
||
# RLS_DATABASE_URL=postgresql://craftvia_app:craftvia_app_local@localhost:5432/craftvia?schema=public
|
||
|
||
# --- Redis (BullMQ) ---
|
||
# F-18: Redis läuft mit requirepass. REDIS_PASSWORD muss zum docker-compose-Default
|
||
# passen; das Passwort steht zusätzlich in der REDIS_URL (redis://:<pw>@host:port).
|
||
REDIS_PASSWORD=craftvia-redis
|
||
REDIS_URL=redis://:craftvia-redis@localhost:6379
|
||
|
||
# --- Objektspeicher (Garage / S3-kompatibel) ---
|
||
# Sind alle vier S3_*-Pflichtvariablen gesetzt, nutzt der Storage-Adapter das echte
|
||
# S3-Backend (Byte-Speicherung + Download-Route /files/<key>). Fehlt eine davon, faellt
|
||
# der Adapter auf den Stub zurueck (nur Metadaten, keine Bytes) - kein Crash.
|
||
# Der Bucket wird NICHT automatisch angelegt (Garage bedient kein S3-CreateBucket): er
|
||
# muss vorab provisioniert sein (Compose-Service "garage-provision"). Fehlt er, wirft der
|
||
# Adapter einen sprechenden Konfigurationsfehler.
|
||
# Garage erzwingt das Key-Format: S3_ACCESS_KEY = "GK" + 24 Hex, S3_SECRET_KEY = 64 Hex.
|
||
S3_ENDPOINT=http://localhost:3900
|
||
S3_ACCESS_KEY=GKdead0000beef0000cafe0000
|
||
S3_SECRET_KEY=0000000000000000000000000000000000000000000000000000000000000001
|
||
S3_BUCKET=craftvia-documents
|
||
# Region beidseitig us-east-1 (deckt sich mit garage.toml s3_region). forcePathStyle ist
|
||
# im Code fest gesetzt - Garage bedient ausschliesslich Path-Style.
|
||
S3_REGION=us-east-1
|
||
|
||
# Garage-Daemon-Secrets (der Daemon liest sie aus der Env, NICHT aus deploy/garage.toml).
|
||
# Lokale Dev-Werte (unkritisch, nur localhost). Fuer eigene Stacks frisch erzeugen:
|
||
# openssl rand -hex 32
|
||
GARAGE_RPC_SECRET=0000000000000000000000000000000000000000000000000000000000000002
|
||
GARAGE_ADMIN_TOKEN=0000000000000000000000000000000000000000000000000000000000000003
|
||
|
||
# --- Backup-Zielspeicher (optional) ---
|
||
# Lane „Konfigurierbarer Backup-Zielspeicher": das Ziel der Backup-/DSGVO-Artefakte ist
|
||
# jetzt im Betreiber-Portal (/admin/backup) waehlbar (Lokal/S3) und wird in der DB
|
||
# gespeichert. Praezedenz zur Laufzeit: DB-Config → diese Env-Vars → lokaler Default.
|
||
# Ohne DB-Config gelten weiter S3_* (siehe oben) bzw. — falls unvollstaendig — der
|
||
# lokale Ordner unten. HINWEIS: sobald im Portal ein Ziel gespeichert wird, hat die
|
||
# DB-Config Vorrang vor S3_*/BACKUP_LOCAL_DIR.
|
||
# Lokaler Ordner fuer Backup-Artefakte (Dev: relativ zum cwd). In Prod auf ein
|
||
# gemountetes, persistentes Volume zeigen lassen (sonst beim Redeploy fluechtig).
|
||
BACKUP_LOCAL_DIR=.backups
|
||
|
||
# --- Auth ---
|
||
AUTH_SECRET=change-me-generate-with-openssl-rand-base64-32
|
||
# PASSWORD_PEPPER (Härtung §1): 32-Byte hex, pro Umgebung eindeutig. openssl rand -hex 32
|
||
# ⚠ NICHT rotierbar ohne Passwort-Reset für alle; NICHT aus AUTH_SECRET ableiten; NICHT ins Backup-Artefakt.
|
||
PASSWORD_PEPPER=change-me-openssl-rand-hex-32
|
||
AUTH_URL=http://localhost:3000
|
||
|
||
# --- KI-Provider (anthropic | openai) ---
|
||
AI_PROVIDER=anthropic
|
||
AI_API_KEY=
|
||
|
||
# --- Anthropic (Lotse KI-Assistent, Auftragsimport) ---
|
||
# Ohne ANTHROPIC_API_KEY ist die KI-Anbindung deaktiviert (graceful degradation):
|
||
# kein Entwurf, Status bleibt –manuell zu erfassen", die UI funktioniert weiter.
|
||
ANTHROPIC_API_KEY=
|
||
# Optionale Modell-ID; Default: claude-opus-5
|
||
ANTHROPIC_MODEL=claude-opus-5
|
||
|
||
# --- E-Mail / SMTP (SEC1) ---
|
||
# Dev: Mailpit oder Mailhog (docker-compose Service `mailhog`, SMTP auf 1025,
|
||
# Weboberflaeche auf 8025). Gegen localhost wird TLS bewusst nicht erzwungen.
|
||
# Prod: dedizierte Absenderdomain mit SPF, DKIM und DMARC – Vorbedingung vor
|
||
# dem ersten Produktivversand. Secrets ausschliesslich aus dem Secret-Store.
|
||
SMTP_HOST=localhost
|
||
SMTP_PORT=1025
|
||
# true = implizites TLS (Port 465), false = STARTTLS (587). Ohne Angabe wird
|
||
# aus dem Port abgeleitet.
|
||
SMTP_SECURE=false
|
||
SMTP_USER=
|
||
SMTP_PASSWORD=
|
||
# Absenderadresse und Anzeigename. MAIL_FROM/MAIL_FROM_NAME werden als Alias
|
||
# ebenfalls akzeptiert.
|
||
SMTP_FROM=no-reply@craftvia.de
|
||
MAIL_FROM_NAME=Craftvia
|
||
# Optionale Antwortadresse (sonst keine Reply-To-Kopfzeile).
|
||
MAIL_REPLY_TO=
|
||
# Basis fuer absolute Links in Mails. Faellt auf AUTH_URL zurueck.
|
||
APP_BASE_URL=http://localhost:3000
|
||
|
||
# --- Craftvia: KI-Extraktion (Auftragsimport) & Lotse ---
|
||
# Nutzt ANTHROPIC_API_KEY / ANTHROPIC_MODEL (s. oben). Ohne Key: manuelle Erfassung.
|
||
AI_EXTRACTION_PROVIDER=anthropic
|
||
|
||
# --- Craftvia: Transkription von Sprachnotizen (Whisper-kompatible API) ---
|
||
# Ohne TRANSCRIPTION_API_KEY bleibt die Transkription deaktiviert (Status "disabled").
|
||
TRANSCRIPTION_PROVIDER=openai-compatible
|
||
TRANSCRIPTION_API_URL=https://api.openai.com/v1/audio/transcriptions
|
||
TRANSCRIPTION_API_KEY=
|
||
TRANSCRIPTION_MODEL=whisper-1
|
||
|
||
# --- Craftvia: optionaler Malware-Scan für Uploads (ClamAV clamd) ---
|
||
# Leer = nur Allowlist/Magic-Byte-Prüfung; gesetzt = zusätzlich clamd INSTREAM.
|
||
CLAMAV_HOST=
|
||
CLAMAV_PORT=3310
|
||
|
||
# --- Craftvia: Berichts-PDF (Worker, playwright-core + Chromium) ---
|
||
# Leer = Playwright-Chromium bzw. lokal installiertes Google Chrome (Entwicklerrechner).
|
||
# Im Docker-Worker-Image fest /usr/bin/chromium.
|
||
PDF_CHROMIUM_PATH=
|
||
|
||
# --- Craftvia: Offline/PWA ---
|
||
# Ab wie vielen Tagen ein lokal gespeichertes Auftragsbundle als veraltet gilt (1–365).
|
||
OFFLINE_MAX_DAYS=7
|
||
|
||
# --- Craftvia: Rate Limits der REST-API (je Nutzer, Anfragen pro Minute) ---
|
||
# Allgemein für /api/v1/**.
|
||
API_RATE_LIMIT_PER_MINUTE=300
|
||
# Einsatz-/Sync-Endpunkte (/api/v1/sync, /api/v1/uploads, /api/v1/field/**) – höher, weil
|
||
# die PWA nach Offline-Phasen Outbox und Fotos in Schüben nachsendet.
|
||
API_FIELD_RATE_LIMIT_PER_MINUTE=1200
|
||
|
||
# --- Craftvia: KI-Protokoll & Kostenbremse ---
|
||
# Nach N Tagen leert/pseudonymisiert ein Worker-Job Ein-/Ausgaben im KI-Protokoll
|
||
# (AiGeneration); Metadaten (Art, Modell, Tokens, Zeitpunkt) bleiben erhalten.
|
||
AI_GENERATION_RETENTION_DAYS=180
|
||
# Tokens (ein + aus) je Mandant je Kalendermonat; darüber lehnen Lotse und
|
||
# Import-Extraktion ab. 0 = unbegrenzt.
|
||
AI_MONTHLY_TOKEN_LIMIT=0
|
||
|
||
# --- Optionale Fundament-Variablen (Default leer) ---
|
||
# MFA_ENC_KEY: Schlüssel für TOTP-Secrets at-rest (leer = aus AUTH_SECRET abgeleitet).
|
||
# ⚠ Nach dem Setzen nicht mehr ändern.
|
||
# MFA_ENC_KEY=
|
||
# BACKUP_ENC_KEY: Verschlüsselung der Backup-Artefakte (leer = AUTH_SECRET).
|
||
# BACKUP_ENC_KEY=
|
||
# WebAuthn/Passkeys: Origin und RP-ID (leer = aus AUTH_URL abgeleitet).
|
||
# WEBAUTHN_ORIGIN=http://localhost:3000
|
||
# WEBAUTHN_RP_ID=localhost
|
||
# Demo-Seed-Passwort (Default Demo1234!).
|
||
# SEED_PASSWORD=
|
||
# RLS-Test hart statt Skip, wenn craftvia_app kein LOGIN hat (CI).
|
||
# RLS_TEST_REQUIRED=true
|