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.
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:
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.