1. Objective

The objective of the web server configuration is to
  • provide the locally operated AI and RAG services
  • in a secure and controlled manner
  • via HTTP/HTTPS in the internal network
  • with a clear separation between

Der Webserver fungiert als Reverse Proxy, TLS-Termination und Zugriffskontrollschicht.

2. Systemarchitektur und Überlegung

Zielarchitektur soll sein:

Komponente

Funktion

Nginx

Reverse Proxy + TLS

Ollama

LLM Runtime (GPU-gestützt)

RAG API (FastAPI)

Dokumenten-Retrieval + LLM-Orchestrierung

Qdrant

Vektor-Datenbank

Open WebUI

Chat-Frontend

2.1 Warum so?

Das Ziel besteht darin, ein RAG-System zu schaffen, auf das externe Programme über den Ollama-Service zugreifen können. Das RAG-System soll maßgeblich auf der KI laufen und selbst entwickelte Programme, die beispielsweise auf einem Mac oder einem Windows-Rechner laufen, sollen den Ollama-Dienst nutzen können. Darüber hinaus soll die Nutzung von OpenWebUI zum Testen und Stellen von Anfragen möglich sein. Die Aufteilung in verschiedene Module soll eine spätere Verteilung auf verschiedene KI-Systeme ermöglichen, z. B. wenn der Cluster erweitert wird oder verteilte Rechenaufgaben auf verschiedenen Maschinen laufen sollen.

3. Warum Nginx als Reverse Proxy?

Begründung:

  1. Trennung von Anwendung und Exposition

    → Die Dienste laufen intern auf 127.0.0.1 (z. B. 8080, 3000, 11434).

  2. TLS-Termination zentral

    → Nur Nginx verwaltet Zertifikate (/etc/ssl/localca/homecpt.crt).

  3. Pfadbasierte Routing-Logik

    /rag/ → RAG-API

    / → Open WebUI

  4. Timeouts steuerbar

    → LLM-Generierung kann mehrere Minuten dauern

    → Standard-Timeouts wären zu kurz

  5. Erweiterbarkeit

    → Logging, Rate Limiting, Access-Control später möglich

Der Dienst läuft lokal und nicht in einem Dogger.

4. Server-Konfiguration: "homecpt" auf Port 443

Konfigurationsbeispiel NGINX: Achtung: Fehler: Hier wird NGINX in einem Docker installiert. Kann man machen! location /rag/ { rewrite ^/rag/(.*)$ /$1 break; proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; proxy_set_header X-Forwarded-Proto https; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_connect_timeout 30s; proxy_read_timeout 3600s; proxy_send_timeout 3600s; send_timeout 3600s; proxy_buffering off; proxy_cache off; } Und hier direkt auf der Maschine ohne Docker:

Wichtigste Pfade:

  • Hauptconfig: /etc/nginx/nginx.conf

  • vHosts: /etc/nginx/sites-available/

  • aktive vHosts (Symlinks): /etc/nginx/sites-enabled/

  • Logs: /var/log/nginx/access.log, /var/log/nginx/error.log

Best Practice:

  • bearbeiten in sites-available

  • aktivieren per Symlink in sites-enabled

Eigene Site anlegen (Beispiel: homecpt) Datei erstellen :

sudo nano /etc/nginx/sites-available/homecpt

Beispiel (HTTP-only, später HTTPS ergänzen):

server {

    listen 80;

    server_name homecpt homecpt.local;

    location / {

        proxy_pass http://127.0.0.1:3000/;  # Open WebUI

        proxy_http_version 1.1;

        proxy_set_header Host $host;

        proxy_set_header X-Forwarded-Proto http;

        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        proxy_set_header Upgrade $http_upgrade;

        proxy_set_header Connection $connection_upgrade;

        proxy_read_timeout 3600s;

        proxy_send_timeout 3600s;

        proxy_buffering off;

        proxy_cache off;

    }

    location /rag/ {

        rewrite ^/rag/(.*)$ /$1 break;

        proxy_pass http://127.0.0.1:8080;

        proxy_set_header Host $host;

        proxy_set_header X-Forwarded-Proto http;

        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        proxy_connect_timeout 30s;

        proxy_read_timeout 3600s;

        proxy_send_timeout 3600s;

        send_timeout 3600s;

        proxy_buffering off;

        proxy_cache off;

    }

}

Aktivieren:

sudo ln -s /etc/nginx/sites-available/homecpt /etc/nginx/sites-enabled/homecpt

Default deaktivieren:

sudo rm -f /etc/nginx/sites-enabled/default

4.1 Warum diese Konfiguration gewählt wurde

4.1.1 rewrite-Regel

rewrite ^/rag/(.*)$ /$1 break;

Begründung:

  • Die RAG-API kennt keine /rag-Prefixe.

  • Intern läuft sie auf /ask, /upload, /evaluate (Selbst definierte Schnittstellen in app.py im Dogger RAG).

  • Der Reverse Proxy entfernt das Präfix.

→ Trennung von externer URL-Struktur und interner API-Logik.

4.1.2 Lange Timeouts (3600s)

Begründung:

  • LLM-Generierung (große Modelle wie Mixtral 8x22B) kann mehrere Minuten dauern.

  • Standard-Nginx-Timeout (~60s) führte zu:
    • upstream timed out
    • Browser NetworkError
  • Daher wurden explizit hohe Werte gesetzt.

→ Stabilität > Standard-Web-Latenz.

4.1.3 proxy_buffering off

Begründung:

  • Verhindert, dass Nginx die Antwort puffert.

Besonders wichtig bei:

    • langen Antworten

    • Streaming

    • großen JSON-Responses

→ Direktes Durchreichen der Upstream-Antwort.

4.1.4 X-Forwarded-Proto Header

Begründung:

  • FastAPI / Backend muss wissen, dass der Client HTTPS nutzt.

    • korrekte URL-Generierung

    • Security-Policies

    • Logs

      Wichtig für:

5. Sicherheitsüberlegungen

5.1 Interne Bindung

  • Ollama läuft auf 0.0.0.0:11434, aber Zugriff erfolgt primär über Proxy.

  • RAG läuft intern auf 127.0.0.1:8080.

→ Minimierung direkter Angriffsfläche.

5.2 Netztrennung

  • Guest-Zugriff über guest.homecpt

  • Interner Zugriff über homecpt

→ Segmentierung zwischen Admin und Gastnutzung.

6. Docker-Konzept

Der Webserver läuft lokal, um möglichst höchste Performance zu haben und bei einem Neustart den Fehler zu verhindern, dass der Dogger nicht startet. Bei den anderen Modulen habe ich mich für Docker entschieden.

6.1 Warum Docker?

  • Reproduzierbarkeit

  • Saubere Trennung der Dienste

  • Einfache Updates

  • GPU-Passthrough via NVIDIA Runtime

Begründung:

  • Möglichkeit der Begrenzung des Kontextfensters verhindert exzessive Speicherallokation.

  • Reduktion paralleler Modelle stabilisiert GPU-Verhalten.

6.2 Nachteil:

 Zusätzliche Komplexität
  • Docker + Docker Compose + Netzwerke + Volumes

  • Fehlerquellen: falsche Runtime, GPU-Passthrough, Restart-Policy

  • Debugging kann aufwändiger sein (Host vs Container)

  • Laut Grok und chatcpt etwas langsamer (chatcpt gibt 5% Performanceverlust an)

Praxisbeispiel:

GPU war da, wurde aber im Container nicht genutzt → Runtime-Problem.

Ich habe mich aber am Ende dennoch für eine Dockerlösung entschieden, da es für mich einfacher war, die verschiedenen Einstellungen in verschiedenen Docker zu testen.

7. Installation unter Ubuntu (Mein Betriebssystem)

Ich installierte alle Service mit SSL

7.1 Paketlisten aktualisieren

sudo apt update

7.2 NGINX installieren

sudo apt install nginx -y

7.3 Dienste starten

sudo systemctl start nginx

7.4 Autostart erzwingen

sudo systemctl enable nginx

7.5 Status prüfen

sudo systemctl status nginx

7.6 Firewall konfigurieren

sudo ufw allow 'Nginx Full'

7.7 Grundstruktur nach Installation

/etc/nginx/nginx.conf

/etc/nginx/sites-available/

/etc/nginx/sites-enabled/

/var/log/nginx/

Konzept:

  • sites-available/ → Konfigurationsdateien

  • sites-enabled/ → Symlinks zu aktiven Sites

7.8 Neue Konfiguration erstellen

sudo nano /etc/nginx/sites-available/homecpt

Beispiel:

server {

    listen 80;

    server_name homecpt;

    location / {

        return 200 "NGINX läuft korrekt\n";

    }

}

7.9 Script aktivieren auf Webserver

sudo ln -s /etc/nginx/sites-available/homecpt /etc/nginx/sites-enabled/

7.10 Alles neu laden

sudo systemctl reload nginx

7.11 HTTPS Zertifikat erstellen

sudo openssl req -x509 -nodes -days 365 \

  -newkey rsa:2048 \

  -keyout /etc/ssl/localca/homecpt.key \

  -out /etc/ssl/localca/homecpt.crt

und im Script (siehe Punkt 7.8) ergänzen:

server {

    listen 443 ssl;

    server_name homecpt;

    ssl_certificate     /etc/ssl/localca/homecpt.crt;

    ssl_certificate_key /etc/ssl/localca/homecpt.key;

    location / {

        return 200 "HTTPS funktioniert\n";

    }

}

7.12 Reverse Proxy erstellen

location /rag/ {

    rewrite ^/rag/(.*)$ /$1 break;

    proxy_pass http://127.0.0.1:8080;

    proxy_set_header Host $host;

    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

}

7.12.1 Warum Reverse Proxy?

  • Der Client sieht nur NGINX.
  • Die internen Dienste bleiben verborgen.
  • Angriffsfläche im Guestnetzwerk reduziert

8. Lessons Learned (nach etlichen Systemkonfigurationen)

  • Default-Timeouts sind für LLM ungeeignet.

  • Browser-fetch("/ask") funktioniert hinter Reverse Proxy nicht → Base-Path notwendig.

  • GPU-Idle bedeutet nicht zwingend Fehlfunktion.

  • default_num_ctx=262144 ist Heuristik, nicht realer Request.

  • Warum nicht direkt FastAPI öffentlich, sondern Reverse-Proxy?

    • FastAPI kann TLS und ASGI – aber:

      • Kein optimiertes Reverse Proxy

      • Kein effizientes Static File Handling

      • Weniger robuste Timeout-Steuerung

      • Kein zentrales Zertifikatsmanagement

      • Kein sauberes Multi-Service-Routing

NGINX ist genau dafür gebaut. Weiterempfehlungen auch im NVIDIA Playbook

     
without
https://digitaleserbe.net/wp-content/themes/hazel/
https://digitaleserbe.net/
#c1c1c1
style2
scroll
Laden...
/homepages/44/d18949504/htdocs/clickandbuilds/DigitalesErbeFimberger/
#
on
none
loading
#
Sort Gallery
on
no
off
off
off