Deployment guide

Qdrant

Overview

Qdrant is a high-performance, open-source vector similarity search engine and vector database, written in Rust for speed and reliability under heavy load. It stores points made of a vector and a JSON payload, indexes them with HNSW, and answers nearest-neighbour, filtered and hybrid search queries in milliseconds through a REST and gRPC API.

Qdrant ships a built-in web dashboard for browsing collections, running interactive API requests and exploring search results. It is a strong foundation for semantic search, recommendations, retrieval-augmented generation and anomaly detection.

The SecureAnyCloud image installs the official prebuilt Qdrant server binary at /opt/qdrant/bin/qdrant. It runs as the qdrant service, bound to loopback 127.0.0.1:6333 (REST and dashboard) and 127.0.0.1:6335 (gRPC), behind nginx, which terminates TLS. nginx serves the REST API and dashboard on port 443 and reverse proxies gRPC over TLS on port 6334, so the API key never crosses the wire in plaintext.

Secure by default, no open API: Qdrant serves an open, unauthenticated API when no key is set. This image never ships that. A qdrant-firstboot.service oneshot generates a unique API key on each VM's first boot and writes it to a root-only file and the service environment. It also regenerates a per-VM TLS certificate, resolves the instance URL, writes a root-only info note, and then disables itself.

The qdrant service requires the first-boot unit, so it can never start open before a key is set. No two VMs share a key, and none is baked into the image.

Dedicated data disk: vector data (the storage and snapshots directories) lives on a dedicated data disk mounted at /var/lib/qdrant, captured into the image so every VM is provisioned with it. The server binary and dashboard assets stay on the OS disk.

What you get:

  • Qdrant (verified at 1.18.3) as the official prebuilt Rust server binary
  • The built-in Qdrant web dashboard, served over TLS
  • qdrant.service bound to loopback 127.0.0.1:6333 (REST + dashboard) and 127.0.0.1:6335 (gRPC)
  • nginx terminating TLS: REST + dashboard on 443, gRPC on 6334, and 80 redirecting to HTTPS
  • qdrant-firstboot.service for the first-boot API key, per-VM TLS certificate and info note
  • A unique per-VM API key generated on first boot, in a root-only 0600 file
  • A dedicated data disk mounted at /var/lib/qdrant for storage and snapshots
  • Ubuntu 24.04 LTS base, patched at build time
  • 24/7 SecureAnyCloud support, 24h response SLA

Prerequisites

Before you deploy this image, you need an active Azure subscription, an SSH key pair, and a VNet with a subnet.

Qdrant performance and index capacity scale with memory. The recommended VM size is Standard_B2s (2 vCPU, 4 GB RAM) for evaluation and small collections, or Standard_D4s_v5 or larger for production workloads with millions of vectors. The dedicated data disk holds your collections, so resize it to suit your dataset.

1

Deploy from the Azure Portal

Search the Marketplace for Qdrant on Ubuntu 24.04 and choose your VM size. Attach an NSG that allows TCP 22 (SSH) from your management network. The NSG must also allow TCP 443 (REST + dashboard) and 6334 (gRPC) from the networks and applications that need to query Qdrant. Port 80 only issues an HTTPS redirect.

2

Deploy from the Azure CLI

RG="qdrant-prod"; LOCATION="eastus"; VM_NAME="qdrant-01" IMAGE_URN="sac1647283583153:qdrant-ubuntu-24-04:default:latest" SSH_KEY="$(cat ~/.ssh/id_rsa.pub)" az group create --name "$RG" --location "$LOCATION" az network vnet create -g "$RG" --name qdrant-vnet --address-prefix 10.90.0.0/16 --subnet-name qdrant-subnet --subnet-prefix 10.90.1.0/24 az network nsg create -g "$RG" --name qdrant-nsg az network nsg rule create -g "$RG" --nsg-name qdrant-nsg --name allow-ssh --priority 100 \
  --source-address-prefixes "<your-mgmt-cidr>" --destination-port-ranges 22 --access Allow --protocol Tcp az network nsg rule create -g "$RG" --nsg-name qdrant-nsg --name allow-api --priority 110 \
  --source-address-prefixes "<your-mgmt-cidr>" --destination-port-ranges 443 6334 --access Allow --protocol Tcp
# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:qdrant-ubuntu-24-04:default:latest
az vm create -g "$RG" --name "$VM_NAME" --image "$IMAGE_URN" \
  --size Standard_B2s --storage-sku StandardSSD_LRS \
  --admin-username azureuser --ssh-key-values "$SSH_KEY" \
  --vnet-name qdrant-vnet --subnet qdrant-subnet --nsg qdrant-nsg --public-ip-sku Standard
3

Connect via SSH

ssh azureuser@<vm-ip>
4

Verify the services are running

Qdrant listens on loopback 127.0.0.1:6333 (REST + dashboard) and 127.0.0.1:6335 (gRPC); nginx fronts them with TLS on ports 443 and 6334. The health endpoint is public. The data API requires your key.

sudo systemctl is-active qdrant nginx ss -tln | grep -E '127.0.0.1:6333|:443 ' curl -ks https://127.0.0.1/healthz cat /opt/qdrant/VERSION

You should see both services active, the listening sockets, healthz check passed, and the installed Qdrant version.

The built-in dashboard is served over TLS at https://<your-vm-ip>/dashboard. The certificate is self-signed per VM, so your browser warns on the first visit. Accept the exception, or trust /etc/nginx/tls/qdrant.crt, to reach the dashboard.

5

Read your per-VM API key and confirm auth is enforced

The API key was generated on this VM's first boot and stored in a root-only file. Read it and keep it secret, because it authenticates every data request. Confirm that unauthenticated and wrong-key requests are rejected while the correct key is accepted.

sudo cat /root/qdrant-info.txt echo "no key -> HTTP $(curl -ks -o /dev/null -w '%{http_code}' https://127.0.0.1/collections)" echo "wrong key -> HTTP $(curl -ks -o /dev/null -w '%{http_code}' -H 'api-key: wrong' https://127.0.0.1/collections)"
QDRANT_KEY=$(sudo grep '^QDRANT_API_KEY=' /root/qdrant-info.txt | cut -d= -f2-)
echo "correct key -> HTTP $(curl -ks -o /dev/null -w '%{http_code}' -H "api-key: $QDRANT_KEY" https://127.0.0.1/collections)"

The info note holds QDRANT_API_KEY and the instance URLs. It is owned by root:root with mode 0600. Unauthenticated and wrong-key calls return 401. Only the per-VM key returns 200.

6

Create a collection and run your first vector search

Load the API key into a shell variable, create a movies collection with 4-dimensional cosine vectors, upsert a few points with payloads, and then run a nearest-neighbour search. Use wait=true so the upsert is indexed before you search.

QDRANT_KEY=$(sudo grep '^QDRANT_API_KEY=' /root/qdrant-info.txt | cut -d= -f2-) H="api-key: $QDRANT_KEY" curl -ks -X PUT https://127.0.0.1/collections/movies -H "$H" -H 'Content-Type: application/json' \
  --data '{"vectors":{"size":4,"distance":"Cosine"}}' | jq -r '.status' curl -ks -X PUT 'https://127.0.0.1/collections/movies/points?wait=true' -H "$H" -H 'Content-Type: application/json' \
  --data '{"points":[ {"id":1,"vector":[0.9,0.1,0.1,0.1],"payload":{"title":"Interstellar","genre":"scifi"}}, {"id":2,"vector":[0.1,0.9,0.1,0.1],"payload":{"title":"Inception","genre":"scifi"}}, {"id":3,"vector":[0.1,0.1,0.9,0.1],"payload":{"title":"The Matrix","genre":"scifi"}}, {"id":4,"vector":[0.1,0.1,0.1,0.9],"payload":{"title":"Dune","genre":"scifi"}} ]}' | jq -r '.status' curl -ks -X POST https://127.0.0.1/collections/movies/points/search -H "$H" -H 'Content-Type: application/json' \
  --data '{"vector":[0.85,0.15,0.1,0.1],"limit":3,"with_payload":true}' \
  | jq -r '.result[] | "\(.payload.title) score=\(.score)"'

The search returns the nearest points to your query vector, each with its cosine similarity score and payload, in a fraction of a millisecond.

The dashboard shows every collection and its status.

7

Filter by payload

Add a payload index so you can filter searches by metadata, and then combine vector similarity with a payload filter. This search returns the nearest scifi titles only.

QDRANT_KEY=$(sudo grep '^QDRANT_API_KEY=' /root/qdrant-info.txt | cut -d= -f2-) H="api-key: $QDRANT_KEY" curl -ks -X PUT https://127.0.0.1/collections/movies/index -H "$H" -H 'Content-Type: application/json' \
  --data '{"field_name":"genre","field_schema":"keyword"}' | jq -r '.status' curl -ks -X POST https://127.0.0.1/collections/movies/points/search -H "$H" -H 'Content-Type: application/json' \
  --data '{"vector":[0.2,0.1,0.9,0.7],"filter":{"must":[{"key":"genre","match":{"value":"scifi"}}]},"limit":4,"with_payload":true}' \
  | jq -r '.result[] | "\(.payload.title) score=\(.score)"'

You can run the same requests from the dashboard's built-in Console, which shows the request and the live scored results side by side.

8

Explore collections in the dashboard

Open a collection in the dashboard to browse its points, inspect payloads and vectors, run "find similar" from any point, and visualise the vector space. This is the fastest way to check your data.

9

Snapshots for backup and restore

Qdrant can snapshot a collection to the snapshots directory on the data disk. You can download the snapshot and restore it elsewhere.

QDRANT_KEY=$(sudo grep '^QDRANT_API_KEY=' /root/qdrant-info.txt | cut -d= -f2-) H="api-key: $QDRANT_KEY" curl -ks -X POST https://127.0.0.1/collections/movies/snapshots -H "$H" | jq -r '.result.name' curl -ks https://127.0.0.1/collections/movies/snapshots -H "$H" | jq -r '.result[].name'

Snapshots are written under /var/lib/qdrant/snapshots on the dedicated data disk.

10

Enable a real TLS certificate

The appliance ships with a self-signed certificate generated per VM. For production, point a DNS record at the VM and replace it with a CA-signed certificate. You can obtain one with certbot and place it in the nginx TLS paths.

sudo apt-get update && sudo apt-get install -y certbot
sudo certbot certonly --standalone -d your-domain.example.com
sudo cp /etc/letsencrypt/live/your-domain.example.com/fullchain.pem /etc/nginx/tls/qdrant.crt
sudo cp /etc/letsencrypt/live/your-domain.example.com/privkey.pem /etc/nginx/tls/qdrant.key
sudo systemctl reload nginx

Clients can then verify the certificate normally instead of using -k.

Persistence, first boot and updates

Vector data lives on the dedicated data disk mounted at /var/lib/qdrant (the storage and snapshots directories) and is captured into the image, so a VM launched from this image is ready immediately.

The first-boot service generates the per-VM API key, regenerates the per-VM TLS certificate and writes a root-only info note. It then disables itself, so subsequent reboots are unaffected. The OS is patched at build time and ships with unattended security upgrades enabled.

Support

Every SecureAnyCloud deployment includes 24/7 support with a 24 hour response SLA. Contact sales@secureanycloud.com for help with deployment, configuration or scaling.

This is a repackaged open-source software product with additional charges for SecureAnyCloud support services. Qdrant is a trademark of its respective owner. All product and company names are trademarks or registered trademarks of their respective holders. Use of them does not imply any affiliation with or endorsement by them.

Deploy on Azure

Launch Qdrant on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.

View this image

Need Help?

Our support team is available 24/7.

sales@secureanycloud.com

Deploy on Azure