Cómo desplegar Qdrant con Docker y comprobar una búsqueda vectorial

Qdrant es una base de datos vectorial: almacena vectores y metadatos, y permite recuperar los puntos más similares a una consulta. En el flujo básico de esta guía, Qdrant no convierte texto en vectores. La aplicación debe generar esos embeddings mediante un modelo externo y enviar vectores cuya dimensión coincida con la colección.

En este procedimiento desplegarás Qdrant 1.19.0 con Docker Compose en un Cloud Server con Ubuntu. Habilitarás una clave de API, limitarás el servicio a localhost, crearás una colección de prueba, insertarás tres puntos y ejecutarás una consulta de similitud. Finalmente, reiniciarás el contenedor para comprobar la persistencia y crearás un snapshot descargable.

Versión revisada: Qdrant 1.19.0, 31 de agosto de 2026. Los comandos se contrastaron con la documentación oficial.

Alcance: el ejemplo implementa una instancia autogestionada de un solo nodo. Es apropiada para aprendizaje, integración y cargas que toleren una interrupción, pero no proporciona alta disponibilidad.

Cómo funciona la búsqueda vectorial con Qdrant

El recorrido real tiene cuatro etapas:

  1. La aplicación recibe una consulta, por ejemplo, cómo desplegar contenedores.
  2. Un modelo de embeddings externo transforma el texto en un vector numérico.
  3. Qdrant compara ese vector con los almacenados mediante una métrica como coseno.
  4. Qdrant devuelve los puntos más cercanos, ordenados por puntuación, junto con su payload.

Qdrant no necesita una GPU para esta demostración. La GPU es una opción avanzada para acelerar determinadas tareas de indexación, no un requisito del despliegue básico.

Requisitos previos

  • Cloud Server con Ubuntu 22.04 o 24.04, acceso SSH y usuario con sudo.
  • Docker Engine y el complemento Docker Compose instalados.
  • curl y openssl.
  • Espacio persistente suficiente en disco.
  • Puerto TCP 6333 libre en el host.
  • Para datos reales: modelo de embeddings elegido, dimensión de salida conocida y métrica de distancia definida.
  • Backup previo si el servidor contiene datos que no pueden perderse.

Comprueba el estado inicial:

uname -m
docker --version
docker compose version
free -h
df -h /
ss -ltn | awk '$4 ~ /:6333$/'

Si el último comando muestra un proceso escuchando en 6333, identifica su función antes de continuar.

1. Preparar el directorio y la clave de API

Crea un directorio restringido y genera una clave aleatoria:

install -d -m 700 ~/qdrant-deploy
cd ~/qdrant-deploy
umask 077
printf 'QDRANT_API_KEY=%s\n' "$(openssl rand -hex 32)" > .env
chmod 600 .env

Comprueba los permisos sin imprimir el secreto:

stat -c '%a %U:%G %n' . .env

El archivo .env debe mostrar permisos 600. No lo subas a un repositorio ni lo incluyas en capturas.

2. Configurar Qdrant con Docker Compose

Crea ~/qdrant-deploy/compose.yaml:

services:
  qdrant:
    image: qdrant/qdrant:v1.19.0
    container_name: qdrant
    restart: unless-stopped
    ports:
      - "127.0.0.1:6333:6333"
    environment:
      QDRANT__SERVICE__API_KEY: "${QDRANT_API_KEY}"
    volumes:
      - qdrant_storage:/qdrant/storage
      - qdrant_snapshots:/qdrant/snapshots

volumes:
  qdrant_storage:
  qdrant_snapshots:

La publicación 127.0.0.1:6333:6333 limita la API REST y el panel web al propio servidor.

El ejemplo no publica:

  • 6334, utilizado por la API gRPC.
  • 6335, utilizado para la comunicación entre nodos distribuidos.

La versión se fija para evitar actualizaciones implícitas. Antes de cambiarla, revisa las notas de lanzamiento y crea un snapshot.

3. Validar y arrancar Qdrant

Valida la sintaxis sin imprimir la configuración resuelta, que contiene la clave:

cd ~/qdrant-deploy
docker compose config -q
docker compose pull
docker compose up -d
docker compose ps

docker compose config -q debe terminar sin salida y con código 0. El contenedor debe aparecer en ejecución.

Comprueba la salud y revisa los registros:

curl -fsS http://127.0.0.1:6333/healthz
docker compose logs --tail=100 qdrant

La primera orden debe devolver:

healthz check passed

Los endpoints de salud pueden responder sin clave. Esto no significa que las colecciones estén desprotegidas.

Comprueba que una petición sin credenciales no pueda listar colecciones:

curl -sS -o /dev/null -w '%{http_code}\n' \
  http://127.0.0.1:6333/collections

La respuesta no debe ser 200.

Carga la clave para la sesión actual y repite la petición:

set -a
. ./.env
set +a

curl -fsS \
  -H "api-key: ${QDRANT_API_KEY}" \
  http://127.0.0.1:6333/collections

La respuesta esperada contiene "status":"ok" y una lista de colecciones inicialmente vacía.

Acceso remoto seguro

Para una prueba administrativa puedes abrir un túnel SSH desde tu equipo:

ssh -L 6333:127.0.0.1:6333 usuario@TU_IP

Para una aplicación en producción, utiliza una red privada o un proxy inverso con TLS. No cambies el binding a 0.0.0.0 ni abras el firewall sin autenticación, cifrado y restricciones de origen: las instalaciones autogestionadas de Qdrant no son seguras por defecto.

4. Crear una colección

Esta demostración utiliza vectores de cuatro dimensiones para que los datos sean legibles:

curl -fsS -X PUT \
  -H "api-key: ${QDRANT_API_KEY}" \
  -H 'Content-Type: application/json' \
  http://127.0.0.1:6333/collections/documentos-demo \
  -d '{
    "vectors": {
      "size": 4,
      "distance": "Cosine"
    }
  }'

La respuesta debe incluir "status":"ok" y "result":true.

Comprueba la colección:

curl -fsS \
  -H "api-key: ${QDRANT_API_KEY}" \
  http://127.0.0.1:6333/collections/documentos-demo

En una implementación real, size debe coincidir exactamente con la dimensión de salida del modelo de embeddings.

5. Insertar vectores y metadatos

Inserta tres puntos. wait=true hace que la API espere a que la operación se aplique:

curl -fsS -X PUT \
  -H "api-key: ${QDRANT_API_KEY}" \
  -H 'Content-Type: application/json' \
  'http://127.0.0.1:6333/collections/documentos-demo/points?wait=true' \
  -d '{
    "points": [
      {
        "id": 1,
        "vector": [0.90, 0.10, 0.10, 0.00],
        "payload": {
          "titulo": "Administrar Linux",
          "categoria": "sistemas"
        }
      },
      {
        "id": 2,
        "vector": [0.85, 0.15, 0.10, 0.00],
        "payload": {
          "titulo": "Desplegar con Docker",
          "categoria": "contenedores"
        }
      },
      {
        "id": 3,
        "vector": [0.10, 0.10, 0.90, 0.00],
        "payload": {
          "titulo": "Configurar correo",
          "categoria": "email"
        }
      }
    ]
  }'

La respuesta debe indicar "status":"completed".

Qdrant realiza un upsert: si envías nuevamente un punto con el mismo ID, reemplazará sus datos. Revisa los identificadores antes de cargar información en una colección existente.

6. Ejecutar una búsqueda vectorial

Consulta los dos puntos más próximos al vector [0.88, 0.12, 0.10, 0.00]:

curl -fsS -X POST \
  -H "api-key: ${QDRANT_API_KEY}" \
  -H 'Content-Type: application/json' \
  http://127.0.0.1:6333/collections/documentos-demo/points/query \
  -d '{
    "query": [0.88, 0.12, 0.10, 0.00],
    "limit": 2,
    "with_payload": true
  }'

La respuesta debe incluir dos elementos en result.points, con id, score y payload.

Los documentos sobre Linux y Docker deben aparecer por encima del documento de correo. Sus vectores son más próximos al vector consultado.

Esta prueba confirma el recorrido de la API, no la calidad semántica. Para evaluar una aplicación real, genera documentos y consultas con el mismo modelo de embeddings y mide la relevancia con casos representativos.

7. Comprobar la persistencia

Si abriste una nueva sesión SSH, vuelve a cargar el entorno:

cd ~/qdrant-deploy
set -a
. ./.env
set +a

Reinicia Qdrant y espera hasta 60 segundos:

docker compose restart qdrant

for intento in $(seq 1 30); do
  if curl -fsS http://127.0.0.1:6333/readyz >/dev/null; then
    break
  fi

  if [ "$intento" -eq 30 ]; then
    docker compose ps
    docker compose logs --tail=100 qdrant
    exit 1
  fi

  sleep 2
done

Comprueba que la colección sigue presente:

curl -fsS \
  -H "api-key: ${QDRANT_API_KEY}" \
  http://127.0.0.1:6333/collections/documentos-demo

Ejecuta nuevamente la consulta del paso anterior para validar también el resultado funcional.

Advertencia: no uses docker compose down -v salvo que quieras eliminar deliberadamente los volúmenes. docker compose down conserva los volúmenes nombrados; la opción -v los elimina junto con los datos.

8. Crear y descargar un snapshot

Crea un snapshot:

curl -fsS -X POST \
  -H "api-key: ${QDRANT_API_KEY}" \
  http://127.0.0.1:6333/collections/documentos-demo/snapshots

Lista los snapshots:

curl -fsS \
  -H "api-key: ${QDRANT_API_KEY}" \
  http://127.0.0.1:6333/collections/documentos-demo/snapshots

La respuesta de creación contiene result.name. Asigna ese valor, descarga el archivo y calcula su checksum:

SNAPSHOT_NAME='PEGA_AQUI_EL_VALOR_DE_RESULT_NAME'

curl -fsS \
  -H "api-key: ${QDRANT_API_KEY}" \
  -o "${SNAPSHOT_NAME}" \
  "http://127.0.0.1:6333/collections/documentos-demo/snapshots/${SNAPSHOT_NAME}"

test -s "${SNAPSHOT_NAME}" && sha256sum "${SNAPSHOT_NAME}"

Desde tu equipo, copia el archivo fuera del servidor:

scp usuario@TU_IP:/home/usuario/qdrant-deploy/PEGA_AQUI_EL_NOMBRE.snapshot ./
sha256sum PEGA_AQUI_EL_NOMBRE.snapshot

Los checksums deben coincidir.

Un snapshot almacenado únicamente en el mismo servidor no es una copia de seguridad suficiente. Conserva una copia externa con acceso restringido y ensaya la restauración en un entorno aislado.

La documentación actual de Qdrant indica que el destino de una restauración debe utilizar la misma versión menor o, como máximo, una versión menor posterior.

Problemas frecuentes

La API responde 401 o 403

Comprueba que cargaste .env y que utilizas el encabezado api-key:

test -n "${QDRANT_API_KEY:-}" \
  && echo 'Clave cargada' \
  || echo 'Clave no cargada'

docker compose config -q
docker compose logs --tail=100 qdrant

No ejecutes docker compose config sin -q en una sesión grabada: la configuración resuelta puede mostrar secretos.

Qdrant rechaza la dimensión del vector

La cantidad de valores no coincide con vectors.size.

No rellenes ni recortes vectores arbitrariamente. Utiliza el mismo modelo para documentos y consultas. Si cambias de modelo, planifica una colección nueva y una reindexación o migración.

Los datos desaparecen al recrear el servicio

Comprueba que el volumen existe:

docker volume ls | grep qdrant
docker compose config -q

Revisa si alguien ejecutó docker compose down -v o eliminó el volumen manualmente.

El puerto 6333 está ocupado

Identifica el proceso:

sudo ss -ltnp | grep ':6333'

Puedes cambiar únicamente el puerto del host:

ports:
  - "127.0.0.1:6336:6333"

En ese caso, adapta las URL de la guía para utilizar 6336.

Qdrant consume demasiada memoria o disco

Comprueba recursos y registros:

docker stats
docker compose logs --tail=100 qdrant
df -h

La capacidad depende de la cantidad y dimensión de vectores, el tipo de datos, los payloads, los índices y las réplicas. Ajusta recursos a partir de mediciones reales, sin imponer límites arbitrarios que puedan interrumpir las optimizaciones.

Buenas prácticas antes de producción

  • Mantén Qdrant en una interfaz privada o detrás de un proxy con TLS.
  • Utiliza una clave de solo lectura para aplicaciones que únicamente realizan consultas.
  • Fija versión o digest y crea un snapshot antes de actualizar.
  • Copia los backups fuera del host y prueba la restauración.
  • Supervisa /readyz, latencia, errores, CPU, memoria, disco y /metrics.
  • Crea índices de payload para los campos utilizados frecuentemente en filtros.
  • Evalúa relevancia, latencia y consumo mediante consultas reales versionadas.
  • Para alta disponibilidad, implementa nodos distribuidos, réplicas y balanceo.

Cloud Serversby Donweb

Todo el poder de la nube a tus proyectos y aplicaciones.
Alojamiento ultra rápido, escalable y con alta disponibilidad.

  • Performance que te sorprenderá
  • Rápida escalabilidad y sin limitaciones
  • Arquitectura de alta disponibilidad
  • Soporte experto y ejecutivos de cuenta
  • Pagos en tu moneda y facturación local

Descubre la mejor solución de Cloud Hosting