Meilisearch mit Docker installieren: Blitzschnelle Suchmaschinen-API selbst hosten
Meilisearch ist eine in Rust geschriebene Such-API mit über 58.000 GitHub-Stars und Ergebnissen in unter 50 ms – mit Tippfehlertoleranz und KI-Hybridsuche. Per Docker Compose in Minuten selbst gehostet.

Wer in seiner Web-App, seinem SaaS-Produkt oder einem internen Tool eine wirklich schnelle Volltextsuche braucht, stößt früher oder später auf Meilisearch. Die in Rust geschriebene Such-Engine liefert Ergebnisse typischerweise in unter 50 ms, toleriert Tippfehler out-of-the-box, beherrscht Facetten-Filter, Geo-Suche, Synonyme und – seit Version 1.x – auch semantische Vektorsuche (Hybridsuche). Mit über 58.000 GitHub-Stars ist Meilisearch die entwicklerfreundlichste selbstgehostete Suchmaschine im Open-Source-Ökosystem. Das Beste: Ein einziger Docker-Container genügt – keine externe Datenbank, kein Redis, kein Elasticsearch-Cluster. Diese Anleitung zeigt dir, wie du Meilisearch per Docker Compose plattformneutral auf einem Linux-Host (Ubuntu/Debian, NAS mit Docker-Support, VPS) zum Laufen bringst – sicher, persistent und in unter zehn Minuten.
Voraussetzungen
- Docker Engine >= 20.10 und Docker Compose V2 (als Plugin
docker compose) sind installiert. Falls nicht: Docker und Docker Compose auf Linux installieren (Ubuntu/Debian). - Linux-Host, VM oder NAS mit Docker-Unterstützung (amd64 oder arm64 – beide Architekturen werden offiziell unterstützt).
- Mindestens 512 MB RAM verfügbar; für aktive Indexierung 1–2 GB empfohlen. Auf kleinen VMs mit 512 MB unbedingt
MEILI_MAX_INDEXING_MEMORYbegrenzen. - Mindestens 1 GB freier Speicherplatz für das Daten-Volume.
- Port 7700 am Host noch nicht belegt (prüfen:
ss -tlnp | grep 7700). - Für Produktionsbetrieb: Reverse Proxy mit HTTPS (z. B. Traefik als Docker-Reverse-Proxy mit automatischem HTTPS). Meilisearch selbst bietet kein natives TLS.
Eckdaten auf einen Blick
| Parameter | Wert |
|---|---|
| Docker-Image | getmeili/meilisearch:v1.46.1 |
| Registry | Docker Hub (hub.docker.com) |
| Port | 7700 (HTTP-API + Web-Dashboard) |
| Volume | meili_data:/meili_data |
| Mindest-RAM | 512 MB (1–2 GB empfohlen) |
| Architektur | linux/amd64 und linux/arm64 |
| Lizenz | MIT (Community Edition) |
| Externe DB nötig | Nein – eigene LMDB eingebaut |
Schritt 1: Projektordner anlegen
Lege einen dedizierten Ordner für den Meilisearch-Stack an. Alle Konfigurationsdateien liegen dort, das Daten-Volume wird von Docker selbst verwaltet.
mkdir -p /opt/meilisearch
cd /opt/meilisearchDu kannst auch ~/meilisearch als Homeverzeichnis-Variante verwenden – der Rest der Anleitung funktioniert identisch.
Verifizieren: ls /opt/meilisearch gibt ein leeres Verzeichnis zurück. Das ist korrekt – die Dateien folgen in den nächsten Schritten.
Schritt 2: .env-Datei mit Secrets anlegen
Der Master-Key schützt die gesamte Meilisearch-API. Er muss mindestens 16 Bytes lang sein (UTF-8); aus ihm leitet Meilisearch automatisch einen Admin-Key und einen Such-Key ab. Generiere einen kryptografisch starken Wert:
openssl rand -hex 32Das Ergebnis (64 hexadezimale Zeichen) in die .env-Datei eintragen:
MEILI_MASTER_KEY=hier_dein_generierter_key_eintragen
MEILI_ENV=production
MEILI_NO_ANALYTICS=true
MEILI_LOG_LEVEL=INFODateirechte einschränken, damit der Key nicht für andere Systemnutzer lesbar ist:
chmod 600 /opt/meilisearch/.envWichtig: Die Datei muss vor dem ersten docker compose up existieren. Fehlt sie oder ist MEILI_MASTER_KEY nicht gesetzt, startet Meilisearch im Produktionsmodus gar nicht – du erhältst den Fehler „A master key must be provided".
Verifizieren: cat /opt/meilisearch/.env zeigt die vier Variablen. ls -la /opt/meilisearch/.env zeigt -rw------- als Berechtigung.
Schritt 3: compose.yaml erstellen
Die compose.yaml definiert den Meilisearch-Container mit Healthcheck, Named Volume und allen relevanten Umgebungsvariablen. Beachte besonders MEILI_HTTP_ADDR=0.0.0.0:7700: Ohne diese Variable lauscht Meilisearch nur auf localhost innerhalb des Containers – Port-Mapping allein reicht dann nicht aus, um den Dienst vom Host zu erreichen. Das ist der häufigste Fallstrick beim Docker-Deployment.
services:
meilisearch:
image: getmeili/meilisearch:v1.46.1
container_name: meilisearch
restart: unless-stopped
ports:
- "7700:7700"
environment:
- MEILI_MASTER_KEY=${MEILI_MASTER_KEY}
- MEILI_ENV=${MEILI_ENV:-production}
- MEILI_HTTP_ADDR=0.0.0.0:7700
- MEILI_NO_ANALYTICS=${MEILI_NO_ANALYTICS:-true}
- MEILI_LOG_LEVEL=${MEILI_LOG_LEVEL:-INFO}
- MEILI_DB_PATH=/meili_data/data.ms
- MEILI_DUMP_DIR=/meili_data/dumps
- MEILI_SNAPSHOT_DIR=/meili_data/snapshots
volumes:
- meili_data:/meili_data
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--spider", "http://localhost:7700/health"]
interval: 30s
timeout: 10s
retries: 5
start_period: 20s
volumes:
meili_data:
driver: localZum Image-Tag: Verwende immer einen konkreten Versionstag (v1.46.1) statt latest. Bei mehreren Hosts oder nach einem erneuten docker compose pull kann latest auf eine neuere, inkompatible Version zeigen. Die aktuell stabile Version findest du stets auf Docker Hub unter getmeili/meilisearch.
Das Named Volume meili_data ist bewusst gewählt: Im Gegensatz zu einem Bind-Mount (./meili_data:/meili_data) gibt es keine Berechtigungsprobleme, wenn das Host-Verzeichnis einem anderen Nutzer gehört als der Container-Prozess.
Verifizieren: docker compose config (im Projektordner ausgeführt) gibt die aufgelöste Konfiguration ohne Fehler aus. Erscheint eine Warnung zu fehlenden Variablen, liegt die .env-Datei nicht im selben Verzeichnis.
Schritt 4: Container starten
Starte den Stack im Hintergrund:
docker compose up -dDocker zieht das Image (~101 MB komprimiert) von Docker Hub und startet den Container. Nach etwa 20 Sekunden sollte der Healthcheck greifen.
Status prüfen:
docker compose psErwartete Ausgabe (nach dem start_period des Healthchecks):
NAME IMAGE SERVICE STATUS PORTS
meilisearch getmeili/meilisearch:v1.46.1 meilisearch Up 2 minutes (healthy) 0.0.0.0:7700->7700/tcpStart-Log ansehen:
docker compose logs meilisearchIm Log sollte u. a. folgendes erscheinen:
INFO meilisearch: Server listening on: "0.0.0.0:7700"
INFO meilisearch: Environment: "production"Verifizieren: curl -s http://localhost:7700/health gibt {"status":"available"} zurück. Erscheint stattdessen Connection refused, ist MEILI_HTTP_ADDR=0.0.0.0:7700 nicht gesetzt oder der Container noch nicht vollständig gestartet – Logs prüfen.
Schritt 5: Dashboard öffnen und API testen
Meilisearch bringt ein eingebautes Mini-Dashboard mit, das ohne zusätzliche Installation direkt im Browser erreichbar ist.
Öffne in deinem Browser: http://<server-ip>:7700
Das Dashboard fragt beim ersten Aufruf nach dem Master-Key. Gib den Key aus deiner .env-Datei ein – du kannst damit Indizes durchsuchen und verwalten, ohne eine Zeile Code zu schreiben.
Alternativ kannst du die API direkt per curl testen. Zuerst die Systemversion abfragen:
curl -s http://localhost:7700/version | python3 -m json.toolEinen Testindex mit Dokumenten anlegen (Master-Key als Bearer-Token):
curl -X POST http://localhost:7700/indexes/filme/documents \
-H "Authorization: Bearer ${MEILI_MASTER_KEY}" \
-H "Content-Type: application/json" \
-d '[{"id":1,"titel":"Der Herr der Ringe"},{"id":2,"titel":"Das Schweigen der Lämmer"}]'Suche mit Tippfehlertoleranz – Meilisearch korrigiert automatisch bis zu zwei Fehler bei Wörtern ab 9 Zeichen:
curl -s "http://localhost:7700/indexes/filme/search" \
-H "Authorization: Bearer ${MEILI_MASTER_KEY}" \
-H "Content-Type: application/json" \
-d '{"q":"Herr der Rnge"}' | python3 -m json.toolMeilisearch findet trotz des Tippfehlers „Rnge" den richtigen Treffer und gibt processingTimeMs typischerweise im einstelligen Millisekundenbereich zurück.
Verifizieren: Die Such-Antwort enthält "hits":[{"id":1,"titel":"Der Herr der Ringe"}] und "processingTimeMs" liegt deutlich unter 50. Das Dashboard unter http://<server-ip>:7700 zeigt den Index „filme" mit zwei Dokumenten.
Schritt 6: API-Keys für Anwendungen erstellen
In der Produktion sollte deine Anwendung nie den Master-Key direkt verwenden. Meilisearch leitet aus dem Master-Key automatisch einen Default Admin Key (volle Schreibrechte) und einen Default Search Key (nur Leserechte) ab. Diese Keys kannst du abfragen:
curl -s http://localhost:7700/keys \
-H "Authorization: Bearer ${MEILI_MASTER_KEY}" | python3 -m json.toolDen Default Search Key verwendest du im Frontend-Code – er ist read-only und kann gefahrlos in JavaScript-Bundles eingebettet werden. Für spezifischere Berechtigungen (z. B. nur bestimmte Indizes, Multi-Tenant-Szenarien) erstellst du eigene Keys per POST /keys mit dem Master-Key als Bearer-Token.
Verifizieren: Die Antwort enthält mindestens zwei Einträge mit den Feldern "key", "actions" und "indexes". Der Search-Key hat "actions":["search"], der Admin-Key deutlich mehr Rechte.
Schritt 7: Backup und Updates
Backup per Dump
Meilisearch bietet zwei Sicherungsmethoden. Dumps sind versions-übergreifend portierbar und eignen sich für Migrationen:
curl -X POST http://localhost:7700/dumps \
-H "Authorization: Bearer ${MEILI_MASTER_KEY}"Die erzeugte .dump-Datei liegt im Container unter /meili_data/dumps, das über das Named Volume auf dem Host zugänglich ist:
docker volume inspect meilisearch_meili_data
# Mountpoint zeigt den Host-Pfad, z. B.:
# /var/lib/docker/volumes/meilisearch_meili_data/_data/Für automatische tägliche Snapshots füge MEILI_SCHEDULE_SNAPSHOT=86400 zur .env-Datei hinzu und starte den Container neu. Snapshots landen in /meili_data/snapshots. Beachte: Snapshots sind nur für denselben Major-Release wiederherstellbar – für Major-Upgrades immer Dumps verwenden. Eine solide Backup-Strategie beschreibt 3-2-1-Backup-Strategie umsetzen: Anleitung mit Restic, USB-Disk und S3-Cloud.
Update auf neue Version
cd /opt/meilisearch
# compose.yaml: image-Tag auf neue Version anpassen, z. B. v1.47.0
docker compose pull
docker compose up -dBei Minor-Updates (v1.x auf v1.y) ist kein Dump nötig – das Daten-Volume bleibt unverändert. Bei Major-Upgrades (v1.x auf v2.x) vorher zwingend einen Dump erstellen, da die LMDB-Datenbank nicht rückwärtskompatibel ist.
Verifizieren: Nach dem Update zeigt docker compose ps den neuen Image-Tag und Status healthy. curl -s http://localhost:7700/version gibt die neue Versionsnummer zurück.
Troubleshooting / Typische Fehler
- „Connection refused" auf Port 7700:
MEILI_HTTP_ADDR=0.0.0.0:7700fehlt in dercompose.yaml. Meilisearch lauscht dann nur container-intern auflocalhost:7700, Port-Mapping hat keinen Effekt. Variable ergänzen, Container mitdocker compose up -dneu starten. - „A master key must be provided":
MEILI_ENV=productionist gesetzt, aberMEILI_MASTER_KEYfehlt in der.env-Datei oder die Datei liegt nicht im selben Verzeichnis wiecompose.yaml. Prüfe mitdocker compose config, ob die Variable aufgelöst wird. - „The provided API key is invalid": Der Master-Key ist kürzer als 16 Bytes. Bei Sonderzeichen kann die Byte-Länge von der Zeichenanzahl abweichen. Sicherer:
openssl rand -hex 32erzeugt stets einen 64-Zeichen-ASCII-Key. - Container bleibt bei „starting" statt „healthy": Der Healthcheck schlägt fehl. Häufigste Ursache:
MEILI_HTTP_ADDRfehlt.docker compose logs meilisearchzeigt die genaue Fehlermeldung. - OOM-Kill auf kleinen VMs: Meilisearch nutzt standardmäßig 2/3 des verfügbaren RAMs für die Indexierung. Auf VMs mit wenig Arbeitsspeicher zu
.envhinzufügen:MEILI_MAX_INDEXING_MEMORY=256Mb. Danachdocker compose up -dausführen. - „Address already in use": Port 7700 ist belegt. Prüfen mit
ss -tlnp | grep 7700. Incompose.yamlden Host-Port ändern (z. B.7701:7700) –MEILI_HTTP_ADDRbleibt auf0.0.0.0:7700(Container-intern). - Datenverlust nach Major-Upgrade: Beim Upgrade zwischen Major-Versionen ist die LMDB-Datenbank nicht rückwärtskompatibel. Vor jedem Major-Upgrade per
POST /dumpseinen Dump erstellen und nach dem Upgrade importieren (POST /snapshotsreicht hier nicht).
Häufige Fragen
Brauche ich PostgreSQL, Redis oder eine andere externe Datenbank?
Nein. Meilisearch bringt seine eigene eingebettete LMDB-Datenbank mit. Ein einziger Docker-Container ist alles, was du brauchst – kein Redis, kein Elasticsearch, kein PostgreSQL. Das macht den Betrieb deutlich einfacher als bei vergleichbaren Such-Engines wie OpenSearch oder Typesense-Clustern.
Wie aktiviere ich die KI-gestützte Hybridsuche?
Hybridsuche kombiniert klassische Volltextsuche mit semantischer Vektorsuche. Sie wird pro Index über die Einstellungs-API konfiguriert: PATCH /indexes/{uid}/settings mit einem embedders-Objekt, das den Embedding-Provider definiert (z. B. openAI, huggingFace, ollama). Für lokale Embeddings ohne Cloud-Abhängigkeit bietet sich Ollama an – eine Installationsanleitung findest du unter Ollama und Open WebUI mit Docker: eigenes lokales KI-Sprachmodell ohne Cloud betreiben.
Ist Meilisearch auf ARM-Hardware lauffähig?
Ja. Das offizielle Image getmeili/meilisearch unterstützt sowohl linux/amd64 als auch linux/arm64 (je ~101 MB komprimiert). Der richtige Layer wird automatisch beim Pull ausgewählt – dasselbe Image-Tag funktioniert auf einem Raspberry Pi 4/5, einem Apple-Silicon-Mac (via Docker Desktop) und jedem AMD64-Server.
Wie erstelle ich eingeschränkte API-Keys für meine Anwendung?
Nach dem Start leitet Meilisearch automatisch einen Admin-Key und einen Such-Key ab. Eigene Keys mit feingranularen Rechten (bestimmte Indizes, bestimmte Aktionen, Ablaufdatum) erstellst du per POST /keys mit dem Master-Key als Bearer-Token. Für Multi-Tenant-Szenarien unterstützt Meilisearch zusätzlich Tenant-Tokens, mit denen jeder Nutzer nur seine eigenen Daten sieht.
Was ist der Unterschied zwischen Dumps und Snapshots?
Dumps (POST /dumps) erzeugen ein portables Exportformat, das über Major-Versionen hinweg importiert werden kann – ideal für Migrationen. Snapshots sind binäre Kopien der LMDB-Datenbank und lassen sich nur in derselben Major-Version wiederherstellen, sind aber deutlich schneller erstellt. Für regelmäßige Sicherungen empfiehlt sich eine Kombination: tägliche Snapshots für den schnellen Restore, gelegentliche Dumps als Migrations-Reserve.
Muss ich Meilisearch absichern, bevor es öffentlich erreichbar ist?
Ja, unbedingt. Meilisearch hat kein natives HTTPS. Ohne Reverse Proxy werden Master-Key und API-Keys im Klartext übertragen. Stelle immer einen Reverse Proxy mit TLS davor – z. B. Traefik, Caddy oder Nginx Proxy Manager. Außerdem: MEILI_ENV=production und ein starker Master-Key sind Pflicht. Ohne sie läuft Meilisearch im völlig offenen Entwicklungsmodus ohne jede Authentifizierung.
Fazit
Meilisearch ist einer der einfachsten Wege, eine produktionsreife Suchmaschine in die eigene Infrastruktur zu integrieren. Der Rust-Kern sorgt für Geschwindigkeit, das RESTful-API-Design und die verfügbaren SDKs für JavaScript, Python, PHP, Go und weitere Sprachen machen die Anbindung unkompliziert. Der wichtigste Unterschied zu gehosteten Lösungen: du behältst die volle Kontrolle über deine Daten – kein Cloud-Lock-in, keine Kosten pro Anfrage, keine Datenweitergabe. Die Kernfallstricke – MEILI_HTTP_ADDR nicht vergessen, Master-Key mindestens 16 Bytes, vor Major-Upgrades Dump erstellen – sind leicht zu umschiffen, wenn man sie kennt. Für Produktionsumgebungen ist ein Reverse Proxy mit HTTPS der nächste logische Schritt; für lokale Entwicklung und interne Tools reicht der Setup aus dieser Anleitung sofort.
Weiterführende Anleitungen und Quellen
- Traefik als Docker-Reverse-Proxy mit automatischem HTTPS einrichten – HTTPS-Termination vor Meilisearch
- Docker Compose absichern: Secrets, Healthchecks, Non-Root und Read-Only für den Produktivbetrieb – Sicherheits-Hardening für den Stack
- Lokales RAG-System mit Qdrant und Embeddings selbst bauen – Vektorsuche als Ergänzung zu Meilisearch
- Ollama und Open WebUI mit Docker: lokales KI-Sprachmodell ohne Cloud betreiben – Embedding-Provider für die Meilisearch-Hybridsuche
Offizielle Dokumentation: Meilisearch Docker Guide | Konfigurationsreferenz (Instance Options) | Docker Hub: getmeili/meilisearch | GitHub-Repository