Qdrant Qdrant

Open-Source Vector Database

Qdrant - High-performance, massive-scale Vector Database and Vector Search Engine for the next generation of AI.

Some Dashboard Quickstart examples use incorrect endpoint URLs. Remove the dashboard/ path prefix when following the tutorial. See the reported issue.

Collections

Qdrant calls its independent vector stores collections, rather than databases. Collection configurations and aliases are discovered at backup time rather than maintained as a fixed inventory in this README.

Clients can access this instance through qdrant:6333. Open WebUI uses Chroma, not these collections.

Storage

  • Compose definition: qdrant.yaml.
  • Declared bind: ${DOCKER_VOLUMES}/qdrant/storage:/qdrant/storage.
  • Collections are stored under storage/collections/<collection-name>/.

References

Backup

Backup coverage

backup.yaml enables native full-storage snapshots of the single-node instance, including all collections and aliases. scripts/backup/db/qdrant.py discovers the inventory dynamically, with no collection allowlist; newly created collections are included automatically in the next successful export. It publishes private full.snapshot, inventory.json and checksum manifest under ${DB_BACKUP_ROOT}/ai-qdrant/<UTC run>/. The existing 00:05 export and 03:00 B2-gated seven-local-export retention jobs automatically include it. Kopia snapshots the database-export source at 01:15 and application volumes at 01:20. See the backup guide for shared scheduling, retention and snapshot-selection procedures.

python3 scripts/backup/run.py ai/qdrant --dry-run
python3 scripts/backup/run.py ai/qdrant
python3 scripts/backup/run.py ai/qdrant --verify-latest

The adapter gets the API key from the running container without logging it or placing it in command arguments. It requires cluster-disabled mode, records version/collection configurations/counts/aliases, checks native size/SHA-256, reads every nested tar payload without extraction, and rejects inventory drift during capture. It does not stop Qdrant or its clients. Full snapshots are not a transaction with external source documents; matching before/after counts do not prove that no same-count payload updates occurred.

Only the newly returned full snapshot and confirmed exporter-owned intermediates are removed; operator snapshots are preserved. v1.19.1 removes collection intermediates automatically. If a request is interrupted before returning an owned snapshot name, inspect server snapshot inventory before deleting anything; the adapter does not guess ownership of unrelated artifacts.

Recovery and post-restore check

Retrieve the native artifact, inventory and manifest from the same B2 root; verify hashes/structure before use. Restore into empty destination storage using the matching qdrant/qdrant:v1.19.1 image and startup command:

./qdrant --storage-snapshot /restore/full.snapshot

Mount the snapshot read-only at /restore/full.snapshot and empty destination storage at /qdrant/storage. Restore the original ignored API key and Compose settings separately; the native snapshot is not a copy of container credentials. Preserve client applications’ source documents, embedding/chunking settings and model assets separately if regeneration is required. Before switching clients, compare collections/configurations/counts/aliases with inventory.json, confirm each alias points to its expected collection, and test a representative retrieval. Use an isolated destination for a drill, never production storage.

name: qdrant
services:
  qdrant:
    image: qdrant/qdrant:v1.20.0@sha256:9bfc89f9914fc14876a88c05270685921a55b8877b254a98bcc1cc2f0a424cd2
    container_name: qdrant
    restart: unless-stopped
    healthcheck:
      # Based on: https://github.com/qdrant/qdrant/issues/4250
      # Better would be to use `/healthz`: https://qdrant.tech/documentation/guides/monitoring/#kubernetes-health-endpoints
      test:
        - CMD-SHELL
        - bash -c ':> /dev/tcp/127.0.0.1/6333' || exit 1
      interval: 30s
      timeout: 10s
      retries: 3
    volumes:
      - ${DOCKER_VOLUMES}/qdrant/storage:/qdrant/storage
    networks:
      - proxy
    environment:
      # Reference: https://github.com/qdrant/qdrant/blob/master/config/config.yaml
      QDRANT__LOG_LEVEL: INFO
      QDRANT__SERVICE__API_KEY: ${QDRANT_API_KEY:-""}
      QDRANT__SERVICE__ENABLE_CORS: false # TODO how do restrict to https://qdrant.${MYDOMAIN} ?
    labels:
      traefik.enable: true
      traefik.http.routers.qdrant.middlewares: localaccess@file
      traefik.http.services.qdrant.loadbalancer.server.port: 6333
      homepage.group: AI
      homepage.name: "Qdrant"
      homepage.icon: chatgpt.png
      homepage.href: https://qdrant.${MYDOMAIN}/dashboard/
      homepage.description: "Open-Source Vector Database"

networks:
  proxy:
    external: true