# mediaeng/llmproxy Ein schlanker Reverse-Proxy für [Ollama](https://ollama.com), der API-Keys mit konfigurierbaren Token- und Request-Quoten verwaltet. Eingehende Anfragen im OpenAI-kompatiblen Format werden authentifiziert, auf Quota geprüft und an den konfigurierten Ollama-Server weitergeleitet. Ollama muss dabei nicht auf demselben Host laufen — `OLLAMA_URL` kann auf jeden erreichbaren Server zeigen, also auf den Docker-Host selbst, einen anderen Rechner im Netzwerk oder einen Remote-Server. ## Funktionen - OpenAI-kompatibler Endpunkt (`/v1/chat/completions`, `/v1/models`) - API-Key-Verwaltung mit tages- und monatlichen Token-/Request-Limits - Web-basierte Admin-Oberfläche (Port 8001) - Streaming-Support (Server-Sent Events) - Tool-Use / Function Calling wird durchgereicht - Rotierende Nutzungs-Logs - SQLite (Standard) oder PostgreSQL ## Ports | Port | Dienst | |------|--------| | `8000` | Proxy-Endpunkt (OpenAI-API) | | `8001` | Admin-API + Web-Oberfläche | Port 8001 muss exposed werden, da der Container die Admin-Oberfläche selbst auf diesem Port ausliefert. Alle API-Endpunkte erfordern das `ADMIN_PASSWORD` — ein Zugriff ohne gültiges Token liefert nur die öffentlichen Frontend-Dateien (HTML/JS/CSS der Login-Seite). Das Passwort ist damit die primäre Schutzmaßnahme. Zusätzliche Härtung: Portbindung auf `127.0.0.1` beschränkt den Zugriff auf den lokalen Host und verhindert direkten Netzwerkzugriff: ``` ports: - "127.0.0.1:8001:8001" # nur lokal erreichbar # oder: - "8001:8001" # netzwerkweit, Schutz nur durch ADMIN_PASSWORD ``` ## Umgebungsvariablen | Variable | Standard | Beschreibung | |----------|----------|--------------| | `ADMIN_PASSWORD` | – | **Pflicht.** Passwort für die Admin-Oberfläche | | `OLLAMA_URL` | `http://localhost:11434` | URL des Ollama-Servers (ohne `/v1`-Suffix) | | `DEFAULT_MODEL` | `llama3` | Modell, das verwendet wird wenn der Client keines angibt | | `DATABASE_URL` | `sqlite:///./test.db` | Datenbank-Verbindungsstring (SQLite oder PostgreSQL) | | `PROXY_HOST` | `0.0.0.0` | Bind-Adresse des Proxy | | `PROXY_PORT` | `8000` | Port des Proxy | | `ADMIN_PORT` | `8001` | Port der Admin-API | | `APP_TZ` | `Europe/Berlin` | Zeitzone für Tages-/Monats-Reset der Quoten | | `LOG_FILE` | `logs/usage.log` | Pfad der rotierenden Nutzungs-Logdatei | ## Docker Compose – Ollama extern, SQLite Wenn Ollama außerhalb von Docker läuft — auf dem Docker-Host oder einem anderen erreichbaren Server. `OLLAMA_URL` entsprechend anpassen. ```yaml services: llmproxy: image: mediaeng/llmproxy:latest restart: unless-stopped ports: - "8000:8000" - "127.0.0.1:8001:8001" environment: ADMIN_PASSWORD: changeme OLLAMA_URL: http://host.docker.internal:11434 # oder http://:11434 DEFAULT_MODEL: llama3 APP_TZ: Europe/Berlin volumes: - llmproxy-data:/app/backend # Auf Linux extra_hosts ergänzen, da host.docker.internal dort # nicht automatisch verfügbar ist: # extra_hosts: # - "host.docker.internal:host-gateway" volumes: llmproxy-data: ``` ## Docker Compose – Ollama extern, PostgreSQL ```yaml services: llmproxy: image: mediaeng/llmproxy:latest restart: unless-stopped ports: - "8000:8000" - "127.0.0.1:8001:8001" environment: ADMIN_PASSWORD: changeme OLLAMA_URL: http://host.docker.internal:11434 # oder http://:11434 DEFAULT_MODEL: llama3 APP_TZ: Europe/Berlin DATABASE_URL: postgresql://llmproxy:secret@db:5432/llmproxy volumes: - llmproxy-data:/app/backend depends_on: db: condition: service_healthy # extra_hosts: # - "host.docker.internal:host-gateway" db: image: postgres:16-alpine restart: unless-stopped environment: POSTGRES_DB: llmproxy POSTGRES_USER: llmproxy POSTGRES_PASSWORD: secret volumes: - pg-data:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U llmproxy"] interval: 5s timeout: 5s retries: 5 volumes: pg-data: ``` ## Docker Compose – Ollama als Container, SQLite Ollama und llmproxy laufen gemeinsam in Docker, Daten in einem Volume. ```yaml services: llmproxy: image: mediaeng/llmproxy:latest restart: unless-stopped ports: - "8000:8000" - "127.0.0.1:8001:8001" environment: ADMIN_PASSWORD: changeme OLLAMA_URL: http://ollama:11434 DEFAULT_MODEL: llama3 APP_TZ: Europe/Berlin volumes: - llmproxy-data:/app/backend depends_on: - ollama ollama: image: ollama/ollama:latest restart: unless-stopped volumes: - ollama-data:/root/.ollama volumes: llmproxy-data: ollama-data: ``` ## Docker Compose – Ollama als Container, PostgreSQL Für Produktionsumgebungen mit externer Datenbank. ```yaml services: llmproxy: image: mediaeng/llmproxy:latest restart: unless-stopped ports: - "8000:8000" - "127.0.0.1:8001:8001" environment: ADMIN_PASSWORD: changeme OLLAMA_URL: http://ollama:11434 DEFAULT_MODEL: llama3 APP_TZ: Europe/Berlin DATABASE_URL: postgresql://llmproxy:secret@db:5432/llmproxy depends_on: db: condition: service_healthy ollama: condition: service_started db: image: postgres:16-alpine restart: unless-stopped environment: POSTGRES_DB: llmproxy POSTGRES_USER: llmproxy POSTGRES_PASSWORD: secret volumes: - pg-data:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U llmproxy"] interval: 5s timeout: 5s retries: 5 ollama: image: ollama/ollama:latest restart: unless-stopped volumes: - ollama-data:/root/.ollama volumes: pg-data: ollama-data: ``` ## Schnellstart ```bash docker run -d \ -p 8000:8000 \ -e ADMIN_PASSWORD=changeme \ -e OLLAMA_URL=http://host.docker.internal:11434 \ -v llmproxy-data:/app/backend \ mediaeng/llmproxy:latest ``` ## Client-Konfiguration Den Proxy als OpenAI-kompatibler Endpunkt konfigurieren: ``` Base URL: http://:8000/v1 API Key: ```