Zum Inhalt

On-Premise-Installation

Voraussetzungen

Serveranforderungen: - Linux-Server (Ubuntu 22.04+, Debian 12+, RHEL 9+ oder jedes Docker-fähige OS) - Docker Engine 24.0+ - Docker Compose v2.20+ - Git - Mindestens 4 GB RAM (8 GB empfohlen) - Mindestens 20 GB Festplatte (+ Build-Cache)

Vom Kunden bereitgestellte Infrastruktur:

Komponente Anforderung
PostgreSQL Version 16+ mit den Erweiterungen citext, pgcrypto, uuid-ossp und einer dedizierten Anwendungsrolle für DATABASE_URL
S3-Speicher Jeder S3-kompatible: AWS S3, MinIO, Cloudflare R2, Hetzner usw.
Reverse Proxy TLS-Terminierung und Routing (nginx, Traefik, Caddy usw.)
Domain DNS-Eintrag, der auf Ihren Server zeigt

Optional: - Konfiguration für ausgehende E-Mail: Resend API-Schlüssel oder SMTP-Relay/Server-Details - Microsoft Entra SSO (siehe sso-entra.md)

Schnellstart

# 1. Repository klonen
git clone https://github.com/kanap-it/kanap.git
cd kanap

# 2. Umgebung konfigurieren VOR dem Bauen
cp infra/.env.onprem.example .env
nano .env  # DATABASE_URL, S3-Credentials, ADMIN_EMAIL, JWT_SECRET, APP_BASE_URL setzen
# Siehe den Konfigurationsleitfaden für alle Variablen

# 3. Docker-Images bauen
docker build -t kanap-api:latest ./backend
docker build -t kanap-web:latest ./frontend

# 4. Container starten
docker compose -f infra/compose.onprem.yml up -d

# 5. Start überprüfen
docker compose -f infra/compose.onprem.yml logs -f api
# Auf "Application started"-Meldung warten
# Beim ersten Start erstellt KANAP automatisch Mandant, Admin-Benutzer und Abonnement

# 6. Ihren Reverse Proxy konfigurieren, um Traffic zu routen an:
#    - /api/* → api:8080
#    - /*     → web:80
# Stellen Sie sicher, dass der Proxy Host beibehält und X-Forwarded-Proto setzt.

# 7. Auf Anwendung zugreifen
# https://kanap.ihre-domain.de
# Mit ADMIN_EMAIL / ADMIN_PASSWORD aus .env anmelden

Wichtig: Schließen Sie die Konfiguration (Schritt 2) ab, bevor Sie Container starten. Die API liest .env beim Start und erstellt beim ersten Start den Mandanten und Admin-Benutzer mit diesen Werten.

Datenbankrollen-Anforderung: DATABASE_URL muss eine dedizierte PostgreSQL-Anwendungsrolle verwenden. Zeigen Sie nicht auf postgres oder eine andere Cluster-Admin-Rolle. KANAP verweigert den Start, anstatt ohne effektive RLS-Durchsetzung zu laufen.

E-Mail-Wahl: On-Premise-Bereitstellungen können entweder Resend oder SMTP für ausgehende E-Mail verwenden. SMTP ist nützlich, wenn der Kunde bereits ein internes Mail-Relay oder einen verwalteten Anbieter wie Microsoft 365 hat. Konfigurieren Sie eine dieser Optionen, wenn Sie möchten, dass Passwortzurücksetzung, Einladungen und Benachrichtigungs-E-Mails ab dem ersten Tag funktionieren.

Reverse-Proxy-Beispiel (nginx)

Reverse-Proxy-Anforderungen:

  1. TLS auf Port 443 terminieren
  2. /api/* an den API-Container routen (Port 8080)
  3. Alle anderen Anfragen an den Web-Container routen (Port 80)
  4. X-Forwarded-Proto: https setzen und Host / X-Forwarded-Host beibehalten
  5. WebSocket-Upgrade unterstützen (verwendet für Echtzeit-Funktionen)

Da Container an 127.0.0.1 gebunden sind, läuft nginx auf dem gleichen Host und proxyt zu localhost.

server {
    listen 443 ssl;
    listen [::]:443 ssl;
    server_name kanap.company.com;

    ssl_certificate     /path/to/fullchain.pem;
    ssl_certificate_key /path/to/privkey.pem;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers off;

    # Datei-Upload-Limit (KANAP unterstützt bis zu 20 MB)
    client_max_body_size 20m;

    # /api → /api/ kanonisieren
    location = /api { return 301 /api/; }

    # API: /api-Präfix vor dem Proxying entfernen
    location ^~ /api/ {
        proxy_pass http://127.0.0.1:8080/;
        proxy_set_header Host              $host;
        proxy_set_header X-Real-IP         $remote_addr;
        proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-Host  $host;

        # WebSocket-Unterstützung
        proxy_http_version 1.1;
        proxy_set_header Upgrade    $http_upgrade;
        proxy_set_header Connection "upgrade";

        # Lang laufende Anfragen (Exporte, Importe)
        proxy_read_timeout  300s;
        proxy_send_timeout  300s;
        proxy_redirect off;
    }

    # Alles andere → SPA
    location / {
        proxy_pass http://127.0.0.1:8081;
        proxy_set_header Host              $host;
        proxy_set_header X-Real-IP         $remote_addr;
        proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        proxy_http_version 1.1;
        proxy_set_header Upgrade    $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_redirect off;
    }
}

server {
    listen 80;
    listen [::]:80;
    server_name kanap.company.com;
    return 301 https://$host$request_uri;
}

Selbstsigniertes TLS (keine Domain): Wenn Sie keine Domain haben und per IP-Adresse auf KANAP zugreifen, erstellen Sie ein selbstsigniertes Zertifikat:

sudo mkdir -p /etc/ssl/kanap
sudo openssl req -x509 -nodes -days 365 \
  -newkey rsa:2048 \
  -keyout /etc/ssl/kanap/server.key \
  -out /etc/ssl/kanap/server.crt \
  -subj "/CN=IHRE_IP" \
  -addext "subjectAltName=IP:IHRE_IP"

Ersetzen Sie IHRE_IP durch die IP-Adresse Ihres Servers und aktualisieren Sie server_name, APP_BASE_URL und CORS_ORIGINS entsprechend. Benutzer müssen beim ersten Zugriff die Browser-Zertifikatswarnung akzeptieren.

host.docker.internal: Wenn PostgreSQL oder S3-Speicher auf dem Docker-Host laufen (nicht in einem Container), verwenden Sie host.docker.internal als Hostname in DATABASE_URL und S3_ENDPOINT. Die Datei compose.onprem.yml enthält das extra_hosts-Mapping, das dies ermöglicht.

Netzwerkarchitektur

                    ┌─────────────────────────────────────────────────────┐
                    │              Kunden-Infrastruktur                    │
                    │                                                      │
    Internet        │  ┌──────────────┐    ┌─────────────────────────┐   │
        │           │  │ Ihr Reverse  │    │     Docker-Host         │   │
        │           │  │    Proxy     │    │                         │   │
   ┌────▼────┐      │  │   (TLS)      │    │  ┌─────┐    ┌─────┐    │   │
   │ Browser │──────┼─▶│   :443       │───▶│  │ api │    │ web │    │   │
   └─────────┘      │  └──────────────┘    │  │:8080│    │ :80 │    │   │
                    │                      │  └─────┘    └─────┘    │   │
                    │  ┌──────────────┐    └─────────────────────────┘   │
                    │  │  PostgreSQL  │                                   │
                    │  │   (Ihres)    │◀──────── DATABASE_URL            │
                    │  └──────────────┘                                   │
                    │  ┌──────────────┐                                   │
                    │  │  S3-Speicher │◀──────── S3_ENDPOINT             │
                    │  │   (Ihres)    │                                   │
                    │  └──────────────┘                                   │
                    └─────────────────────────────────────────────────────┘

Deployment-Modell: Nur Single-Container-Deployment. Der Betrieb mehrerer API- oder Web-Replikas wird nicht unterstützt. Für Hochverfügbarkeit verlassen Sie sich auf Docker-Neustart-Richtlinien und Infrastruktur-Redundanz (Datenbank-HA, S3-Haltbarkeit).

Erste Anmeldung

  1. Navigieren Sie zu https://<ihre-domain>
  2. Melden Sie sich mit den Zugangsdaten aus .env an (ADMIN_EMAIL / ADMIN_PASSWORD)
  3. Ändern Sie sofort das Admin-Passwort über das Benutzerprofil
  4. Konfigurieren Sie Organisationseinstellungen
  5. Laden Sie weitere Benutzer ein (wenn E-Mail konfiguriert ist)