Zum Inhalt

On-Premise-Konfiguration

Dieser Leitfaden behandelt erforderliche und optionale Umgebungsvariablen für On-Premise-Bereitstellungen. Eine vollständige Vorlage ist unter infra/.env.onprem.example verfügbar.

Erforderlich: Bereitstellungsmodus

Variable Beschreibung Beispiel
DEPLOYMENT_MODE Muss single-tenant sein für On-Premise-Bereitstellungen single-tenant

Optional: Mandantenidentität

Variable Erforderlich Standard Beschreibung
DEFAULT_TENANT_SLUG Nein default Interne Kennung für den Mandanten (URL-sicher, Kleinbuchstaben)
DEFAULT_TENANT_NAME Nein My Organization Name Ihrer Organisation, angezeigt im UI-Header und in Berichten

Beim ersten Start erstellt KANAP automatisch einen Mandanten mit diesen Werten. Die Standardwerte funktionieren für die meisten Bereitstellungen -- Sie müssen sie nur ändern, wenn ein bestimmter Organisationsname in der Anwendung erscheinen soll.

Erforderlich: Admin-Zugangsdaten

Variable Beschreibung Beispiel
ADMIN_EMAIL E-Mail des initialen Admin-Benutzers admin@firma.de
ADMIN_PASSWORD Initiales Admin-Passwort (nach der ersten Anmeldung ändern!) AendernSie123!
JWT_SECRET JWT-Signaturschlüssel (generieren: openssl rand -hex 32) 64 Hex-Zeichen
APP_BASE_URL Öffentliche URL (verwendet in E-Mail-Links) https://kanap.firma.de
CORS_ORIGINS Kommagetrennte erlaubte Browser-Origins (in Produktion erforderlich) https://*.firma.de

E-Mail-Links: Passwortzurücksetzungs-/Einladungs-URLs verwenden APP_BASE_URL (oder weitergeleiteten Host/Proto). On-Premise sollte APP_BASE_URL auf die extern erreichbare URL setzen und den Reverse Proxy so konfigurieren, dass er Host / X-Forwarded-Proto weitergibt.

CORS: Konfigurieren Sie CORS_ORIGINS, um zu steuern, welche Browser-Origins auf die API zugreifen können. Die Anwendung startet in Produktion nicht, wenn CORS_ORIGINS nicht gesetzt ist. Setzen Sie es auf die exakte URL, über die Benutzer auf KANAP zugreifen.

# Muss mit APP_BASE_URL übereinstimmen
CORS_ORIGINS=https://kanap.firma.de

Startvalidierung: Die Anwendung verweigert den Start, wenn JWT_SECRET, DATABASE_URL oder APP_BASE_URL fehlen oder leer sind. Sie verweigert auch den Betrieb, wenn die PostgreSQL-Rolle aus DATABASE_URL noch SUPERUSER oder BYPASSRLS ist.

Erforderlich: Datenbank

Variable Beschreibung Beispiel
DATABASE_URL PostgreSQL-Verbindungsstring postgres://user:pass@host:5432/kanap?sslmode=require

Datenbankanforderungen: - PostgreSQL 16 oder höher (getestetes Minimum; ältere Versionen können funktionieren, werden aber nicht unterstützt) - Erweiterungen: citext, pgcrypto, uuid-ossp - Benutzer benötigt CREATE TABLE / ALTER TABLE-Berechtigungen für Migrationen - Empfohlen: Dedizierte Datenbank - DATABASE_URL muss eine dedizierte Anwendungsrolle verwenden, nicht postgres oder eine andere Cluster-Admin-Rolle - Empfohlen: App-Rolle von Anfang an als NOSUPERUSER NOBYPASSRLS erstellen

Datenbankeinrichtung (Beispiel):

-- 1. Datenbank und dedizierte App-Rolle erstellen
CREATE DATABASE kanap;
CREATE USER kanap WITH PASSWORD 'sicheres-passwort' NOSUPERUSER NOBYPASSRLS;
GRANT ALL PRIVILEGES ON DATABASE kanap TO kanap;

-- 2. Mit kanap-Datenbank verbinden und Erweiterungen aktivieren
\c kanap
CREATE EXTENSION IF NOT EXISTS citext;
CREATE EXTENSION IF NOT EXISTS pgcrypto;
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";

-- 3. Schema-Berechtigungen vergeben (für Migrationen)
GRANT ALL ON SCHEMA public TO kanap;

Wenn eine dedizierte Anwendungsrolle anfangs mit zu vielen Rechten erstellt wurde, wird KANAPs erste Migration sie automatisch auf NOSUPERUSER NOBYPASSRLS härten. Wenn DATABASE_URL auf eine geschützte Cluster-Admin-Rolle wie postgres zeigt, schlägt der Start fehl und Sie müssen auf eine dedizierte App-Rolle wechseln.

Erforderlich: Speicher

Variable Beschreibung Beispiel
S3_ENDPOINT S3-kompatibler Endpunkt https://s3.amazonaws.com
S3_BUCKET Bucket-Name (muss existieren) kanap-files
S3_REGION Region us-east-1
AWS_ACCESS_KEY_ID Zugriffsschlüssel AKIA...
AWS_SECRET_ACCESS_KEY Geheimschlüssel secret
S3_FORCE_PATH_STYLE true für MinIO, false für AWS/R2 false

Bucket-Anforderungen: - Erstellen Sie den Bucket vor dem Start von KANAP (wird nicht automatisch erstellt) - Berechtigungen: s3:PutObject, s3:GetObject, s3:DeleteObject, s3:ListBucket

KANAP verwendet den AWS SDK v3 S3-Client für den Objektspeicherzugriff; jeder Anbieter mit S3-kompatiblem API-Verhalten wird unterstützt.

Getestete Anbieter: - AWS S3 (S3_ENDPOINT=https://s3.amazonaws.com, S3_FORCE_PATH_STYLE=false) - MinIO (S3_ENDPOINT=http://minio:9000, S3_FORCE_PATH_STYLE=true) - Cloudflare R2 (https://<account>.r2.cloudflarestorage.com) - Hetzner (https://<region>.your-objectstorage.com)

Optional: E-Mail über Resend

Variable Beschreibung Beispiel
RESEND_API_KEY Resend API-Schlüssel re_xxxxx
RESEND_FROM_EMAIL Absenderadresse KANAP <noreply@ihredomain.de>

Wenn nicht konfiguriert, kann KANAP in Single-Tenant-Bereitstellungen dennoch E-Mail über SMTP senden. Wenn weder Resend noch SMTP konfiguriert ist, sind E-Mail-Funktionen deaktiviert, einschließlich Benutzereinladungen und Passwortzurücksetzung. Siehe Betrieb für SQL-Passwortzurücksetzungs-Fallback.

Optional: E-Mail über SMTP (nur Single-Tenant / On-Premise)

SMTP wird nur im Modus DEPLOYMENT_MODE=single-tenant unterstützt. Multi-Tenant/Cloud-Bereitstellungen verwenden weiterhin Resend.

Variable Beschreibung Beispiel
SMTP_HOST SMTP-Server-Hostname smtp.firma.de
SMTP_PORT SMTP-Port 587
SMTP_USER SMTP-Benutzername kanap
SMTP_PASSWORD SMTP-Passwort secret
SMTP_FROM Absenderadresse KANAP <noreply@firma.de>
SMTP_SECURE true für implizites TLS (465), false für STARTTLS/Plain (587/25) false

Hinweise: - SMTP_USER und SMTP_PASSWORD sind optional. Lassen Sie beide ungesetzt für Relays, die dem Quellhost/der Quell-IP vertrauen. - Wenn SMTP_SECURE nicht gesetzt ist, verwendet KANAP standardmäßig true für Port 465 und false andernfalls. - Wenn sowohl SMTP als auch Resend im Single-Tenant-Modus konfiguriert sind, hat SMTP Vorrang. - SMTP_FROM sollte eine Adresse sein, als die Ihr SMTP-Server senden darf. - Wenn E-Mail außerhalb Ihres Netzwerks gesendet wird, konfigurieren Sie SPF, DKIM und DMARC auf der Absenderdomain über Ihren Mail-Administrator oder Provider.

Gängige SMTP-Profile

Internes Relay ohne Authentifizierung:

SMTP_HOST=mail.firma.local
SMTP_PORT=25
SMTP_SECURE=false
SMTP_FROM=KANAP <noreply@firma.de>

Authentifiziertes Relay oder Provider:

SMTP_HOST=smtp.firma.de
SMTP_PORT=587
SMTP_SECURE=false
SMTP_USER=noreply@firma.de
SMTP_PASSWORD=secret
SMTP_FROM=KANAP <noreply@firma.de>

Microsoft 365 SMTP-Übermittlung:

SMTP_HOST=smtp.office365.com
SMTP_PORT=587
SMTP_SECURE=false
SMTP_USER=noreply@firma.de
SMTP_PASSWORD=secret
SMTP_FROM=KANAP <noreply@firma.de>

Verwenden Sie das Microsoft 365-Profil nur, wenn SMTP AUTH für das Postfach und den Mandanten erlaubt ist.

Optional: Entra SSO

Siehe den dedizierten Leitfaden: sso-entra.md.

Optional: Erweitert

Variable Beschreibung Standard
LOG_LEVEL Protokollierungsausführlichkeit (debug, info, warn, error) info
JWT_ACCESS_TOKEN_TTL Zugriffstoken-Lebensdauer 15m
JWT_REFRESH_TOKEN_TTL Aktualisierungstoken-Lebensdauer 4h
RATE_LIMIT_ENABLED App-Level Rate-Limiting-Schalter true
RATE_LIMIT_TRUST_PROXY Proxy-Header für Client-IP-Erkennung vertrauen false
APP_URL Basis-URL für Benachrichtigungs-E-Mail-Links im Multi-Tenant-Modus (Mandanten-Slug ersetzt app). Nicht benötigt für On-Premise -- APP_BASE_URL wird stattdessen verwendet. https://app.kanap.net
EMAIL_OVERRIDE Alle E-Mails an diese Adresse umleiten (nur Dev/QA, nie in Produktion) nicht gesetzt

Vollständiges Beispiel (.env)

# =============================================================================
# KANAP On-Premise-Konfiguration
# =============================================================================

# BEREITSTELLUNGSMODUS (erforderlich)
DEPLOYMENT_MODE=single-tenant

# MANDANTENKONFIGURATION (optional - Standardwerte gezeigt)
DEFAULT_TENANT_SLUG=default
DEFAULT_TENANT_NAME=Meine Organisation

# ADMIN-ZUGANGSDATEN (erforderlich)
ADMIN_EMAIL=admin@firma.de
ADMIN_PASSWORD=AendernSieDiesesPasswort123!

# SICHERHEIT (erforderlich)
JWT_SECRET=

# ANWENDUNGS-URL (erforderlich)
APP_BASE_URL=https://kanap.ihre-domain.de

# DATENBANK (erforderlich - dedizierte App-Rolle verwenden, nie postgres)
DATABASE_URL=postgres://kanap:passwort@ihr-postgres:5432/kanap?sslmode=require

# SPEICHER (erforderlich)
S3_ENDPOINT=https://s3.amazonaws.com
S3_BUCKET=kanap-files
S3_REGION=us-east-1
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
S3_FORCE_PATH_STYLE=false   # true für MinIO

# E-MAIL (optional - Resend)
# RESEND_API_KEY=re_xxxxx
# RESEND_FROM_EMAIL=KANAP <noreply@ihredomain.de>

# E-MAIL (optional - SMTP, nur Single-Tenant)
# SMTP_HOST=smtp.firma.de
# SMTP_PORT=587
# SMTP_SECURE=false
# SMTP_USER=
# SMTP_PASSWORD=
# SMTP_FROM=KANAP <noreply@firma.de>

# ERWEITERT (optional - Standardwerte sind in Ordnung)
# LOG_LEVEL=info
# JWT_ACCESS_TOKEN_TTL=15m
# JWT_REFRESH_TOKEN_TTL=4h
# RATE_LIMIT_ENABLED=true
# RATE_LIMIT_TRUST_PROXY=false

Firewall-Regeln

Nach dem initialen Build kann KANAP vollständig isoliert (Air-Gapped) betrieben werden, wenn E-Mail-, SSO- und FX-Kurs-Funktionen alle deaktiviert sind.

Eingehend

Port Protokoll Zweck
443 TCP HTTPS -- nginx Reverse Proxy, der die Anwendung ausliefert
80 TCP HTTP -- leitet auf HTTPS um

Ausgehend -- Ersteinrichtung & Build

Diese Ziele werden nur während der Installation und docker build benötigt. Sie können geschlossen werden, sobald die Anwendung läuft.

Ziel Port Zweck
github.com 443 KANAP-Quellcode klonen
download.docker.com 443 Docker APT-Repository
dl.min.io 443 MinIO-Binary-Download
registry.npmjs.org 443 npm-Abhängigkeiten während docker build
registry-1.docker.io, production.cloudflare.docker.com 443 Basis-Docker-Images pullen (node:20-alpine, nginx:alpine)
Ubuntu APT-Mirrors 80/443 Systempakete (PostgreSQL, nginx usw.)

Ausgehend -- Laufzeit (Bedingt)

Nur erforderlich, wenn die entsprechende Funktion aktiviert ist.

Ziel Port Zweck Wann
api.resend.com 443 Transaktions-E-Mail Wenn RESEND_API_KEY gesetzt ist
Ihr SMTP-Relay oder Provider 25 / 465 / 587 Transaktions-E-Mail über SMTP Wenn SMTP_HOST gesetzt ist
login.microsoftonline.com 443 Entra ID SSO-Metadaten & Tokens Wenn Entra SSO konfiguriert ist
graph.microsoft.com 443 Benutzerprofil-Anreicherung Wenn Entra SSO konfiguriert ist
api.worldbank.org 443 Jährliche FX-Kurse Optional
v6.exchangerate-api.com 443 Kassakurse Optional

Intern (Keine Firewall-Regel nötig)

Diese Verbindungen bleiben auf dem Server -- Loopback oder Docker-Bridge-Netzwerk.

Verbindung Port Hinweise
nginx → API-Container 8080 Gebunden an 127.0.0.1
nginx → Web-Container 8081 Gebunden an 127.0.0.1
API-Container → PostgreSQL 5432 Über host.docker.internal (Docker-Bridge 172.16.0.0/12)
API-Container → MinIO 9000 Über host.docker.internal
MinIO-Konsole 9001 Nur lokale Administration, nicht extern exponiert

Hintergrundjobs

Das Backend führt geplante Hintergrundjobs für E-Mail-Benachrichtigungen aus: - Ablaufwarnungen: täglich um 08:00 UTC -- warnt Benutzer vor Verträgen und OPEX-Positionen, die innerhalb von 30 Tagen ablaufen. - Wöchentlicher Zusammenfassungs-Digest: stündliche Prüfung -- sendet zeitzonenbewusste wöchentliche Zusammenfassungen an Benutzer, die sich dafür entschieden haben.

Diese Jobs erfordern, dass die API als dauerhaft laufender Prozess läuft (nicht als Serverless-Funktion). Im On-Premise-Modus wird APP_BASE_URL für Benachrichtigungs-E-Mail-Links verwendet (keine Subdomain-Ableitung). Wenn kein ausgehender E-Mail-Transport konfiguriert ist, überspringen diese Jobs das Senden problemlos.