2026-04-29 17:13:14 +02:00
2026-04-27 18:54:27 +02:00
2026-04-27 18:54:27 +02:00

Ollama Proxy mit API-Keys und Quotas

Ein Reverse-Proxy für Ollama mit API-Key-Authentifizierung, Quota-Management und Web-Admin-Oberfläche.

Features

  • API-Key-Authentifizierung (Bearer Token oder sk--Prefix)
  • Optionales Ablaufdatum pro API-Key
  • Quota-Management mit getrennten Tages- und Monatslimits (Tokens & Requests)
  • Token-Zählung via tiktoken, Reset-Grenzen in der Zeitzone Europe/Berlin
  • Web-Admin-Oberfläche (API-Keys verwalten, Ollama-Einstellungen, Verbrauchsanzeige)
  • OpenAI-kompatibler /v1/chat/completions-Endpunkt mit Streaming und Tool-Use
  • Rotierende Nutzungs-Logs
  • SQLite (Standard) oder PostgreSQL
  • Docker-Image auf DockerHub: mediaeng/llmproxy

Sicherheit

  • Admin-Oberfläche passwortgeschützt (ADMIN_PASSWORD) — alle API-Endpunkte erfordern den Token
  • API-Keys als SHA-256-Hash in der DB — Plaintext nur einmalig bei Erstellung
  • Quota-Check atomar mit SELECT FOR UPDATE (kein TOCTOU-Race)
  • Port 8001 kann optional auf 127.0.0.1 gebunden werden (zusätzliche Härtung)

Konfiguration

.env-Datei im Projektverzeichnis anlegen:

ADMIN_PASSWORD=change-me
PROXY_HOST=0.0.0.0
PROXY_PORT=8000
ADMIN_PORT=8001
DATABASE_URL=sqlite:///./test.db
OLLAMA_URL=http://localhost:11434
DEFAULT_MODEL=llama3
APP_TZ=Europe/Berlin
LOG_FILE=logs/usage.log
Variable Standard Beschreibung
ADMIN_PASSWORD Passwort für die Admin-Oberfläche (Pflicht)
PROXY_HOST 0.0.0.0 Bind-Adresse des Proxys
PROXY_PORT 8000 Port des Proxys
ADMIN_PORT 8001 Port der Admin-API
DATABASE_URL sqlite:///./test.db DB-Verbindungsstring (SQLite oder PostgreSQL)
OLLAMA_URL http://localhost:11434 Adresse der Ollama-Instanz (auch in der UI änderbar)
DEFAULT_MODEL llama3 Standard-Modell für /v1/chat/completions (auch in der UI änderbar)
APP_TZ Europe/Berlin Zeitzone für tägliche/monatliche Quota-Resets
LOG_FILE logs/usage.log Pfad der rotierenden Nutzungs-Logdatei
ALLOWED_ORIGINS http://localhost:5173 CORS-Origins (nur für Entwicklung relevant)

Entwicklung (lokal)

Voraussetzungen

  • Python 3.12+ mit virtualenv
  • Node.js 18+
python -m venv .venv
source .venv/bin/activate
pip install -r backend/requirements-dev.txt
cd frontend && npm install

Starten

Per Script:

cp .env.example .env   # ADMIN_PASSWORD setzen
./start.sh

Per PyCharm: Run-Config „Dev" starten (startet Proxy, Admin-API und Vite-Dev-Server gemeinsam).

Das Script prüft alle Ports auf Belegung, initialisiert die Datenbank und startet alle drei Dienste.

Admin-Oberfläche: http://localhost:5173

Produktion (Docker)

Docker Compose (empfohlen)

docker compose up -d

Zieht das Image von DockerHub, lädt Variablen aus .env und verwendet die lokale SQLite-Datenbank. Weitere Compose-Varianten (PostgreSQL, Ollama als Container) siehe DOCKERHUB.md.

Image selbst bauen und pushen

./build_push.sh

Das Script zeigt den aktuellen Git-Tag, bietet an einen neuen zu setzen, baut das Image für linux/arm64 und pusht zu mediaeng/llmproxy.

Port 8001 (Admin)

Port 8001 muss exposed werden, da der Container die Admin-Oberfläche auf diesem Port ausliefert. Alle API-Endpunkte erfordern das ADMIN_PASSWORD — der Token ist der primäre Schutz. Optionale zusätzliche Härtung: Bindung auf 127.0.0.1:

ports:
  - "127.0.0.1:8001:8001"   # nur lokal
  # oder:
  - "8001:8001"              # netzwerkweit, Schutz durch ADMIN_PASSWORD

Proxy-Endpunkte (Port 8000)

Alle Endpunkte erfordern einen gültigen API-Key im Authorization-Header.

curl -X POST http://localhost:8000/v1/chat/completions \
  -H "Authorization: Bearer sk-xxxxxx" \
  -H "Content-Type: application/json" \
  -d '{"model":"llama3","messages":[{"role":"user","content":"Hallo"}]}'
Endpunkt Methode Beschreibung
/v1/chat/completions POST Chat (OpenAI-Format, Streaming + Tool-Use)
/v1/models GET Modelle (OpenAI-Format)
/api/generate POST Ollama generate (nativ)
/api/chat POST Ollama chat (nativ)
/api/tags GET Verfügbare Modelle
/api/versions GET Ollama-Version

Admin-API (Port 8001)

Alle Endpunkte erfordern Authorization: Bearer <ADMIN_PASSWORD>.

Endpunkt Methode Beschreibung
/api/api-keys GET Alle API-Keys mit Verbrauchsdaten
/api/api-keys POST Neuen API-Key erstellen
/api/api-keys/{id}/quota PATCH Limits eines Keys aktualisieren
/api/api-keys/{id}/activate PUT API-Key aktivieren
/api/api-keys/{id}/deactivate PUT API-Key deaktivieren
/api/api-keys/{id} DELETE API-Key löschen
/api/settings GET/PUT Ollama-URL und Standard-Modell
/api/ollama-models GET Verfügbare Modelle von Ollama
/api/proxy-info GET Lokaler Proxy-Endpunkt

Tests

cd backend
python -m pytest tests/ -v

Projektstruktur

llm_quota/
├── backend/
│   ├── main.py              # Proxy-Server (Port 8000)
│   ├── admin.py             # Admin-API + Static-File-Serving (Port 8001)
│   ├── database.py          # DB-Verbindung & Session
│   ├── models.py            # SQLAlchemy-Modelle (APIKey, Setting, Usage)
│   ├── schemas.py           # Pydantic-Schemas
│   ├── crud.py              # DB-Operationen, Token-Zählung, Quota-Logik
│   ├── init_db.py           # Tabellen anlegen & Settings seeden
│   ├── requirements.txt     # Produktiv-Dependencies
│   ├── requirements-dev.txt # Test-Dependencies
│   └── tests/
│       ├── conftest.py
│       ├── test_auth.py
│       └── test_quota.py
├── frontend/
│   └── src/
│       ├── main.jsx         # React-Admin-UI
│       └── styles.css
├── .idea/runConfigurations/
│   └── Dev.xml              # PyCharm Run-Config
├── Dockerfile
├── docker-compose.yml       # Produktiv-Start mit DockerHub-Image
├── docker-entrypoint.sh
├── .dockerignore
├── start.sh                 # Entwicklungs-Startscript
├── run_dev.py               # Entwicklungs-Runner für PyCharm
├── build_push.sh            # Docker-Build & Push zu DockerHub
├── DOCKERHUB.md             # DockerHub-Beschreibung (deutsch)
├── DOCKERHUB.en.md          # DockerHub-Beschreibung (englisch)
└── .gitignore

Lizenz

MIT

Description
No description provided
Readme 206 KiB
Languages
Python 55.3%
JavaScript 28.4%
CSS 9.8%
Shell 4.9%
Dockerfile 1.1%
Other 0.5%