Pourquoi auto-héberger Weaviate sur un VPS
Weaviate ne se contente pas de stocker des vecteurs. Chaque objet porte ses propriétés (texte, nombres, dates, références) et un ou plusieurs vecteurs, si bien qu'une seule requête renvoie les documents pertinents avec toutes leurs métadonnées. Les modules text2vec-* calculent les embeddings à l'import, les modules generative-* transmettent les résultats à un LLM, et les modules de reranking réordonnent les candidats. Le tout s'interroge en REST, en GraphQL ou en gRPC. L'auto-héberger sur un VPS vous laisse choisir les modules activés, brancher vos propres modèles d'embeddings (par exemple via Ollama sur la même machine) et garder documents et vecteurs sur un serveur que vous administrez. Pour un assistant documentaire interne, un moteur de recherche de catalogue ou une mémoire d'agent, vous maîtrisez la latence, la rétention, le schéma des collections et la fréquence des sauvegardes. Et vous faites évoluer les ressources du VPS au rythme de votre corpus, plutôt qu'au rythme d'une grille de facturation au volume.
Ce que Weaviate apporte concrètement
- Vectorisation intégrée — avec un module
text2vec-*, vous insérez du texte brut et Weaviate calcule le vecteur lui-même. - Recherche hybride native — une requête
hybridcombine score vectoriel et BM25, pondérés par le paramètrealpha. - RAG dans la base — les modules
generative-*envoient les objets trouvés à un LLM et renvoient la réponse avec les sources. - Multi-tenancy — un shard isolé par client dans la même collection, idéal pour un SaaS qui sépare les données de chaque compte.
- Named vectors — plusieurs vecteurs par objet (titre, contenu, image), chacun avec son propre vectorizer et son propre index.
- Compression de l'index — quantization PQ, BQ ou SQ pour réduire la mémoire occupée par les vecteurs.
- Licence BSD-3-Clause — code auditable, déployable sans dépendance à un service managé.
Prérequis chiffrés pour un VPS Weaviate
Pour tester avec quelques milliers d'objets, 2 Go de RAM suffisent. Pour un usage réel avec vectorisation déléguée à une API ou à Ollama, 4 Go et 2 vCPU constituent un point de départ confortable. Si vous faites tourner text2vec-transformers sur la même machine, prévoyez 8 Go ou plus : l'inférence sur CPU est lente à l'import massif. Côté disque, comptez de 30 à 60 Go de SSD selon le volume, en gardant de la marge car Weaviate passe en lecture seule quand l'occupation du disque dépasse un seuil (DISK_USE_READONLY_PERCENTAGE, 90 % par défaut). Trois ports comptent : 8080 pour REST et GraphQL, 50051 pour gRPC (utilisé par le client Python v4 pour les requêtes et les imports), et 2112 pour les métriques Prometheus si vous les activez. Aucun d'eux ne doit être exposé brut sur Internet : seul un reverse proxy en HTTPS, sur un sous-domaine comme vectors.mondomaine.com, doit faire face au public. Il vous faut enfin Docker et Docker Compose, déjà présents sur les VPS issus du Marketplace.
Quel vectorizer choisir
Faites défiler le tableau
| Option | Où tourne le modèle | Quand la choisir |
|---|---|---|
| none + vecteurs fournis | Dans votre application, avant l'import | Vous calculez déjà vos embeddings ou voulez un contrôle total du modèle |
| text2vec-openai | API externe, clé transmise en en-tête X-OpenAI-Api-Key | Mise en route rapide, VPS léger, données qui peuvent quitter le serveur |
| text2vec-ollama | Serveur Ollama sur le VPS ou le réseau privé | Embeddings locaux sans GPU dédié, avec un modèle comme nomic-embed-text |
| text2vec-transformers | Conteneur d'inférence à côté de Weaviate | Modèle figé dans l'image, idéalement avec GPU pour les gros imports |
| Plusieurs via named vectors | Mélange des options ci-dessus | Comparer deux modèles ou vectoriser titre et contenu séparément |
Déployer Weaviate étape par étape
Préparer le VPS et le DNS
Vérifiez Docker avec
docker compose version. Créez un enregistrement DNS A pourvectors.mondomaine.comvers l'IP du VPS, puis un dossier/opt/weaviatequi contiendra ledocker-compose.yml.Écrire le service weaviate
Déclarez l'image
semitechnologies/weaviate:1.27.2(aussi publiée surcr.weaviate.io). Publiez les ports en local uniquement :127.0.0.1:8080:8080et127.0.0.1:50051:50051. Docker contourne les règlesufwpour les ports publiés, donc un8080:8080resterait joignable depuis Internet même pare-feu actif. Montez un volume nommé sur/var/lib/weaviateet ajoutezrestart: unless-stopped.Poser les variables de base
PERSISTENCE_DATA_PATH=/var/lib/weaviatepour la persistance,QUERY_DEFAULTS_LIMIT=25pour le nombre de résultats par défaut,CLUSTER_HOSTNAME=node1pour un nom de nœud stable : s'il change entre deux redémarrages, le nœud ne retrouve plus son état. AjoutezDEFAULT_VECTORIZER_MODULE=noneou le module de votre choix, etENABLE_API_BASED_MODULES=truepour activer les modules qui appellent une API (text2vec-openai,text2vec-ollama,generative-openai…).Activer l'authentification par clé API
Passez
AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED=false, puisAUTHENTICATION_APIKEY_ENABLED=true,AUTHENTICATION_APIKEY_ALLOWED_KEYS=cle-admin,cle-lectureetAUTHENTICATION_APIKEY_USERS=admin,app-lecture: les clés et les utilisateurs se correspondent dans l'ordre. Générez les clés avecopenssl rand -hex 32. Pour restreindre la seconde clé à la lecture, ajoutezAUTHORIZATION_ADMINLIST_ENABLED=true,AUTHORIZATION_ADMINLIST_USERS=adminetAUTHORIZATION_ADMINLIST_READONLY_USERS=app-lecture.Démarrer et vérifier
Lancez
docker compose up -d, puiscurl -s localhost:8080/v1/.well-known/readyqui répond 200 quand le nœud est prêt.curl -s -H "Authorization: Bearer $CLE" localhost:8080/v1/metarenvoie la version et la liste des modules chargés : c'est le premier contrôle à faire quand un vectorizer semble absent.Placer Nginx et le TLS devant le port 8080
Configurez un
serverNginx pourvectors.mondomaine.comavecproxy_pass http://127.0.0.1:8080;, émettez le certificat aveccertbot --nginx -d vectors.mondomaine.comet relevezclient_max_body_sizesi vous importez par lots en REST. L'en-têteAuthorizationest transmis tel quel à Weaviate.Se connecter avec le client Python v4
Installez
pip install -U weaviate-client. Sur le VPS :client = weaviate.connect_to_local(port=8080, grpc_port=50051, auth_credentials=Auth.api_key(CLE)), avecfrom weaviate.classes.init import Auth. Depuis un autre serveur, utilisezweaviate.connect_to_custom(...)en précisant hôte, port et TLS pour HTTP et pour gRPC. Vérifiez avecclient.is_ready()et terminez parclient.close().Créer une collection et importer
client.collections.create("Article", ...)avec ses propriétés et son vectorizer, puisarticles = client.collections.get("Article"). Importez par lots dans un blocwith articles.batch.dynamic() as batch:en appelantbatch.add_object(properties={...}), et ajoutezvector=[...]si le vectorizer estnone. Contrôlez ensuitearticles.batch.failed_objectspour repérer les objets rejetés.Brancher le reste de la stack IA
Pour des embeddings et une génération 100 % locales, installez Ollama sur le même VPS et pointez
text2vec-ollamaetgenerative-ollamavers son API. Open WebUI ou votre application RAG interrogent ensuite Weaviate comme mémoire documentaire.
Modéliser les données : collections, multi-tenancy et named vectors
Dans Weaviate, les données vivent dans des collections (appelées classes dans l'ancienne API). Une collection définit ses propriétés typées (text, int, number, date, boolean, références vers d'autres collections), son vectorizer et la configuration de son index. Déclarez explicitement les propriétés plutôt que de laisser l'auto-schéma les deviner à la première insertion : un champ date deviné comme texte ne se filtre plus correctement. Pour un SaaS, activez la multi-tenancy à la création avec multi_tenancy_config=Configure.multi_tenancy(enabled=True) : chaque tenant reçoit son propre shard, s'interroge via collection.with_tenant("client-a"), et un tenant inactif peut être désactivé pour libérer la mémoire. Les named vectors permettent enfin d'attacher plusieurs vecteurs à un même objet, par exemple un pour le titre et un pour le contenu, chacun avec son modèle et son index. Attention : le vectorizer et le type d'index d'une collection ne se changent pas après coup, un changement passe par une nouvelle collection et une réimportation.
Interroger Weaviate : les requêtes utiles
- Recherche sémantique —
articles.query.near_text(query="résiliation de contrat", limit=5)exige un vectorizer, sinon passez parnear_vectoravec votre propre embedding. - Recherche hybride —
articles.query.hybrid(query="facture en double", alpha=0.5):alpha=1donne une recherche purement vectorielle,alpha=0une recherche purement BM25. - Mots-clés seuls —
articles.query.bm25(query="RGPD")utilise l'index inversé, utile pour les références, codes produit et noms propres. - Filtres —
filters=Filter.by_property("langue").equal("fr"), importé depuisweaviate.classes.query, se combine avec toutes les requêtes ci-dessus. - RAG intégré —
articles.generate.near_text(query=..., limit=3, grouped_task="Réponds à partir de ces extraits")renvoie les objets et la réponse du LLM configuré. - GraphQL — l'endpoint
/v1/graphqlreste disponible pour les outils qui l'utilisent, avec les opérateursnearText,hybridetbm25.
Index HNSW, flat ou dynamic et dimensionnement mémoire
Par défaut, chaque collection utilise un index HNSW, rapide mais gardé en mémoire. La documentation de Weaviate donne une règle empirique : prévoir environ deux fois la taille brute des vecteurs. Un million de vecteurs de 768 dimensions en float32 pèsent environ 3 Go, soit autour de 6 Go de RAM pour l'index. L'index flat ne garde rien en mémoire et convient aux petites collections, notamment aux tenants d'un SaaS. L'index dynamic démarre en flat puis bascule en HNSW au-delà d'un seuil d'objets ; il nécessite ASYNC_INDEXING=true. Pour réduire l'empreinte, activez une quantization : PQ (product quantization) compresse fortement après une phase d'entraînement sur vos données, BQ (binary quantization) réduit chaque dimension à un bit et convient surtout aux vecteurs de grande dimension, SQ (scalar quantization) passe chaque dimension sur un octet. Fixez aussi GOMEMLIMIT à environ 80 % de la RAM allouée au conteneur pour que le ramasse-miettes de Go intervienne avant que le noyau ne tue le processus.
Sauvegardes et mises à jour
Ajoutez ENABLE_MODULES=backup-filesystem et BACKUP_FILESYSTEM_PATH=/var/lib/weaviate/backups, puis déclenchez une sauvegarde avec curl -X POST -H "Authorization: Bearer $CLE" -H "Content-Type: application/json" -d '{"id":"nightly-20261001"}' localhost:8080/v1/backups/filesystem. Le statut se lit sur GET /v1/backups/filesystem/nightly-20261001 et la restauration passe par POST /v1/backups/filesystem/nightly-20261001/restore. Une sauvegarde sur le même disque ne protège pas d'une perte du VPS : copiez le dossier ailleurs, ou utilisez backup-s3 avec BACKUP_S3_BUCKET vers un stockage objet compatible S3. Pour mettre à jour, lisez les notes de migration de la version visée, sauvegardez, changez le tag de l'image puis lancez docker compose pull && docker compose up -d. Passez les versions mineures une par une et ne redescendez jamais de version sur les mêmes données sans restaurer une sauvegarde.
Ne laissez pas le port gRPC 50051 ouvert sur Internet : les applications du même VPS l'utilisent en local, et un poste distant passe par un tunnel ssh -L 50051:localhost:50051 user@vps. Le déploiement Marketplace lie d'ailleurs ce port à 127.0.0.1 et démarre avec l'accès anonyme ouvert pour faciliter la prise en main : activez l'authentification par clé API avant d'importer des données. Donnez à votre application une clé en lecture seule et réservez la clé admin aux imports et aux sauvegardes.
Superviser Weaviate
Activez PROMETHEUS_MONITORING_ENABLED=true : Weaviate expose alors ses métriques sur le port 2112 (/metrics), à collecter par Prometheus et à afficher dans Grafana. Surveillez en priorité la mémoire du processus, la durée des imports par lot et le nombre d'objets par collection. Les endpoints /v1/.well-known/live et /v1/.well-known/ready servent de sondes à un healthcheck Docker ou à un outil comme Uptime Kuma. Côté système, docker stats donne la consommation instantanée du conteneur et df -h l'occupation du volume, à suivre de près puisque le passage en lecture seule est déclenché par le disque et non par la RAM. Gardez enfin les journaux avec docker compose logs -f weaviate : les erreurs de module et les échecs de vectorisation y apparaissent avec le nom de l'objet concerné.
Dépannage : les erreurs les plus fréquentes
- Réponse 401 sur toutes les requêtes — l'accès anonyme est désactivé et la requête n'envoie pas
Authorization: Bearer <clé>, ou la clé ne figure pas dansAUTHENTICATION_APIKEY_ALLOWED_KEYS. - Le client Python v4 refuse de se connecter — il vérifie aussi gRPC : le port
50051doit être joignable depuis le client, en local ou par tunnel SSH, etgrpc_portdoit correspondre. - Module introuvable à la création d'une collection — le module n'est pas chargé : contrôlez
ENABLE_MODULES,ENABLE_API_BASED_MODULESet la liste renvoyée par/v1/meta. - Conteneur qui redémarre avec le code 137 — le noyau l'a tué faute de mémoire : posez
GOMEMLIMIT, activez une quantization ou augmentez la RAM du VPS. - Imports rejetés en lecture seule — le disque a dépassé
DISK_USE_READONLY_PERCENTAGE: libérez de l'espace ou agrandissez le volume, puis remettez les shards en écriture. - Erreurs de vectorisation à l'import — clé d'API du fournisseur absente (
X-OpenAI-Api-Keypassé dansheadersdu client) ou serveur Ollama injoignable depuis le conteneur Weaviate.
Weaviate, Qdrant, pgvector ou Milvus
Faites défiler le tableau
| Critère | Weaviate | Qdrant | pgvector | Milvus |
|---|---|---|---|---|
| Nature | Base vectorielle en Go | Base vectorielle en Rust | Extension de PostgreSQL | Base vectorielle distribuée |
| Vectorisation intégrée | Oui, modules text2vec-* | Non, embeddings fournis par le client | Non, embeddings fournis par l'application | Principalement côté client |
| API | REST, GraphQL, gRPC | REST, gRPC | SQL | gRPC, REST, SDK |
| Hybride et filtres | BM25 + vecteur natif, filtres | Filtres sur payload, vecteurs creux | WHERE SQL, plein texte PostgreSQL à combiner | Filtres scalaires, BM25 dans les versions récentes |
| Empreinte sur un VPS | Moyenne, conteneur unique | Faible, conteneur unique | Celle de votre PostgreSQL | Plus lourde, etcd et MinIO en mode standalone |
| Compression | PQ, BQ, SQ | Scalaire, binaire, produit | halfvec, bit | Plusieurs index quantifiés (IVF_PQ, IVF_SQ8…) |
| Licence | BSD-3-Clause | Apache 2.0 | Licence PostgreSQL | Apache 2.0 |
| Cas d'usage type | RAG tout-en-un avec vectorisation intégrée | Recherche vectorielle frugale | Vecteurs à côté de données relationnelles | Très gros volumes, déploiement en cluster |
Quand Weaviate est le bon choix
Weaviate se justifie quand vous voulez que la base prenne en charge la vectorisation, la recherche hybride et la génération, plutôt que de les assembler vous-même dans le code applicatif. Il convient bien à un assistant documentaire, à une recherche de catalogue multilingue ou à un SaaS qui isole chaque client par tenant. Si vous calculez déjà vos embeddings et cherchez l'empreinte la plus faible, Qdrant est plus frugal. Si vos données sont déjà dans PostgreSQL et que le volume reste modeste, pgvector évite une brique de plus. Milvus vise les très gros volumes distribués, au prix d'une infrastructure plus lourde. Sur un VPS, commencez avec un seul nœud, un index HNSW, une clé API et des sauvegardes quotidiennes, puis ajoutez quantization et multi-tenancy quand les mesures le demandent. Pour aller plus loin, consultez nos guides sur Qdrant, Ollama et Open WebUI, qui complètent Weaviate dans une stack RAG auto-hébergée.
Déployer Weaviate sur votre VPS
Commandez un VPS ServOrbit et déployez Weaviate en quelques clics depuis le Marketplace — Ubuntu 24.04, Docker pré-installé, image semitechnologies/weaviate:1.27.2 prête à l'emploi.