Por qué autoalojar Weaviate en un VPS
Weaviate no se limita a almacenar vectores. Cada objeto lleva sus propiedades (texto, números, fechas, referencias) y uno o varios vectores, de modo que una sola consulta devuelve los documentos pertinentes con todos sus metadatos. Los módulos text2vec-* calculan los embeddings al importar, los módulos generative-* envían los resultados a un LLM y los módulos de reranking reordenan los candidatos. Todo se consulta por REST, GraphQL o gRPC. Autoalojarlo en un VPS le permite elegir qué módulos se activan, conectar sus propios modelos de embeddings (por ejemplo mediante Ollama en la misma máquina) y mantener documentos y vectores en un servidor que usted administra. Para un asistente documental interno, un buscador de catálogo o una memoria de agente, usted controla la latencia, la retención, el esquema de las colecciones y la frecuencia de las copias de seguridad. Y amplía los recursos del VPS al ritmo de su corpus, no al ritmo de una tarifa por volumen.
Lo que Weaviate aporta en la práctica
- Vectorización integrada — con un módulo
text2vec-*, usted inserta texto plano y Weaviate calcula el vector por sí mismo. - Búsqueda híbrida nativa — una consulta
hybridcombina la puntuación vectorial y BM25, ponderadas por el parámetroalpha. - RAG dentro de la base — los módulos
generative-*envían los objetos encontrados a un LLM y devuelven la respuesta junto con las fuentes. - Multi-tenancy — un shard aislado por cliente dentro de la misma colección, ideal para un SaaS que separa los datos de cada cuenta.
- Named vectors — varios vectores por objeto (título, contenido, imagen), cada uno con su propio vectorizer y su propio índice.
- Compresión del índice — cuantización PQ, BQ o SQ para reducir la memoria que ocupan los vectores.
- Licencia BSD-3-Clause — código auditable, desplegable sin depender de un servicio gestionado.
Requisitos cuantificados para un VPS con Weaviate
Para probar con unos miles de objetos bastan 2 GB de RAM. Para un uso real con la vectorización delegada a una API o a Ollama, 4 GB y 2 vCPU son un punto de partida cómodo. Si ejecuta text2vec-transformers en la misma máquina, prevea 8 GB o más: la inferencia en CPU es lenta en las importaciones masivas. En disco, cuente de 30 a 60 GB de SSD según el volumen y deje margen, porque Weaviate pasa a solo lectura cuando la ocupación del disco supera un umbral (DISK_USE_READONLY_PERCENTAGE, 90 % por defecto). Tres puertos importan: 8080 para REST y GraphQL, 50051 para gRPC (que el cliente Python v4 usa para consultas e importaciones) y 2112 para las métricas de Prometheus si las activa. Ninguno debe quedar expuesto directamente a Internet: solo un proxy inverso en HTTPS, en un subdominio como vectors.example.com, debe dar la cara al público. Por último, necesita Docker y Docker Compose, ya presentes en los VPS creados desde el Marketplace.
Qué vectorizer elegir
Desplace la tabla
| Opción | Dónde se ejecuta el modelo | Cuándo elegirla |
|---|---|---|
| none + vectores propios | En su aplicación, antes de importar | Ya calcula sus embeddings o quiere control total sobre el modelo |
| text2vec-openai | API externa, clave enviada en la cabecera X-OpenAI-Api-Key | Arranque rápido, VPS ligero, datos que pueden salir del servidor |
| text2vec-ollama | Servidor Ollama en el VPS o en la red privada | Embeddings locales sin GPU dedicada, con un modelo como nomic-embed-text |
| text2vec-transformers | Contenedor de inferencia junto a Weaviate | Modelo incluido en la imagen, idealmente con GPU para grandes importaciones |
| Varios mediante named vectors | Combinación de las opciones anteriores | Comparar dos modelos o vectorizar título y contenido por separado |
Desplegar Weaviate paso a paso
Preparar el VPS y el DNS
Compruebe Docker con
docker compose version. Cree un registro DNS A paravectors.example.comhacia la IP del VPS y después una carpeta/opt/weaviateque contendrá eldocker-compose.yml.Escribir el servicio weaviate
Declare la imagen
semitechnologies/weaviate:1.27.2(también publicada encr.weaviate.io). Publique los puertos solo en local:127.0.0.1:8080:8080y127.0.0.1:50051:50051. Docker se salta las reglas deufwen los puertos publicados, así que un8080:8080seguiría accesible desde Internet aunque el cortafuegos esté activo. Monte un volumen con nombre en/var/lib/weaviatey añadarestart: unless-stopped.Definir las variables básicas
PERSISTENCE_DATA_PATH=/var/lib/weaviatepara la persistencia,QUERY_DEFAULTS_LIMIT=25para el número de resultados por defecto,CLUSTER_HOSTNAME=node1para un nombre de nodo estable: si cambia entre dos reinicios, el nodo deja de encontrar su estado. AñadaDEFAULT_VECTORIZER_MODULE=noneo el módulo que prefiera, yENABLE_API_BASED_MODULES=truepara activar los módulos que llaman a una API (text2vec-openai,text2vec-ollama,generative-openai…).Activar la autenticación por clave API
Ponga
AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED=falsey despuésAUTHENTICATION_APIKEY_ENABLED=true,AUTHENTICATION_APIKEY_ALLOWED_KEYS=clave-admin,clave-lecturayAUTHENTICATION_APIKEY_USERS=admin,app-lectura: claves y usuarios se corresponden por orden. Genere las claves conopenssl rand -hex 32. Para limitar la segunda clave a lectura, añadaAUTHORIZATION_ADMINLIST_ENABLED=true,AUTHORIZATION_ADMINLIST_USERS=adminyAUTHORIZATION_ADMINLIST_READONLY_USERS=app-lectura.Arrancar y comprobar
Ejecute
docker compose up -dy despuéscurl -s localhost:8080/v1/.well-known/ready, que responde 200 cuando el nodo está listo.curl -s -H "Authorization: Bearer $CLAVE" localhost:8080/v1/metadevuelve la versión y la lista de módulos cargados: es la primera comprobación cuando un vectorizer parece no estar disponible.Poner Nginx y TLS delante del puerto 8080
Configure un
serverde Nginx paravectors.example.comconproxy_pass http://127.0.0.1:8080;, emita el certificado concertbot --nginx -d vectors.example.comy aumenteclient_max_body_sizesi importa por lotes vía REST. La cabeceraAuthorizationllega a Weaviate sin cambios.Conectarse con el cliente Python v4
Instale
pip install -U weaviate-client. En el VPS:client = weaviate.connect_to_local(port=8080, grpc_port=50051, auth_credentials=Auth.api_key(CLAVE)), confrom weaviate.classes.init import Auth. Desde otro servidor, useweaviate.connect_to_custom(...)indicando host, puerto y TLS tanto para HTTP como para gRPC. Compruebe conclient.is_ready()y termine conclient.close().Crear una colección e importar
client.collections.create("Article", ...)con sus propiedades y su vectorizer, y despuésarticles = client.collections.get("Article"). Importe por lotes dentro de un bloquewith articles.batch.dynamic() as batch:llamando abatch.add_object(properties={...}), y añadavector=[...]si el vectorizer esnone. Revise luegoarticles.batch.failed_objectspara detectar los objetos rechazados.Conectar el resto de la pila de IA
Para embeddings y generación totalmente locales, instale Ollama en el mismo VPS y apunte
text2vec-ollamaygenerative-ollamaa su API. Open WebUI o su aplicación RAG consultan entonces Weaviate como memoria documental.
Modelar los datos: colecciones, multi-tenancy y named vectors
En Weaviate, los datos viven en colecciones (llamadas clases en la API antigua). Una colección define sus propiedades tipadas (text, int, number, date, boolean, referencias a otras colecciones), su vectorizer y la configuración de su índice. Declare las propiedades de forma explícita en lugar de dejar que el auto-esquema las adivine en la primera inserción: un campo de fecha interpretado como texto ya no se filtra correctamente. Para un SaaS, active la multi-tenancy al crear la colección con multi_tenancy_config=Configure.multi_tenancy(enabled=True): cada tenant recibe su propio shard, se consulta mediante collection.with_tenant("cliente-a") y un tenant sin actividad puede desactivarse para liberar memoria. Por último, los named vectors permiten asociar varios vectores a un mismo objeto, por ejemplo uno para el título y otro para el contenido, cada uno con su modelo y su índice. Atención: el vectorizer y el tipo de índice de una colección no se pueden cambiar después; un cambio implica una nueva colección y una reimportación.
Consultar Weaviate: las consultas útiles
- Búsqueda semántica —
articles.query.near_text(query="rescisión de contrato", limit=5)requiere un vectorizer; si no, usenear_vectorcon su propio embedding. - Búsqueda híbrida —
articles.query.hybrid(query="factura duplicada", alpha=0.5):alpha=1da una búsqueda puramente vectorial yalpha=0una búsqueda puramente BM25. - Solo palabras clave —
articles.query.bm25(query="RGPD")usa el índice invertido, útil para referencias, códigos de producto y nombres propios. - Filtros —
filters=Filter.by_property("idioma").equal("es"), importado desdeweaviate.classes.query, se combina con todas las consultas anteriores. - RAG integrado —
articles.generate.near_text(query=..., limit=3, grouped_task="Responde a partir de estos extractos")devuelve los objetos y la respuesta del LLM configurado. - GraphQL — el endpoint
/v1/graphqlsigue disponible para las herramientas que lo usan, con los operadoresnearText,hybridybm25.
Índice HNSW, flat o dynamic y dimensionamiento de memoria
Por defecto, cada colección usa un índice HNSW, rápido pero mantenido en memoria. La documentación de Weaviate da una regla práctica: prever aproximadamente el doble del tamaño bruto de los vectores. Un millón de vectores de 768 dimensiones en float32 pesan unos 3 GB, es decir, alrededor de 6 GB de RAM para el índice. El índice flat no guarda nada en memoria y conviene a colecciones pequeñas, en particular a los tenants de un SaaS. El índice dynamic empieza como flat y pasa a HNSW por encima de un umbral de objetos; requiere ASYNC_INDEXING=true. Para reducir la huella, active una cuantización: PQ (product quantization) comprime mucho tras una fase de entrenamiento con sus datos, BQ (binary quantization) reduce cada dimensión a un bit y conviene sobre todo a vectores de alta dimensión, SQ (scalar quantization) guarda cada dimensión en un byte. Fije también GOMEMLIMIT en torno al 80 % de la RAM asignada al contenedor para que el recolector de basura de Go actúe antes de que el kernel mate el proceso.
Copias de seguridad y actualizaciones
Añada ENABLE_MODULES=backup-filesystem y BACKUP_FILESYSTEM_PATH=/var/lib/weaviate/backups, y lance una copia con curl -X POST -H "Authorization: Bearer $CLAVE" -H "Content-Type: application/json" -d '{"id":"nightly-20261001"}' localhost:8080/v1/backups/filesystem. El estado se consulta en GET /v1/backups/filesystem/nightly-20261001 y la restauración pasa por POST /v1/backups/filesystem/nightly-20261001/restore. Una copia en el mismo disco no le protege de perder el VPS: copie la carpeta a otro lugar o use backup-s3 con BACKUP_S3_BUCKET hacia un almacenamiento de objetos compatible con S3. Para actualizar, lea las notas de migración de la versión de destino, haga una copia, cambie la etiqueta de la imagen y ejecute docker compose pull && docker compose up -d. Avance las versiones menores de una en una y nunca baje de versión sobre los mismos datos sin restaurar una copia.
No deje el puerto gRPC 50051 abierto a Internet: las aplicaciones del mismo VPS lo usan en local y un equipo remoto pasa por un túnel ssh -L 50051:localhost:50051 user@vps. El despliegue del Marketplace vincula este puerto a 127.0.0.1 y arranca con el acceso anónimo abierto para facilitar la primera toma de contacto: active la autenticación por clave API antes de importar datos. Dé a su aplicación una clave de solo lectura y reserve la clave de administración para importaciones y copias de seguridad.
Supervisar Weaviate
Active PROMETHEUS_MONITORING_ENABLED=true: Weaviate expone entonces sus métricas en el puerto 2112 (/metrics), para recogerlas con Prometheus y mostrarlas en Grafana. Vigile primero la memoria del proceso, la duración de las importaciones por lotes y el número de objetos por colección. Los endpoints /v1/.well-known/live y /v1/.well-known/ready sirven de sondas para un healthcheck de Docker o una herramienta como Uptime Kuma. A nivel de sistema, docker stats muestra el consumo instantáneo del contenedor y df -h la ocupación del volumen, que conviene seguir de cerca porque el paso a solo lectura lo provoca el disco y no la RAM. Por último, revise los registros con docker compose logs -f weaviate: los errores de módulo y los fallos de vectorización aparecen allí con el nombre del objeto afectado.
Solución de problemas: los errores más frecuentes
- Respuesta 401 en todas las peticiones — el acceso anónimo está desactivado y la petición no envía
Authorization: Bearer <clave>, o la clave no figura enAUTHENTICATION_APIKEY_ALLOWED_KEYS. - El cliente Python v4 no logra conectarse — también comprueba gRPC: el puerto
50051debe ser accesible desde el cliente, en local o por túnel SSH, ygrpc_portdebe coincidir. - Módulo no encontrado al crear una colección — el módulo no está cargado: revise
ENABLE_MODULES,ENABLE_API_BASED_MODULESy la lista que devuelve/v1/meta. - Contenedor que se reinicia con el código 137 — el kernel lo ha matado por falta de memoria: defina
GOMEMLIMIT, active una cuantización o amplíe la RAM del VPS. - Importaciones rechazadas en solo lectura — el disco ha superado
DISK_USE_READONLY_PERCENTAGE: libere espacio o amplíe el volumen y vuelva a poner los shards en escritura. - Errores de vectorización al importar — falta la clave API del proveedor (
X-OpenAI-Api-Keypasada en losheadersdel cliente) o el servidor Ollama no es accesible desde el contenedor de Weaviate.
Weaviate, Qdrant, pgvector o Milvus
Desplace la tabla
| Criterio | Weaviate | Qdrant | pgvector | Milvus |
|---|---|---|---|---|
| Naturaleza | Base vectorial en Go | Base vectorial en Rust | Extensión de PostgreSQL | Base vectorial distribuida |
| Vectorización integrada | Sí, módulos text2vec-* | No, embeddings aportados por el cliente | No, embeddings aportados por la aplicación | Principalmente en el cliente |
| API | REST, GraphQL, gRPC | REST, gRPC | SQL | gRPC, REST, SDK |
| Híbrido y filtros | BM25 + vector nativo, filtros | Filtros sobre payload, vectores dispersos | WHERE SQL, texto completo de PostgreSQL a combinar | Filtros escalares, BM25 en versiones recientes |
| Huella en un VPS | Media, un solo contenedor | Baja, un solo contenedor | La de su PostgreSQL | Mayor, etcd y MinIO en modo standalone |
| Compresión | PQ, BQ, SQ | Escalar, binaria, de producto | halfvec, bit | Varios índices cuantizados (IVF_PQ, IVF_SQ8…) |
| Licencia | BSD-3-Clause | Apache 2.0 | Licencia PostgreSQL | Apache 2.0 |
| Caso de uso típico | RAG todo en uno con vectorización integrada | Búsqueda vectorial frugal | Vectores junto a datos relacionales | Volúmenes muy grandes, despliegue en clúster |
Cuándo Weaviate es la elección adecuada
Weaviate se justifica cuando quiere que la base se encargue de la vectorización, la búsqueda híbrida y la generación, en lugar de ensamblarlas usted mismo en el código de la aplicación. Encaja bien en un asistente documental, una búsqueda de catálogo multilingüe o un SaaS que aísla a cada cliente en su propio tenant. Si ya calcula sus embeddings y busca la menor huella posible, Qdrant es más frugal. Si sus datos ya están en PostgreSQL y el volumen sigue siendo modesto, pgvector le ahorra un componente más. Milvus apunta a volúmenes distribuidos muy grandes, a costa de una infraestructura más pesada. En un VPS, empiece con un solo nodo, un índice HNSW, una clave API y copias diarias, y añada cuantización y multi-tenancy cuando las mediciones lo pidan. Para ir más allá, consulte nuestras guías sobre Qdrant, Ollama y Open WebUI, que completan Weaviate en una pila RAG autoalojada.
Despliegue Weaviate en su VPS
Solicite un VPS de ServOrbit y despliegue Weaviate en unos pocos clics desde el Marketplace — Ubuntu 24.04, Docker preinstalado, imagen semitechnologies/weaviate:1.27.2 lista para usar.