Zum Hauptinhalt springen
S-EDV news
← Alle Anleitungen
📘 Anleitung Datenbanken 14.08.2026 · 9 min Lesezeit Geprüft 01.10.2026

Milvus mit Docker installieren: Hochskalierbare Open-Source-Vektordatenbank für RAG und Semantic Search

Milvus Standalone 3.0 per Docker Compose installieren: Vektordatenbank für RAG und Semantic Search mit etcd und MinIO, eigenen Zugangsdaten, lokal gebundenen Ports und Verifizieren nach jedem Schritt.

Werbung Mit * markierte Links sind Werbelinks: Bei einem Kauf erhalten wir eine Provision, der Preis bleibt gleich. Als Amazon-Partner verdiene ich an qualifizierten Verkäufen. Mehr dazu

Titelbild: Milvus mit Docker installieren, Vektoren, Suche, RAG

Semantische Suche, RAG-Pipelines (Retrieval-Augmented Generation) und Empfehlungssysteme brauchen im Produktivbetrieb eine Vektordatenbank. Milvus ist eine Apache-2.0-lizenzierte Vektordatenbank für die Ähnlichkeitssuche in sehr großen Mengen hochdimensionaler Vektoren (Embeddings). Diese Anleitung zeigt, wie Sie Milvus Standalone 3.0 per Docker Compose auf einem Linux-Host oder einer VM aufsetzen und betreiben.

Voraussetzungen

  • Docker Engine 20.10+ und Docker Compose V2 (Plugin, Befehl docker compose) installiert: nicht das veraltete docker-compose (V1). Noch nicht installiert? Siehe Docker und Docker Compose auf Linux installieren.
  • Mindestens 2 CPU-Kerne, x86-64 mit SSE4.2 und AVX/AVX2 (prüfen mit grep -o -m1 -w avx2 /proc/cpuinfo) oder ARM64; das Image v3.0.2 gibt es für beide Architekturen.
  • Mindestens 8 GB RAM (16 GB empfohlen); unter Last crashen etcd oder Milvus mit OOM-Kills, wenn zu wenig Arbeitsspeicher verfügbar ist.
  • SSD-Storage mit mindestens 500 IOPS und unter 10 ms fsync-Latenz: etcd ist latenzempfindlich; auf HDDs oder langsamen NFS-Shares bricht der Dienst ab.
  • Mindestens 20 GB freier Speicherplatz für die Images (Milvus rund 0,6 GB komprimiert, dazu etcd und MinIO) und die Daten-Volumes.
  • Optional: curl für Health-Check-Verifikation und python3 + pip für einen pymilvus-Verbindungstest.

Schritt 1: Projektordner und Verzeichnisstruktur anlegen

Legen Sie einen eigenen Ordner für das Milvus-Projekt an; er enthält Konfiguration und persistente Daten und vereinfacht Updates und Backups.

$ mkdir -p /opt/milvus
$ cd /opt/milvus

Milvus legt seine Daten später automatisch unter ./volumes/ ab (gesteuert über die Variable DOCKER_VOLUME_DIRECTORY). Die drei Unterordner legt Docker beim ersten Start an; Sie können sie auch vorab erstellen. Die Rechte am Milvus-Ordner setzt der Init-Container aus Schritt 3, weil Milvus 3.0 nicht mehr als root läuft:

$ mkdir -p /opt/milvus/volumes/etcd
$ mkdir -p /opt/milvus/volumes/minio
$ mkdir -p /opt/milvus/volumes/milvus

Prüfen Sie die Ordnerstruktur:

$ ls -la /opt/milvus/volumes/
# Erwartete Ausgabe:
# drwxr-xr-x  etcd/
# drwxr-xr-x  minio/
# drwxr-xr-x  milvus/

Schritt 2: .env-Datei mit Secrets anlegen

Die .env-Datei enthält alle Zugangsdaten und anpassbaren Pfade. Die Standard-Zugangsdaten minioadmin/minioadmin sind nur für lokale Tests geeignet; setzen Sie eigene, starke Werte. Tragen Sie außerdem den absoluten Pfad als DOCKER_VOLUME_DIRECTORY ein, damit die Volumes immer am richtigen Ort landen.

# /opt/milvus/.env

# Datenpfad fuer alle drei Volumes (absoluter Pfad empfohlen)
DOCKER_VOLUME_DIRECTORY=/opt/milvus

# MinIO Credentials - in Produktion UNBEDINGT aendern!
MINIO_ACCESS_KEY=IHR_MINIO_BENUTZER
MINIO_SECRET_KEY=IHR_MINIO_PASSWORT

Prüfen Sie, dass die Datei korrekt erstellt wurde:

$ cat /opt/milvus/.env
# Ausgabe: alle Zeilen sauber lesbar, keine BOM-Zeichen,
# kein Leerzeichen vor dem Gleichheitszeichen

Schritt 3: compose.yaml anlegen

Die folgende compose.yaml basiert auf der offiziellen Compose-Datei zum Release v3.0.2. Abweichungen: Zugangsdaten aus der .env, Healthcheck-Abhängigkeiten und Ports nur auf 127.0.0.1, weil Milvus ohne aktivierte Authentifizierung jeden Zugriff erlaubt. Die 2.x-Linie wird parallel gepflegt (aktuell v2.6.25); deren Compose-Datei unterscheidet sich, verwenden Sie dafür die Datei aus dem jeweiligen Release.

# /opt/milvus/compose.yaml
services:
  milvus-volume-init:
    image: milvusdb/milvus:v3.0.2
    user: "0:0"
    network_mode: none
    read_only: true
    restart: "no"
    entrypoint: ["/bin/sh", "-c"]
    command:
      - |
        set -eu
        uid="$$(id -u milvus)"
        gid="$$(id -g milvus)"
        marker="/var/lib/milvus/.milvus-volume-owner-$${uid}-$${gid}"
        if [ ! -e "$${marker}" ]; then
          chown -R "$${uid}:$${gid}" /var/lib/milvus
          touch "$${marker}"
          chown "$${uid}:$${gid}" "$${marker}"
        fi
    volumes:
      - ${DOCKER_VOLUME_DIRECTORY:-.}/volumes/milvus:/var/lib/milvus

  etcd:
    container_name: milvus-etcd
    image: quay.io/coreos/etcd:v3.5.25
    environment:
      - ETCD_AUTO_COMPACTION_MODE=revision
      - ETCD_AUTO_COMPACTION_RETENTION=1000
      - ETCD_QUOTA_BACKEND_BYTES=4294967296
      - ETCD_SNAPSHOT_COUNT=50000
    volumes:
      - ${DOCKER_VOLUME_DIRECTORY:-.}/volumes/etcd:/etcd
    command: >
      etcd
      -advertise-client-urls=http://etcd:2379
      -listen-client-urls http://0.0.0.0:2379
      --data-dir /etcd
    healthcheck:
      test: ["CMD", "etcdctl", "endpoint", "health"]
      interval: 30s
      timeout: 20s
      retries: 3
    restart: unless-stopped

  minio:
    container_name: milvus-minio
    image: milvusdb/minio:RELEASE.2024-12-18T13-15-44Z
    environment:
      MINIO_ACCESS_KEY: ${MINIO_ACCESS_KEY:-minioadmin}
      MINIO_SECRET_KEY: ${MINIO_SECRET_KEY:-minioadmin}
    ports:
      - "127.0.0.1:9000:9000"
      - "127.0.0.1:9001:9001"
    volumes:
      - ${DOCKER_VOLUME_DIRECTORY:-.}/volumes/minio:/minio_data
    command: minio server /minio_data --console-address ":9001"
    healthcheck:
      test: ["CMD", "mc", "ready", "local"]
      interval: 30s
      timeout: 20s
      retries: 3
    restart: unless-stopped

  standalone:
    container_name: milvus-standalone
    image: milvusdb/milvus:v3.0.2
    command: ["milvus", "run", "standalone"]
    security_opt:
      - seccomp:unconfined
    environment:
      ETCD_ENDPOINTS: etcd:2379
      MINIO_ADDRESS: minio:9000
      MINIO_REGION: us-east-1
      MINIO_ACCESS_KEY_ID: ${MINIO_ACCESS_KEY:-minioadmin}
      MINIO_SECRET_ACCESS_KEY: ${MINIO_SECRET_KEY:-minioadmin}
    volumes:
      - ${DOCKER_VOLUME_DIRECTORY:-.}/volumes/milvus:/var/lib/milvus
    ports:
      - "127.0.0.1:19530:19530"
      - "127.0.0.1:9091:9091"
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:9091/healthz"]
      interval: 30s
      start_period: 90s
      timeout: 20s
      retries: 3
    depends_on:
      milvus-volume-init:
        condition: service_completed_successfully
      etcd:
        condition: service_healthy
      minio:
        condition: service_healthy
    restart: unless-stopped

networks:
  default:
    name: milvus

Wichtige Details: Der MinIO-Container liest MINIO_ACCESS_KEY/MINIO_SECRET_KEY, Milvus dagegen MINIO_ACCESS_KEY_ID/MINIO_SECRET_ACCESS_KEY; beide erhalten dieselben Werte aus der .env. Der etcd-Dienst meldet sich unter dem Service-Namen etcd an (nicht localhost), sonst erreicht Milvus ihn nicht. milvus-volume-init läuft einmal als root und übergibt den Datenordner an den Benutzer milvus. Für Zugriffe von anderen Rechnern auf Port 19530 aktivieren Sie zuerst die Authentifizierung (siehe Häufige Fragen) und entfernen dann 127.0.0.1:.

Prüfen Sie die compose.yaml vor dem Start auf Syntaxfehler:

cd /opt/milvus
docker compose config
# Keine Fehlermeldung = Syntax korrekt;
# die geparste Konfiguration wird ausgegeben

Schritt 4: Stack starten

Starten Sie den Stack im Hintergrund. Docker Compose lädt die Images, legt das Netzwerk milvus an und startet Milvus erst, wenn der Init-Container fertig und etcd sowie MinIO healthy sind.

$ cd /opt/milvus
$ docker compose up -d

Der erste Start dauert 3 bis 8 Minuten. Den Fortschritt verfolgen Sie so:

$ docker compose logs -f

Warten Sie, bis die Logs keine Fehlermeldungen mehr zeigen.

Die drei Dienste zeigen Up (healthy); milvus-volume-init ist beendet und erscheint nur mit docker compose ps -a (Exited (0)):

$ docker compose ps
# Erwartete Ausgabe (gekuerzt):
# NAME                IMAGE                    STATUS
# milvus-etcd         quay.io/coreos/etcd:...  Up (healthy)
# milvus-minio        minio/minio:...          Up (healthy)
# milvus-standalone   milvusdb/milvus:...      Up (healthy)

# Zusaetzlicher Health-Check per curl:
$ curl http://localhost:9091/healthz
# Erwartete Ausgabe: OK

Schritt 5: WebUI und MinIO-Konsole aufrufen

Milvus bringt seit v2.5 eine eingebaute WebUI mit, über die Sie Collections, Statistiken und Abfragen einsehen. Die MinIO-Konsole ermöglicht einen Blick auf die intern gespeicherten Segment- und Indexdateien.

DienstURLZugangsdaten
Milvus WebUIhttp://localhost:9091/webui/keine (Auth deaktiviert)
Milvus Healthhttp://localhost:9091/healthz
MinIO Konsolehttp://localhost:9001aus .env (Standard: minioadmin)
Milvus APIhttp://localhost:19530keine (Auth deaktiviert)

Die WebUI und die MinIO-Konsole antworten:

$ curl -I http://localhost:9091/webui/
# Erwartete Ausgabe: HTTP/1.1 200 OK
$ curl -I http://localhost:9001
# Erwartete Ausgabe: HTTP/1.1 200 OK (MinIO-Konsole)

Schritt 6: Verbindungstest mit pymilvus

Der schnellste Praxistest ist eine Python-Verbindung über das offizielle SDK pymilvus. Installieren Sie die zur Serverversion passende SDK-Version in einer virtuellen Umgebung:

$ pip install "pymilvus==3.0.2"

Der folgende Schnelltest verbindet sich auf Port 19530, listet vorhandene Datenbanken auf und gibt die Serverversion aus:

python3 - <<'EOF'
from pymilvus import MilvusClient

client = MilvusClient(uri="http://localhost:19530")
print("Verbunden! Serverversion:", client.get_server_version())
print("Datenbanken:", client.list_databases())
client.close()
EOF

Die Ausgabe sollte in etwa so aussehen:

# Erwartete Ausgabe:
# Verbunden! Serverversion: v3.0.2
# Datenbanken: ['default']

Erscheint stattdessen ein Verbindungsfehler, prüfen Sie zuerst docker compose ps (alle drei Container healthy?) und dann docker compose logs standalone auf Fehlermeldungen.

Eckdaten im Überblick

ParameterWertHinweis
Image (aktuell)milvusdb/milvus:v3.0.22.x-Linie: v2.6.25
Begleit-Imagesquay.io/coreos/etcd:v3.5.25Exakte Tags verwenden
MinIO-Imagemilvusdb/minio:RELEASE.2024-12-18T13-15-44ZExakten Tag beibehalten
API-Port19530gRPC + REST, SDK-Endpunkt
WebUI / Health9091/webui/ und /healthz
MinIO API9000intern genutzt
MinIO Konsole9001Browser-Verwaltung
etcd Ports2379/2380kein Host-Port-Mapping
Min. RAM8 GB (16 GB empfohlen)Pflicht für stabilen Betrieb
CPUx86_64 + SSE4.2/AVX oder ARM64Images für amd64 und arm64
StorageSSD, >500 IOPS, <10ms fsyncHDD für etcd ungeeignet

Troubleshooting / Typische Fehler

„Illegal instruction“ / Container crasht sofort beim Start

Milvus prüft beim Hochfahren auf AVX/SSE4.2. Auf älteren CPUs oder VMs ohne CPU-Feature-Passthrough schlägt das fehl. Lösung: CPU-Flags in der VM-Konfiguration aktivieren (z. B. in Proxmox CPU-Typ auf host oder x86-64-v3 stellen) oder neuere Hardware nutzen.

„rpc error: code = Internal desc = stream terminated by RST_STREAM“

etcd ist falsch advertised. Die -advertise-client-urls im Command muss den Docker-Service-Namen etcd verwenden, nicht localhost oder 127.0.0.1. Prüfen Sie, ob die compose.yaml unverändert ist.

MinIO-Authentifizierungsfehler (403 beim Start)

Milvus nutzt andere Zugangsdaten als MinIO. Milvus liest MINIO_ACCESS_KEY_ID/MINIO_SECRET_ACCESS_KEY, der MinIO-Container MINIO_ACCESS_KEY/MINIO_SECRET_KEY. Stehen im standalone-Dienst die MinIO-Namen, verwendet Milvus stillschweigend minioadmin. Beide Paare müssen dieselben Werte haben.

depends_on / Startreihenfolge funktioniert nicht

Tritt mit dem alten docker-compose (V1) auf. Verwenden Sie Docker Compose V2 (docker compose version).

Volume-Berechtigungsfehler (permission denied unter /var/lib/milvus)

Milvus 3.0 läuft als Benutzer milvus. Prüfen Sie mit docker compose logs milvus-volume-init, ob der Init-Container gelaufen ist. Nach einer Wiederherstellung von Dateien mit anderem Eigentümer die Markierungsdatei volumes/milvus/.milvus-volume-owner-* löschen und neu starten.

Port 9091 bereits belegt

Der Prometheus Pushgateway nutzt ebenfalls 9091. Lösung: Port-Mapping anpassen, z. B. "127.0.0.1:19091:9091".

OOM-Kill nach kurzer Zeit

Der Container stirbt nach wenigen Minuten, weil RAM fehlt. Unter Docker Desktop (macOS/Windows) das Memory-Limit in den Einstellungen auf mindestens 10 GB erhöhen.

etcd bricht mit „took too long to execute“ ab

Der Storage ist zu langsam. etcd benötigt unter 10 ms fsync-Latenz: auf HDD oder langsamen NFS-Shares funktioniert das nicht zuverlässig.

seccomp:unconfined nicht erlaubt

Auf manchen Managed-Plattformen oder gehärteten Systemen ist diese Option verboten. Dann ist ein eigenes seccomp-Profil oder ein anderer Host nötig.

Datenverlust nach docker compose down -v

docker compose down allein entfernt nur Container, nicht die Volumes. Mit dem Flag -v oder manuellem rm -rf volumes/ gehen alle Daten unwiederbringlich verloren: vor jedem Update die volumes/-Verzeichnisse sichern.

Häufige Fragen

Wie verbinde ich mich per Python nach dem Start?

Mit pymilvus über Port 19530: ohne aktivierte Authentifizierung ist kein Token notwendig:

from pymilvus import MilvusClient
client = MilvusClient(uri="http://localhost:19530")

Wie aktiviere ich die Authentifizierung?

Laden Sie die zum Release passende milvus.yaml herunter (https://raw.githubusercontent.com/milvus-io/milvus/v3.0.2/configs/milvus.yaml), setzen Sie den Eintrag common.security.authorizationEnabled: true und binden Sie die Datei als Volume in den standalone-Dienst ein:

volumes:
  - ${DOCKER_VOLUME_DIRECTORY:-.}/volumes/milvus:/var/lib/milvus
  - ./milvus.yaml:/milvus/configs/milvus.yaml

Nach docker compose up -d ist die Authentifizierung aktiv. Standard-Admin-Zugangsdaten: root / Milvus: sofort ändern!

Was ist der Unterschied zwischen Milvus Standalone und Cluster?

Standalone läuft als einzelner Prozess (alle Komponenten in einem Container) und eignet sich für Entwicklung und kleinere Produktionsszenarien bis etwa 100 Millionen Vektoren. Der Cluster-Modus verteilt QueryNode, DataNode und IndexNode auf mehrere Container oder Hosts für horizontale Skalierung in den Milliardenbereich. Für typische KMU-Szenarien wie RAG oder interne Semantic Search genügt Standalone.

Wie prüfe ich, ob Milvus erfolgreich gestartet ist?

Mit den Prüfungen aus Schritt 4: docker compose ps zeigt alle drei Dienste als Up (healthy), curl http://localhost:9091/healthz liefert OK.

Wie aktualisiere ich Milvus auf eine neue Version?

Erst den Stack mit docker compose down stoppen und die volumes/-Verzeichnisse sichern, dann beide Milvus-Image-Tags in der compose.yaml anpassen und anschließend:

$ cd /opt/milvus
$ docker compose pull
$ docker compose up -d

Bei einem Wechsel von 2.x auf 3.x die Release Notes und Migrationshinweise lesen und die Compose-Datei des Ziel-Releases als Vorlage nehmen (Init-Container, MinIO-Image).

Gibt es eine grafische Verwaltungsoberfläche?

Ja, zwei Optionen: (1) Die eingebaute WebUI unter http://localhost:9091/webui/ ist ab v2.5 ohne zusätzliche Installation verfügbar. (2) Attu ist ein separates Open-Source-GUI (docker pull zilliz/attu), das sich über Port 19530 mit Milvus verbindet und erweiterte Funktionen wie Collection-Management, Datenvisualisierung und interaktive Vektorsuche bietet.

Kann ich Milvus für produktive RAG-Systeme einsetzen?

Ja, mit aktivierter Authentifizierung und Backups. Zum Vergleich der Ansätze: Lokales RAG-System mit Qdrant und Embeddings, und für die Pipeline-Optimierung RAG produktiv betreiben: Chunking, Hybrid-Search und Reranking.

Fazit

Milvus eignet sich, wenn Sie eine skalierbare Vektordatenbank auf eigener Infrastruktur betreiben wollen. Der Standalone-Stack ist in etwa 20 Minuten einsatzbereit, sofern CPU, SSD und 8 GB RAM passen. Milvus, etcd und MinIO arbeiten über ein internes Docker-Netz zusammen; die Ports sind nur lokal erreichbar.

Für den Produktiveinsatz aktivieren Sie zusätzlich die Authentifizierung und richten einen regelmäßigen Backup-Job für die volumes/-Verzeichnisse ein. Zur Härtung des Stacks: Docker Compose absichern: Secrets, Healthchecks und Non-Root.

Weiterführende Anleitungen und Quellen

  1. Docker und Docker Compose auf Linux installieren: die Self-Hosting-Grundlage
  2. Lokales RAG-System mit Qdrant und Embeddings selbst bauen
  3. RAG produktiv betreiben: Chunking, Hybrid-Search, Reranking und Antwortqualität messen
  4. Docker Compose absichern: Secrets, Healthchecks, Non-Root und Read-Only
  5. Ollama und Open WebUI mit Docker: eigenes lokales KI-Sprachmodell

Offizielle Quellen: Milvus-Dokumentation: Docker Compose Installation (Standalone) | Offizielles Standalone Compose-File auf GitHub | milvusdb/milvus auf Docker Hub