Zum Hauptinhalt springen
S-EDV news
← Alle Anleitungen
📘 Anleitung Datenbanken 06.08.2026 · 10 min Lesezeit

Chroma mit Docker installieren: Entwicklerfreundliche Embedding-Datenbank für RAG-Pipelines

Chroma ist mit über 28.000 GitHub-Stars die populärste Embedding-Datenbank für Entwickler – ideal als lokale Komponente in RAG-Pipelines. Diese Anleitung zeigt, wie du ChromaDB als Docker-Container in 15 Minuten startest, absicherst und mit Python oder LangChain verbindest.

Illustration zur Installation von Chroma mit Docker. Die Grafik zeigt eine moderne Embedding Datenbank für RAG Pipelines mit Docker Container, Vektordatenbank, Dokumenten, Embeddings, Terminal und Dashboard in einer professionellen IT Umgebung. Ideal als KI-generiert

Wer eigene KI-Anwendungen mit Retrieval-Augmented Generation (RAG) bauen möchte, braucht früher oder später eine Vektordatenbank – eine Datenbank, die Texte nicht als Zeichenketten, sondern als numerische Vektoren (Embeddings) speichert und semantische Ähnlichkeitssuche ermöglicht. Chroma (ChromaDB) ist dabei die meistgenutzte Wahl unter Entwicklern: über 28.000 GitHub-Stars, aktive Community, Release-Takt alle zwei bis drei Wochen und native Integration in LangChain, LlamaIndex, OpenAI und Ollama. Als Docker-Container ist Chroma in unter 15 Minuten betriebsbereit – ohne externe Datenbank, ohne komplexe Infrastruktur. Diese Anleitung richtet sich an Entwickler und KMU-Admins, die eine lokale oder server-seitige Vektordatenbank als Grundlage ihrer RAG-Pipeline benötigen.

Voraussetzungen

  1. Docker Engine >= 20.10 und Docker Compose Plugin v2 (Befehl: docker compose ohne Bindestrich) auf einem Linux-Host, einer VM oder einem NAS mit Docker-Unterstützung. Wer Docker noch nicht installiert hat, findet eine vollständige Einrichtungsanleitung unter Docker und Docker Compose auf Linux installieren.
  2. Mindestens 2 GB freier RAM (offizielle Anforderung laut Chroma-Dokumentation); für Entwicklungszwecke reichen 4 GB für die gesamte RAG-Anwendung.
  3. Ca. 500 MB freier Speicherplatz für das Image (~170 MB auf AMD64) und die Vektordaten.
  4. Internetverbindung für den initialen docker pull.
  5. Ein alphanumerischer ASCII-Token für die API-Authentifizierung (Sonderzeichen wie ! oder @ führen zu Startfehlern).
  6. Optional: curl für API-Tests, Python >= 3.8 mit pip für Client-Tests.

Schritt 1: Projektordner und Verzeichnisstruktur anlegen

Lege einen dedizierten Projektordner für Chroma an. Alle Dateien – compose.yaml und .env – liegen darin. Docker verwaltet das Datenpersistenz-Volume als benanntes Volume, sodass kein manueller Bind-Mount-Ordner notwendig ist.

mkdir -p /opt/chromadb
cd /opt/chromadb

Wer keinen Root-Zugriff hat oder die Anwendung im Home-Verzeichnis betreiben möchte, verwendet alternativ ~/chromadb.

Verifizieren: ls -la /opt/chromadb zeigt den leeren Ordner. Der aktuelle Benutzer muss Schreibrechte haben – andernfalls sudo chown $USER:$USER /opt/chromadb ausführen.

Schritt 2: .env-Datei mit sicherem Token anlegen

Geheimnisse wie der API-Token gehören nicht direkt in die compose.yaml, sondern in eine .env-Datei. Docker Compose liest diese automatisch ein. Generiere einen sicheren alphanumerischen Token – ausschließlich Buchstaben und Ziffern, keine Sonderzeichen:

# Token generieren (nur Hex-Zeichen = sicher und kompatibel):
openssl rand -hex 32

Die Ausgabe sieht etwa so aus: a3f8c2e1d4b7094f... (64 Zeichen). Diesen Wert trägst du in die .env ein:

# /opt/chromadb/.env
# Alphanumerischer Token fuer die Chroma-API-Authentifizierung
CHROMA_TOKEN=a3f8c2e1d4b7094fdeadbeefc0ffee1234567890abcdef1234567890abcdef12

Schütze die Datei vor unberechtigtem Lesezugriff:

chmod 600 /opt/chromadb/.env

Verifizieren: cat /opt/chromadb/.env zeigt den Token. ls -la /opt/chromadb/.env sollte -rw------- als Berechtigungen anzeigen.

Schritt 3: compose.yaml erstellen

Erstelle die compose.yaml im Projektordner. Die Konfiguration aktiviert Datenpersistenz, Token-Authentifizierung und einen Healthcheck – alle drei Punkte sind für einen stabilen Betrieb wichtig.

Die wichtigsten Eckdaten auf einen Blick:

ParameterWertHinweis
Imagechromadb/chroma:1.5.9Stabile Version (Stand Juni 2026); für Produktion immer fixen Tag verwenden
Port8000:8000Einziger benötigter Port; REST-API v2
Volumechroma_data:/chroma/chromaMuss exakt mit PERSIST_DIRECTORY übereinstimmen
IS_PERSISTENTTRUEPflicht – ohne diese Variable läuft Chroma im RAM-Modus
PERSIST_DIRECTORY/chroma/chromaInterner Container-Pfad; muss zum Volume-Mount passen
ANONYMIZED_TELEMETRYFALSEDeaktiviert Nutzungsstatistiken an Chroma-Entwickler
AuthentifizierungBearer-TokenVia Authorization-Header; nur alphanumerische Tokens
RAM-Bedarfmin. 2 GBOffizielle Anforderung laut Chroma-Dokumentation
services:
  chromadb:
    image: chromadb/chroma:1.5.9
    container_name: chromadb
    restart: unless-stopped
    ports:
      - "8000:8000"
    volumes:
      - chroma_data:/chroma/chroma
    environment:
      - IS_PERSISTENT=TRUE
      - PERSIST_DIRECTORY=/chroma/chroma
      - ANONYMIZED_TELEMETRY=FALSE
      - CHROMA_SERVER_AUTHN_PROVIDER=chromadb.auth.token_authn.TokenAuthenticationServerProvider
      - CHROMA_SERVER_AUTHN_CREDENTIALS=${CHROMA_TOKEN}
      - CHROMA_AUTH_TOKEN_TRANSPORT_HEADER=Authorization
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8000/api/v2/heartbeat"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 10s

volumes:
  chroma_data:
    driver: local

Wichtig: Der Volume-Mount-Pfad /chroma/chroma und die Umgebungsvariable PERSIST_DIRECTORY=/chroma/chroma müssen exakt übereinstimmen. Weichen beide voneinander ab, schreibt Chroma in ein anderes Verzeichnis als das gemountete – Daten gehen beim nächsten Neustart verloren. Das ist einer der häufigsten Fallstricke.

Verifizieren: cat /opt/chromadb/compose.yaml zeigt die vollständige Konfiguration. Prüfe insbesondere, dass ${CHROMA_TOKEN} als Platzhalter erhalten bleibt – der Wert wird erst zur Laufzeit aus der .env aufgelöst.

Schritt 4: Container starten

Starte Chroma im Hintergrund:

cd /opt/chromadb
docker compose up -d

Docker lädt das Image herunter (~170 MB auf AMD64, ~160 MB auf ARM64 für Apple Silicon oder ARM-Server) und startet den Container. Das Image unterstützt beide Architekturen, sodass der gleiche Befehl auf AMD64-Servern wie auf Apple-Silicon-Macs funktioniert.

Prüfe den Status sofort nach dem Start:

docker compose ps

Erwartete Ausgabe (nach dem start_period von 10 Sekunden):

NAME        IMAGE                    COMMAND   SERVICE    STATUS              PORTS
chromadb    chromadb/chroma:1.5.9    ...       chromadb   Up 30 seconds (healthy)   0.0.0.0:8000->8000/tcp

Zeige die Startlogs, um Konfigurationsfehler auszuschließen:

docker compose logs chromadb

Korrekte Ausgabe enthält Zeilen wie Application startup complete und Uvicorn running on http://0.0.0.0:8000. Fehlermeldungen zu Permission denied, Invalid token oder Address already in use sind sofort erkennbar.

Verifizieren: docker compose ps zeigt Status Up ... (healthy). Wenn der Status nach 60 Sekunden noch starting lautet, prüfe docker compose logs chromadb auf Fehlermeldungen.

Schritt 5: API-Endpunkte testen

Chroma stellt eine REST-API auf Version v2 bereit. Teste zunächst den öffentlich erreichbaren Heartbeat-Endpunkt, danach die durch Token gesicherten Endpunkte.

Heartbeat ohne Authentifizierung (zeigt, ob der Server antwortet):

curl http://localhost:8000/api/v2/heartbeat

Erwartete Antwort:

{"nanosecond heartbeat": 1749600000000000000}

Version abfragen (ebenfalls ohne Auth):

curl http://localhost:8000/api/v2/version

Erwartete Antwort: "1.5.9"

Collections auflisten (erfordert Token):

curl -H "Authorization: Bearer DEIN_TOKEN_AUS_ENV" \
  http://localhost:8000/api/v2/collections

Bei korrektem Token: [] (leeres JSON-Array, da noch keine Collections angelegt wurden). Bei fehlendem oder falschem Token antwortet der Server mit HTTP 401.

Teste auch im Browser: http://localhost:8000/api/v2/heartbeat gibt den Zeitstempel zurück.

Verifizieren: Der Heartbeat liefert einen JSON-Zeitstempel. Der Collections-Endpunkt liefert mit korrektem Token [] und ohne Token HTTP 401. Beide Reaktionen bestätigen, dass Authentifizierung und Persistenz korrekt konfiguriert sind.

Schritt 6: Python-Client verbinden und erste Collection anlegen

Installiere den offiziellen Python-Client:

pip install chromadb

Verbinde dich mit dem laufenden Container und lege eine erste Collection an:

python3 - <<'EOF'
import chromadb

# Verbindung zum Docker-Container mit Token-Authentifizierung
client = chromadb.HttpClient(
    host="localhost",
    port=8000,
    headers={"Authorization": "Bearer DEIN_TOKEN_AUS_ENV"}
)

# Herzschlag prüfen
print("Heartbeat:", client.heartbeat())

# Collection anlegen
collection = client.get_or_create_collection(name="test_collection")
print("Collection erstellt:", collection.name)

# Dokumente hinzufügen (Chroma generiert automatisch Embeddings via sentence-transformers)
collection.add(
    documents=["Chroma ist eine Embedding-Datenbank", "Docker vereinfacht Deployments"],
    ids=["doc1", "doc2"]
)

# Semantische Suche
results = collection.query(
    query_texts=["Vektordatenbank fuer KI"],
    n_results=2
)
print("Suchergebnis:", results["documents"])
EOF

Ein wichtiger Hinweis zur automatischen Embedding-Generierung: Wenn keine embedding_function angegeben wird, lädt Chroma beim ersten Aufruf automatisch das Modell all-MiniLM-L6-v2 via sentence-transformers herunter (~90 MB). Das kann einmalig länger dauern. Für eigene Embedding-Modelle (OpenAI, Ollama, HuggingFace) wird die embedding_function beim Collection-Aufruf explizit übergeben.

LangChain-Integration ist ebenfalls direkt möglich:

pip install langchain-chroma
python3 - <<'EOF'
from langchain_chroma import Chroma
from langchain_core.documents import Document

vectorstore = Chroma(
    collection_name="langchain_demo",
    persist_directory=None,  # Remote-Modus via HTTP
    client_settings={
        "chroma_server_host": "localhost",
        "chroma_server_http_port": 8000,
        "chroma_client_auth_provider": "chromadb.auth.token_authn.TokenAuthClientProvider",
        "chroma_client_auth_credentials": "DEIN_TOKEN_AUS_ENV"
    }
)
EOF

Verifizieren: Das Python-Skript gibt Heartbeat: ... und Collection erstellt: test_collection aus. Nach dem Skript bestätigt curl -H "Authorization: Bearer TOKEN" http://localhost:8000/api/v2/collections die neu angelegte Collection im JSON-Response.

Schritt 7: Datenpersistenz und Backup

Chroma speichert alle Embeddings, Metadaten und die interne SQLite-Datenbank im Docker-Volume chroma_data. Prüfe, ob Daten tatsächlich persistiert werden:

# Container stoppen und neu starten
docker compose down
docker compose up -d

# Collections nach Neustart prüfen - test_collection muss noch vorhanden sein
curl -H "Authorization: Bearer DEIN_TOKEN" \
  http://localhost:8000/api/v2/collections

Backup des Volumes:

# Container vorher stoppen, um konsistentes Backup zu gewährleisten
docker compose stop

# Volume-Inhalt als tar.gz sichern
docker run --rm \
  -v chroma_data:/data \
  -v $(pwd):/backup \
  alpine tar czf /backup/chroma-backup-$(date +%Y%m%d).tar.gz /data

# Container wieder starten
docker compose start

Restore aus Backup:

docker compose down
docker volume rm chromadb_chroma_data
docker volume create chromadb_chroma_data
docker run --rm \
  -v chromadb_chroma_data:/data \
  -v $(pwd):/backup \
  alpine tar xzf /backup/chroma-backup-20260611.tar.gz -C /
docker compose up -d

Weitere Strategien für automatisierte Backups erklärt die Anleitung 3-2-1-Backup-Strategie umsetzen mit Restic.

Verifizieren: Nach docker compose down && docker compose up -d sind alle zuvor angelegten Collections noch vorhanden (curl ... /api/v2/collections gibt sie zurück). Das belegt, dass IS_PERSISTENT=TRUE und das Volume korrekt zusammenwirken.

Schritt 8: Updates einspielen

Chroma wird aktiv weiterentwickelt – Releases erscheinen etwa alle zwei bis drei Wochen. Für ein Update passe den Image-Tag in der compose.yaml an (z.B. von 1.5.9 auf 1.6.0) und führe aus:

cd /opt/chromadb
docker compose pull
docker compose up -d

Für Produktionsumgebungen empfiehlt es sich, den Image-Tag immer explizit zu pinnen und vor dem Update ein Backup anzulegen. Das verhindert unbeabsichtigte Upgrades und gibt die Möglichkeit, bei Breaking Changes auf die vorherige Version zurückzugehen.

Einen automatisierten Weg, neue Container-Versionen zu erkennen, bietet die Anleitung Docker-Container automatisch aktualisieren: Diun, WUD und Renovate im Vergleich.

Verifizieren: docker compose ps zeigt nach dem Update den neuen Image-Tag. curl http://localhost:8000/api/v2/version gibt die neue Versionsnummer zurück.

Troubleshooting / Typische Fehler

  1. Daten nach Neustart weg: IS_PERSISTENT=TRUE fehlt oder kein Volume gemountet. Chroma läuft im In-Memory-Modus. Lösung: Beide Werte in compose.yaml setzen, Container neu starten.
  2. Pfad-Inkonsistenz: Daten werden nicht persistiertPERSIST_DIRECTORY und der Volume-Mount-Pfad stimmen nicht überein. Chroma schreibt in ein Verzeichnis, das nicht gemountet ist. Lösung: Beide Pfade auf exakt /chroma/chroma setzen.
  3. Permission denied in den Logs: Der Container-User kann nicht in das Volume-Verzeichnis schreiben. Lösung: Benanntes Docker-Volume statt Bind-Mount verwenden (wie in dieser Anleitung gezeigt). Bei Bind-Mounts: sudo chown -R 1000:1000 ./chroma-data.
  4. HTTP 401 bei allen API-Aufrufen: Token in der .env stimmt nicht mit dem im Authorization-Header überein, oder der Token enthält Sonderzeichen. Lösung: Token aus der .env kopieren (nicht abtippen), nur alphanumerische Zeichen verwenden.
  5. Container startet nicht / Status bleibt starting: Port 8000 ist auf dem Host bereits belegt. Prüfen mit ss -tlnp | grep 8000. Lösung: Entweder den Konflikt-Prozess beenden oder den Host-Port in der compose.yaml auf z.B. 8001:8000 ändern.
  6. config.yaml bricht Persistenz: Ein bekannter Bug (GitHub Issue #4330) – sobald eine config.yaml in den Container gemountet wird, ignoriert Chroma den konfigurierten Pfad. Lösung: Keine config.yaml verwenden und PERSIST_DIRECTORY ausschließlich über Umgebungsvariablen setzen.
  7. Heartbeat gibt 404 zurück: Ältere Skripte oder Monitoring-Tools verwenden noch /api/v1/heartbeat. Ab Chroma 1.x ist /api/v2/heartbeat der korrekte Endpunkt.
  8. Erster Python-Aufruf dauert sehr lange: Chroma lädt beim ersten Aufruf ohne explizite embedding_function automatisch das Modell all-MiniLM-L6-v2 herunter. Das ist einmalig – danach ist das Modell gecacht.

Häufige Fragen

Braucht Chroma eine externe Datenbank wie PostgreSQL oder Redis?

Nein. Chroma ist vollständig eigenständig und nutzt intern SQLite für Metadaten sowie eigene Dateiformate für Vektoren. Ein einzelner Container genügt für Entwicklung und kleine bis mittlere Produktionsszenarien. Externe Datenbanken sind nicht notwendig und werden von Chroma nicht unterstützt.

Welche Embedding-Modelle kann ich mit Chroma verwenden?

Chroma ist modell-agnostisch. Unterstützt werden OpenAI Embeddings, Cohere, HuggingFace/sentence-transformers, Ollama und eigene Embedding-Funktionen. Wichtig: Das Modell muss konsistent zwischen dem Einfügen (add) und dem Abfragen (query) sein. Wer lokal bleiben möchte, findet in der Anleitung Ollama und Open WebUI mit Docker: eigenes lokales KI-Sprachmodell die passende Embedding-Quelle.

Kann ich Chroma in LangChain oder LlamaIndex einbinden?

Ja. LangChain: pip install langchain-chroma, dann Chroma als VectorStore nutzen. LlamaIndex hat ebenfalls eine native Chroma-Integration. Beide Frameworks arbeiten direkt gegen den Docker-Container über dessen HTTP-API.

Wie prüfe ich, ob der Container korrekt läuft?

docker compose ps zeigt den Gesamtstatus. Danach: curl http://localhost:8000/api/v2/heartbeat gibt einen JSON-Zeitstempel zurück, wenn der Server erreichbar ist. Im Browser zeigt http://localhost:8000/api/v2/collections alle vorhandenen Collections als JSON-Array.

Wie sichere ich meine Chroma-Daten?

Zuerst den Container stoppen (docker compose stop), dann den Volume-Inhalt per tar sichern (siehe Schritt 7). Für ein automatisiertes Backup-Konzept eignet sich Restic Backup auf Linux und Windows einrichten und automatisieren.

Ist Chroma von außen erreichbar?

Standardmäßig bindet Chroma auf 0.0.0.0:8000 – der Port ist also auch von anderen Hosts im Netzwerk erreichbar. Ohne Authentifizierung wäre die Datenbank komplett offen. Mit aktivierter Token-Auth (wie in dieser Anleitung) ist jeder API-Aufruf ohne gültigen Bearer-Token mit HTTP 401 abgewiesen. Für den Internetzugriff immer zusätzlich einen Reverse Proxy mit TLS vorschalten.

Was passiert, wenn ich ALLOW_RESET=TRUE setze?

Mit dieser Einstellung kann die gesamte Datenbank per API-Aufruf geleert werden – auch wenn Auth aktiv ist (ein angemeldeter Client kann alles löschen). Diese Option ist ausschließlich für lokale Entwicklung und Tests gedacht. In Produktionsumgebungen darf ALLOW_RESET=TRUE niemals gesetzt sein.

Fazit

Chroma ist der schnellste Einstieg in die Welt der Vektordatenbanken für Entwickler: ein einziger Container, keine externe Datenbank, REST-API v2 und native Unterstützung für alle gängigen LLM-Frameworks. Die Kombination aus IS_PERSISTENT=TRUE, einem korrekt gemounteten Volume und Token-Authentifizierung macht den Container produktionstauglich – zumindest für kleine bis mittlere Workloads. Für hochverfügbare oder sehr große RAG-Pipelines empfiehlt sich ein Blick auf Alternativen wie Qdrant, das ebenfalls als Docker-Container betreibbar ist und neben REST auch gRPC sowie erweiterte Filtermöglichkeiten bietet. Wer jedoch schnell produktiv werden möchte und LangChain oder LlamaIndex einsetzt, ist mit Chroma optimal bedient.

Weiterführende Anleitungen und Quellen

  1. Lokales RAG-System mit Qdrant und Embeddings selbst bauen – Chroma-Alternative mit erweiterter Filterlogik und gRPC
  2. Ollama und Open WebUI mit Docker: eigenes lokales KI-Sprachmodell – lokale Embedding-Quelle für Chroma
  3. RAG produktiv betreiben: Chunking, Hybrid-Search, Reranking – nächste Stufe nach dem Chroma-Setup
  4. Docker und Docker Compose auf Linux installieren – Grundlage für alle Docker-Anleitungen

Offizielle Quellen: Chroma Docs – Docker Deployment | Docker Hub – chromadb/chroma | GitHub Releases – chroma-core/chroma