Héberger Meilisearch soi-même pour une recherche rapide
Suivez ça sur votre propre serveur. Commencer gratuitement, sans carte
Algolia et les API de recherche hébergées similaires facturent selon le volume de recherches et le nombre d’enregistrements, ce qui s’accumule vite une fois qu’un site a un vrai trafic. Meilisearch est un moteur de recherche open source écrit en Rust qui indexe une recherche instantanée et tolérante aux fautes de frappe sur vos propres données, et il est assez léger pour tourner sur le serveur le moins cher que vend un fournisseur cloud. À la fin de ce guide, vous l’aurez en fonctionnement derrière HTTPS avec une vraie clé maîtresse qui le protège, une capture que vous pourrez restaurer, et une mise à niveau courte.
Ce qu’il vous faut
- Un serveur avec Docker et le plugin Compose. Un Hetzner CX23 (2 vCPU, 4 Go de RAM, 40 Go NVMe, 5,99 €/mois hors TVA) fait tourner Meilisearch sans problème pour un index petit à moyen.
- Un domaine ou sous-domaine pointé vers l’adresse IP du serveur.
- Un accès SSH au serveur.
- Vos données prêtes à indexer : Meilisearch garde les documents que vous lui envoyez, il n’explore rien tout seul.
Étape 1 : générer une vraie clé maîtresse
Meilisearch refuse de démarrer en production sans ça. MEILI_ENV=production exige une clé d’au moins 16 octets, et sans elle (ou avec une plus courte), le serveur journalise une clé suggérée et quitte plutôt que de tourner sans protection :
openssl rand -base64 48
Mettez le résultat dans un fichier .env à côté de votre fichier compose, non commité dans le contrôle de version :
MEILI_MASTER_KEY=paste-the-generated-value-here
chmod 600 .env
Étape 2 : écrire le fichier Docker Compose
services:
meilisearch:
image: getmeili/meilisearch:v1.55.0
restart: unless-stopped
environment:
MEILI_MASTER_KEY: ${MEILI_MASTER_KEY}
MEILI_ENV: production
MEILI_NO_ANALYTICS: "true"
volumes:
- ./meili_data:/meili_data
expose:
- "7700"
caddy:
image: caddy:2
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
- caddy_data:/data
- caddy_config:/config
depends_on:
- meilisearch
volumes:
caddy_data:
caddy_config:
Ce guide fixe v1.55.0, la version stable actuelle au moment de l’écriture. MEILI_ENV=production fait deux choses : il désactive l’interface de bac à sable de recherche intégrée sur le chemin racine (une commodité pour le développement local qui n’a rien à faire d’accessible sur un serveur public), et c’est ce qui rend la clé maîtresse obligatoire plutôt qu’optionnelle. MEILI_NO_ANALYTICS=true retire l’instance du rapport d’usage anonyme propre à Meilisearch. ./meili_data est un montage lié simple plutôt qu’un volume nommé, précisément pour qu’une sauvegarde à l’étape 5 ne soit qu’une copie de dossier, et c’est là que vit réellement chaque index et chaque journal de tâches.
Vérifiez que ça s’analyse :
docker compose config
Étape 3 : pointer le DNS et ajouter Caddy
Créez un enregistrement A pour votre sous-domaine pointant vers l’IP du serveur, puis ajoutez un Caddyfile à côté de compose.yml :
search.yourdomain.com {
reverse_proxy meilisearch:7700
}
Étape 4 : démarrer la pile et créer votre premier index
docker compose up -d
docker compose ps
curl https://search.yourdomain.com/health
Vous devriez voir les deux services à l’état Up et la vérification de santé retourner {"status":"available"}. Créez un index et ajoutez un document pour confirmer que la clé maîtresse fonctionne réellement :
curl -X POST 'https://search.yourdomain.com/indexes' \
-H "Authorization: Bearer ${MEILI_MASTER_KEY}" \
-H 'Content-Type: application/json' \
--data-binary '{ "uid": "movies", "primaryKey": "id" }'
curl -X POST 'https://search.yourdomain.com/indexes/movies/documents' \
-H "Authorization: Bearer ${MEILI_MASTER_KEY}" \
-H 'Content-Type: application/json' \
--data-binary '[{ "id": 1, "title": "Carol" }]'
Vous devriez recevoir un taskUid en retour des deux appels. Vérifiez que la tâche s’est terminée, et qu’une recherche trouve réellement le document :
curl "https://search.yourdomain.com/indexes/movies/search?q=carol" \
-H "Authorization: Bearer ${MEILI_MASTER_KEY}"
Vous devriez voir "title": "Carol" dans le tableau hits. À partir de là, votre application devrait créer une clé API limitée, non maîtresse, par cas d’usage (une qui peut seulement chercher, pas gérer les index) via le point de terminaison /keys, plutôt que d’envoyer la clé maîtresse elle-même à un navigateur.
Étape 5 : sauvegarder /meili_data
Le point de terminaison /snapshots propre à Meilisearch (en fait un export planifié, pas un vrai appel d’API de capture instantanée) écrit un fichier .snapshot à l’intérieur du conteneur selon un intervalle que vous configurez, mais la sauvegarde la plus simple et la plus portable est une archive du volume lui-même pendant que le conteneur n’écrit pas activement :
cat > /opt/meilisearch/backup.sh <<'EOF'
#!/bin/sh
cd /opt/meilisearch
docker compose stop meilisearch
tar czf backups/meili-$(date +%F).tar.gz meili_data
docker compose start meilisearch
find backups -name '*.tar.gz' -mtime +14 -delete
EOF
mkdir -p /opt/meilisearch/backups
chmod +x /opt/meilisearch/backup.sh
(crontab -l 2>/dev/null; echo "0 3 * * * /opt/meilisearch/backup.sh") | crontab -
Lancez-le une fois à la main et vérifiez que ça a fonctionné : ./backup.sh && ls -lh backups. Vous devriez voir un fichier .tar.gz avec la date du jour. Le court arrêt et redémarrage garde l’archive cohérente en interne ; pour un index de recherche public, quelques secondes d’indisponibilité à 3 h du matin sont un compromis raisonnable pour une sauvegarde à laquelle vous pouvez réellement faire confiance. Copiez aussi le fichier en dehors du serveur, pour que perdre la machine ne veuille pas dire perdre aussi l’index.
Étape 6 : mettre à niveau
docker compose pull meilisearch
docker compose up -d meilisearch
Meilisearch migre automatiquement son propre format de données sur disque au démarrage quand il le peut, mais les notes de version du projet signalent des sauts de version qui exigent une réindexation par export-import plutôt qu’une mise à niveau sur place ; lisez le journal des modifications pour la version vers laquelle vous allez avant un saut de plusieurs versions, en particulier à travers une limite de version majeure.
Le raccourci : avec Railyard
Railyard fournit Meilisearch comme modèle d’application en un clic (meilisearch dans le catalogue de modèles), construit à partir de l’image officielle getmeili/meilisearch avec MEILI_NO_ANALYTICS déjà défini et un volume de données persistant déjà branché. Déployez-le directement : app.railyard.run/deploy?template=meilisearch. Une vraie différence par rapport au chemin manuel ci-dessus : le modèle suit actuellement l’étiquette flottante latest plutôt qu’une version fixée, donc là où ce guide vous fait choisir et mettre à niveau une version précise vous-même, Railyard avance automatiquement avec le projet amont ; définissez MEILI_MASTER_KEY vous-même comme variable dans la page Settings de l’application dans tous les cas, elle n’est pas générée pour vous. Voyez déployer avec un bouton pour savoir comment fonctionnent les modèles en un clic en général, et bases de données et sauvegardes pour savoir comment les volumes persistants sont gérés sur la plateforme.
Dépannage
Le conteneur se ferme immédiatement avec un message à propos de la clé maîtresse. MEILI_ENV=production sans MEILI_MASTER_KEY défini, ou avec une clé de moins de 16 octets, fait en sorte que Meilisearch refuse de démarrer plutôt que de tourner ouvert. Revérifiez que le fichier .env de l’étape 1 a bien une vraie valeur et que docker compose config la montre résolue, pas une chaîne vide.
401 Unauthorized sur chaque appel d’API. L’en-tête Authorization: Bearer <key> est manquant, ou vous passez la mauvaise clé, souvenez-vous que la clé maîtresse peut tout faire, y compris créer d’autres clés, mais toute requête en a quand même besoin (ou d’une clé limitée) dans l’en-tête ; il n’y a aucun chemin non authentifié une fois qu’une clé maîtresse est définie.
Le HTTPS ne s’émet pas. Vérifiez docker compose logs caddy pour l’erreur ACME ; c’est presque toujours que l’enregistrement DNS de l’étape 3 ne pointe pas encore vers ce serveur, confirmez avec dig +short search.yourdomain.com.
Les résultats de recherche n’incluent pas un document que vous venez d’ajouter. L’indexation est asynchrone ; chaque écriture retourne un taskUid, et le document n’est pas cherchable tant que cette tâche n’est pas terminée. Interrogez /tasks/{taskUid} si vous devez confirmer l’achèvement par programmation plutôt que de deviner avec un délai fixe.
Manque de mémoire sur un petit serveur avec un gros index. Meilisearch garde une quantité significative de données d’index en mémoire pour la vitesse des requêtes ; les 4 Go d’un CX23 conviennent pour un catalogue modeste, mais un index de plusieurs millions de documents veut plutôt le CX33 (8 Go) ou plus que du swap, puisque la latence de recherche (pas seulement la stabilité) en souffre une fois qu’il se met à utiliser le swap.
FAQ
Meilisearch remplace-t-il Elasticsearch ? Pour la plupart des cas d’usage de recherche applicative (un catalogue e-commerce, un site de documentation, une recherche dans l’application), oui, et avec beaucoup moins de charge opérationnelle ; Elasticsearch gagne toujours pour l’agrégation de journaux et les charges de travail analytiques complexes pour lesquelles Meilisearch n’a jamais été conçu.
Plusieurs applications peuvent-elles partager une seule instance Meilisearch ? Oui, les index sont espacés par uid au sein de la même instance, et les clés API limitées peuvent restreindre une clé donnée à des index spécifiques, donc une seule instance sert plusieurs applications en toute sécurité.
Ai-je aussi besoin d’une base de données séparée ? Non, Meilisearch est le système de référence pour ce que vous indexez dedans, même si la plupart des configurations le traitent comme un index de recherche dérivé maintenu synchronisé avec une base de données principale, plutôt que comme la seule copie des données.
Quelle taille un index peut-il atteindre sur un CX23 ? Il n’y a pas de limite stricte dans Meilisearch lui-même ; le plafond pratique, c’est la RAM et le disque du serveur, quelques centaines de milliers de documents de taille habituelle tiennent confortablement dans 4 Go, bien au-delà, c’est là que redimensionner vers le haut aide vraiment.
L’API REST est-elle la seule façon d’y accéder ? Non, des SDK officiels existent pour JavaScript, Python, PHP, Ruby, Go, Rust et plus, qui appellent tous la même API REST que ce guide utilise directement avec curl.
Une fois la clé maîtresse, le HTTPS et une sauvegarde en place, Meilisearch tourne essentiellement tout seul. Les deux choses qui valent la peine d’être revues plus tard sont une clé limitée par application plutôt que la clé maîtresse partout, et la planification de sauvegarde de l’étape 5 une fois que l’index est quelque chose qui vous manquerait vraiment.
Pourquoi les gens choisissent Railyard pour ça
- Votre propre compte infonuagique. Déployez sur DigitalOcean, Hetzner, Vultr, AWS, OVHcloud, ou n'importe quel serveur Linux par SSH, facturé directement par votre fournisseur, sans majoration.
- Un prix fixe par équipe. L'offre gratuite est gratuite pour toujours : un serveur plus un serveur de base de données, trois applications, sans carte. Pro coûte 19 $ par mois pour jusqu'à cinq serveurs et un nombre illimité d'applications. Team coûte 49 $ par mois avec des serveurs illimités. Aucuns frais par application, par déploiement, par siège ou par gigaoctet.
- Des gabarits en un clic. Déployez des applications open source, comme des bases de données, des outils d'analyse et des outils de développement, sur votre propre serveur en un clic.
- Des bases de données gérées. Postgres, MySQL et Redis, avec des sauvegardes planifiées, vérifiées par restauration, et la récupération à un point dans le temps.
- Déploiement par push. Déployez depuis GitHub, GitLab ou la CLI, avec HTTPS automatique et des mises en production sans interruption.