Files
craftvia/.env.prod.example
T
msolarczekandClaude Opus 5 cadaedc6cc L10b Betrieb & Aufräumen: Deploy – craftvia-worker, CI-Testjob, DEPLOY.md, Certvia-Doku archiviert
- 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>
2026-09-14 18:19:19 +02:00

134 lines
6.1 KiB
Bash
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.
# Referenz für die PRODUKTIV-Env-Variablen (Coolify, docker-compose.coolify[.prebuilt].yml).
# ECHTE Secrets NUR in Coolify eintragen – diese Datei enthält nur Platzhalter.
# Unterschiede zum Testserver: HTTPS-AUTH_URL, KEIN Demo-Seed, stattdessen Bootstrap-Admin,
# RLS scharf. Betriebsdoku: docs/craftvia/DEPLOY.md
# --- Datenbank (Service "postgres") ---
POSTGRES_USER=craftvia
POSTGRES_PASSWORD=CHANGE_ME_starkes_db_passwort
POSTGRES_DB=craftvia
DATABASE_URL=postgresql://craftvia:CHANGE_ME_starkes_db_passwort@postgres:5432/craftvia?schema=public
# --- Row Level Security scharfschalten (F-04) ---
# RLS_ENFORCED=true – app und craftvia-worker verbinden sich als eingeschränkte Rolle
# craftvia_app (NOBYPASSRLS) und setzen app.tenant_id pro Transaktion; FORCE ROW LEVEL
# SECURITY macht die Policies dann scharf. Ist der Kontext nicht gesetzt, sieht craftvia_app
# NULL Zeilen – daher NUR mit korrekt gesetztem RLS_DATABASE_URL einschalten (sonst
# bricht die App beim Start bewusst ab).
# WICHTIG: Die Owner-/Migrate-Rolle in DATABASE_URL MUSS BYPASSRLS/Superuser sein
# (Migrationen, Seed, Mail-/Backup-Worker und der mandantenübergreifende Login-Lookup
# laufen darüber). craftvia_app wird von der Baseline-Migration NOLOGIN angelegt und in
# Prod EINMALIG mit LOGIN + starkem Passwort versehen:
# ALTER ROLE craftvia_app WITH LOGIN PASSWORD '<stark>';
RLS_ENFORCED=true
RLS_DATABASE_URL=postgresql://craftvia_app:CHANGE_ME_starkes_craftvia_app_passwort@postgres:5432/craftvia?schema=public
# --- Redis (Service "redis") ---
# F-18: Redis läuft mit requirepass. NUR REDIS_PASSWORD setzen – REDIS_URL wird in den
# Coolify-Compose-Dateien daraus abgeleitet (redis://:${REDIS_PASSWORD}@redis:6379).
REDIS_PASSWORD=CHANGE_ME_starkes_redis_passwort
# --- Objektspeicher (Service "garage", S3-kompatibel) ---
# Bucket/Key legt der Init-Job "garage-provision" an (Admin-API). Format erzwungen:
# S3_ACCESS_KEY = "GK" + 24 Hex -> echo "GK$(openssl rand -hex 12)"
# S3_SECRET_KEY = 64 Hex -> openssl rand -hex 32
S3_ENDPOINT=http://garage:3900
S3_ACCESS_KEY=GK000000000000000000000000
S3_SECRET_KEY=CHANGE_ME_openssl_rand_hex_32
S3_BUCKET=craftvia-documents
S3_REGION=us-east-1
# Garage-Daemon-Secrets (LITERAL in Coolify setzen, nicht via ${...}).
GARAGE_RPC_SECRET=CHANGE_ME_openssl_rand_hex_32
GARAGE_ADMIN_TOKEN=CHANGE_ME_openssl_rand_hex_32
# GARAGE_ZONE=dc1
# GARAGE_CAPACITY_BYTES=100000000000
# --- Backup-Zielspeicher (optional) ---
# Ziel der Backup-/DSGVO-Artefakte ist im Betreiber-Portal (/admin/backup) waehlbar
# (Lokal/S3) und wird verschluesselt in der DB gehalten. Praezedenz: DB-Config →
# Env (S3_*/BACKUP_LOCAL_DIR) → lokaler Default. Fuer „Lokal" mountet die Compose-Datei
# das persistente Volume `backups` auf /app/.backups (app + backup-worker).
BACKUP_LOCAL_DIR=/app/.backups
# Optionaler eigener Backup-Bucket (nur wenn der Backup-Store auf S3 laeuft).
# BACKUP_S3_BUCKET=
# Verschluesselung der Backup-Artefakte (AES-256-GCM); leer = AUTH_SECRET. Je Umgebung
# eigener Wert, alte Keys bis Retention-Ende aufbewahren.
BACKUP_ENC_KEY=CHANGE_ME_openssl_rand_hex_32
# --- Auth (Auth.js v5) – Produktiv über HTTPS ---
# AUTH_SECRET: openssl rand -base64 32 (frisch, NICHT der Testwert)
AUTH_SECRET=CHANGE_ME_openssl_rand_base64_32
# PASSWORD_PEPPER (Härtung §1): openssl rand -hex 32 — frisch je Umgebung, NICHT rotierbar, nie ins Artefakt.
PASSWORD_PEPPER=CHANGE_ME_openssl_rand_hex_32
# MFA_ENC_KEY: TOTP-Secrets at-rest (leer = aus AUTH_SECRET). ⚠ Nach dem Setzen nicht mehr ändern.
MFA_ENC_KEY=CHANGE_ME_openssl_rand_hex_32
AUTH_URL=https://app.craftvia.example
# AUTH_TRUST_HOST ist im Compose fest auf true (hinter dem Coolify-Proxy) – nicht nötig.
# Passkeys/WebAuthn: leer = aus AUTH_URL abgeleitet.
# WEBAUTHN_ORIGIN=https://app.craftvia.example
# WEBAUTHN_RP_ID=app.craftvia.example
# --- E-Mail (produktives SMTP-Relay; SPF/DKIM/DMARC der Absenderdomain vorher einrichten) ---
SMTP_HOST=
SMTP_PORT=587
# true = implizites TLS (465), false = STARTTLS (587); leer = aus Port abgeleitet.
SMTP_SECURE=
SMTP_USER=
SMTP_PASSWORD=
SMTP_FROM=no-reply@craftvia.example
MAIL_FROM_NAME=Craftvia
MAIL_REPLY_TO=
# Basis für absolute Links in Mails/PDFs; leer = AUTH_URL.
APP_BASE_URL=https://app.craftvia.example
# --- KI: Auftragsimport-Extraktion & Lotse (Anthropic) ---
# Ohne ANTHROPIC_API_KEY: graceful degradation (manuelle Erfassung, kein Lotse-Entwurf).
AI_EXTRACTION_PROVIDER=anthropic
ANTHROPIC_API_KEY=
# Leer = Default-Modell aus src/server/ai/client.ts
ANTHROPIC_MODEL=
# --- KI: 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
# --- KI: Kostenbremse & Aufbewahrung ---
# Tokens (ein + aus) je Mandant je Kalendermonat; darüber lehnen Lotse und
# Import-Extraktion ab. 0 = unbegrenzt.
AI_MONTHLY_TOKEN_LIMIT=0
# Nach N Tagen leert/pseudonymisiert ein Worker-Job Ein-/Ausgaben im KI-Protokoll
# (AiGeneration). Frist mit dem DSB abstimmen.
AI_GENERATION_RETENTION_DAYS=180
# --- Craftvia: API-Rate-Limits (je Nutzer, Anfragen pro Minute) ---
API_RATE_LIMIT_PER_MINUTE=300
# /api/v1/sync, /api/v1/uploads, /api/v1/field/**
API_FIELD_RATE_LIMIT_PER_MINUTE=1200
# --- Craftvia: Offline/PWA ---
OFFLINE_MAX_DAYS=7
# --- Craftvia: optionaler Malware-Scan (ClamAV clamd) ---
CLAMAV_HOST=
CLAMAV_PORT=3310
# PDF_CHROMIUM_PATH ist im Worker-Image/Compose fest /usr/bin/chromium – nicht setzen.
# --- Demo-Seed: in PROD AUS lassen! ---
RUN_DEMO_SEED=false
# --- Erst-Admin-Bootstrap (statt Demo-Seed) ---
# Beim ersten Deploy true setzen -> migrate-Job legt Plattform-Admin + ersten Mandanten an
# (idempotent). Danach auf false setzen oder stehen lassen (No-op, wenn vorhanden).
BOOTSTRAP_ADMIN=true
BOOTSTRAP_ADMIN_EMAIL=admin@craftvia.example
BOOTSTRAP_ADMIN_PASSWORD=CHANGE_ME_initiales_admin_passwort
BOOTSTRAP_ADMIN_NAME=Craftvia Admin
BOOTSTRAP_TENANT_NAME=Musterbetrieb GmbH
BOOTSTRAP_TENANT_SLUG=musterbetrieb
BOOTSTRAP_TENANT_SHORT=Musterbetrieb
BOOTSTRAP_TENANT_SECTOR=