Milvus: Install & Full Deployment

Standing up Milvus via Docker, then a full connect-to-query walkthrough — matching the deployment style of the MongoDB and MinIO docs.


This page covers standing up a Milvus server via Docker (for Milvus Lite, no server setup is needed — see 05- Milvus), then a full walkthrough from first connection through querying data back out.


Docker setup (Milvus standalone)

For a local Milvus server (not Lite), use a compose stack with etcd, MinIO, and Milvus standalone.

Example layout (tested on Apple Silicon; adjust platform for amd64 if needed):

Image tags below are current as of this doc’s writing — worth checking for newer releases before deploying.

# docker-compose.milvus.yml
services:
  etcd:
    image: quay.io/coreos/etcd:v3.5.5
    environment:
      - ETCD_AUTO_COMPACTION_MODE=revision
      - ETCD_AUTO_COMPACTION_RETENTION=1000
      - ETCD_QUOTA_BACKEND_BYTES=4294967296
      - ETCD_SNAPSHOT_COUNT=50000
    volumes:
      - etcd_data:/etcd
    command: etcd -advertise-client-urls=http://127.0.0.1:2379 -listen-client-urls http://0.0.0.0:2379 --data-dir /etcd

  minio:
    image: minio/minio:RELEASE.2023-03-20T20-16-18Z
    environment:
      MINIO_ACCESS_KEY: minioadmin
      MINIO_SECRET_KEY: minioadmin
    volumes:
      - minio_data:/minio_data
    command: minio server /minio_data --console-address ":9001"

  milvus:
    image: milvusdb/milvus:v2.4.15
    command: ["milvus", "run", "standalone"]
    environment:
      ETCD_ENDPOINTS: etcd:2379
      MINIO_ADDRESS: minio:9000
    volumes:
      - milvus_data:/var/lib/milvus
    ports:
      - "19530:19530"
      - "9091:9091"
    depends_on:
      - etcd
      - minio

  attu:
    image: zilliz/attu:v2.4.12
    ports:
      # GUI — open http://MILVUS_HOST:3001 in a browser
      - "3001:3000"
    environment:
      # Attu runs inside Compose — use the Milvus *service name*, not MILVUS_HOST
      MILVUS_URL: milvus:19530
      MILVUS_USERNAME: root
      MILVUS_PASSWORD: YOUR_PASSWORD
    depends_on:
      - milvus

volumes:
  etcd_data:
  minio_data:
  milvus_data:

Start:

docker compose -f docker-compose.milvus.yml up -d
Endpoint URL
gRPC API http://MILVUS_HOST:19530
Attu (GUI) http://MILVUS_HOST:3001

Authentication

The Milvus standalone image enables authentication by default. Credentials (replace YOUR_PASSWORD — default install uses Milvus):

Field Value
Username root
Password YOUR_PASSWORD
Token root:YOUR_PASSWORD (username:password — pymilvus MilvusClient format)

Attu uses the same credentials (MILVUS_USERNAME / MILVUS_PASSWORD in the compose file above). If you change the Milvus password, update Attu and AnyLog to match.


Using Milvus Directly (outside AnyLog)

Everything above stands up a real, standalone Milvus instance — AnyLog is just one client talking to it over gRPC. The same instance is fully usable on its own, which is useful for inspecting data AnyLog has written, running ad-hoc searches without going through vector commands, or handing the same collection to a data science workflow that has nothing to do with AnyLog.

Attu (the GUI)

Attu is Milvus’s own official admin console (by Zilliz), already running in the compose stack above at http://MILVUS_HOST:3001. Once logged in (same root/YOUR_PASSWORD credentials as AnyLog), it lets you:

  • Browse collections — schema, index type, row count, and load status, without writing a query
  • Preview data — page through actual rows/vectors in a collection
  • Run vector search interactively — paste in a query vector (or use Attu’s built-in embedding for text, if configured) and see nearest neighbors, without touching the CLI
  • Manage indexes — create/drop/rebuild an index on a field, and switch metric type, outside of vector create
  • View collection load state — Milvus collections must be “loaded” into memory before they’re searchable; Attu shows this state directly, which is useful for catching a collection that exists but isn’t actually queryable yet

This is often the fastest way to sanity-check that data AnyLog inserted actually looks right, before debugging further on the AnyLog side.

pymilvus (direct SDK access)

Since AnyLog is just a pymilvus client itself, you can connect to the exact same instance directly from Python, independent of any AnyLog node:

from pymilvus import MilvusClient

client = MilvusClient(uri="http://MILVUS_HOST:19530", token="root:YOUR_PASSWORD")

# list collections AnyLog has created
print(client.list_collections())

# inspect a collection's schema directly
print(client.describe_collection("sensors"))

# query rows without going through AnyLog at all
results = client.query(collection_name="sensors", filter="subject == 'security'", output_fields=["id", "text", "subject"])
print(results)

This is the same client library milvus_dbms.py uses under the hood — nothing AnyLog-specific about the connection itself, just a different consumer of the same data.

Metrics endpoint

Port 9091 (already exposed in the compose file above) is Milvus’s own Prometheus-compatible metrics endpoint — independent of anything AnyLog reports via get processes/get streaming. Point a Prometheus/Grafana stack at http://MILVUS_HOST:9091/metrics for Milvus-level operational metrics (query latency, memory usage, index build time) if you’re monitoring Milvus as its own service rather than just through AnyLog’s lens.

Standalone vs. cluster mode, and backup

Everything in this doc deploys Milvus standalone (one node, backed by etcd + MinIO for metadata/object storage) — adequate for development and moderate production load. Milvus also supports a distributed cluster mode for horizontal scaling, which is a Milvus-level concern entirely separate from AnyLog’s own operator/cluster model. AnyLog does not replicate across multiple Milvus instances itself). If you outgrow standalone, that’s a Milvus deployment decision to make independent of AnyLog, following Zilliz’s own cluster deployment guidance.

For backup, since standalone Milvus stores its metadata in etcd and its actual vector/object data in MinIO (both visible as their own services in the compose file above), backing up the etcd_data and minio_data volumes covers the underlying state. Zilliz also publishes a dedicated milvus-backup tool for logical collection-level backup/restore, which is generally the more reliable option over raw volume snapshots.


Offline model setup

The text-embedding model (see 05- Milvus) needs internet access once to download. For an offline node, download it on a build machine and ship the cache over:

# build machine
export HF_HOME=/tmp/anylog-model-cache && mkdir -p "$HF_HOME"
python3 -c "from pymilvus import model; fn = model.DefaultEmbeddingFunction(); fn.encode_documents(['warmup']); fn.encode_queries(['warmup'])"
tar -C "$HF_HOME" -czf milvus-embedding-model.tgz hub

# target host (Docker default path)
mkdir -p /app/.anylog-model-cache
tar -xzf milvus-embedding-model.tgz -C /app/.anylog-model-cache
export HF_HOME=/app/.anylog-model-cache
export HF_HUB_OFFLINE=1    # optional

Full Deployment Walkthrough

Set MILVUS_HOST to the machine running the compose stack (localhost on the same machine, or the host IP from a remote client) before starting.

  1. Bring up the Milvus stack (see Docker setup above)
    docker compose -f docker-compose.milvus.yml up -d
    
  2. Connect AnyLog to Milvus
    connect dbms vectors where type = milvus and uri = http://MILVUS_HOST:19530 and token = root:YOUR_PASSWORD and dimension = 768
    

    Verify:

    get databases
    
  3. Create a collection
    vector create where dbms = vectors and collection = sensors and metric_type = COSINE
    

    Verify:

    vector list where dbms = vectors
    
  4. Insert data
    vector insert where dbms = vectors and collection = sensors and text = "door open" and subject = "security"
    vector insert where dbms = vectors and collection = sensors and text = "temperature high" and subject = "process"
    
  5. Query data — semantic search
    vector search where dbms = vectors and collection = sensors and query = "door open" and limit = 5
    

    See Query Data for what the result looks like and how to interpret the similarity score.

  6. Query across the network (if the collection is hosted on multiple operators)
    run client () vector search where dbms = vectors and collection = sensors and query = "door open" and limit = 5
    
  7. Tear down
    disconnect dbms vectors
    
    docker compose -f docker-compose.milvus.yml down
    

Quickstart (Milvus Lite, no Docker/server needed)

If you don’t need a full server deployment, the same flow works entirely locally against a Milvus Lite file:

connect dbms vectors where type = milvus and path = !data_dir/milvus_demo.db and dimension = 768

vector create where dbms = vectors and collection = sensors and metric_type = COSINE

vector insert where dbms = vectors and collection = sensors and text = "door open" and subject = "security"
vector insert where dbms = vectors and collection = sensors and text = "temperature high" and subject = "process"

vector search where dbms = vectors and collection = sensors and query = "door open" and limit = 5

vector query where dbms = vectors and collection = sensors and filter = "subject == 'security'"

get databases

Text embedding example (HISTORY_DOCS)

Three separate sentences (as in the Milvus quickstart) need three vector insert commands — one row per text value:

vector insert where dbms = vectors and collection = history and text = "Artificial intelligence was founded as an academic discipline in 1956." and subject = "history"

vector insert where dbms = vectors and collection = history and text = "Alan Turing was the first person to conduct substantial research in AI." and subject = "history"

vector insert where dbms = vectors and collection = history and text = "Born in Maida Vale, London, Turing was raised in southern England." and subject = "history"

vector search where dbms = vectors and collection = history and query = "Who worked on early artificial intelligence?" and limit = 3

If all sentences are in one text string (commas do not split documents):

vector insert where dbms = vectors and collection = history and text = "Artificial intelligence was founded as an academic discipline in 1956., Alan Turing was the first person to conduct substantial research in AI., Born in Maida Vale, London, Turing was raised in southern England." and subject = "history"
Step What happens
Processed by pymilvus DefaultEmbeddingFunction (encode_documents) — ONNX model GPTCache/paraphrase-albert-onnx (~768 dimensions)
Inserted by vector insertmilvus_dbms.py → Milvus insertone entity, one vector for the full string

Search embeds the query the same way (encode_queries) via vector search ... query = "...".

For bulk load from a file (many rows), use the standalone scripts under [path to milvus scripts]/milvusdb (milvus_prepare_data.pymilvus_insert_data.py).


Troubleshooting

Milvus library not installed

pip install "pymilvus[milvus_lite,model]>=3.0.0" "transformers>=4.36,<5" onnxruntime

For Nuitka: reinstall deps, then rebuild ./build/nuitka_core.sh.

Collection exists without auto_id

Recreate:

vector create where dbms = vectors and collection = sensors and drop = true

Embedding model unavailable (offline)

Provide explicit vectors instead of text / query:

vector insert where dbms = vectors and collection = sensors and vector = [0.1,0.2,...] and text = "label only"

onnxruntime Unknown CPU vendor warning

Harmless on some CPUs / Docker (especially Apple Silicon). Embedding still works if the command completes.

Suppress gRPC stderr (optional)

export GRPC_VERBOSITY=NONE
export GLOG_minloglevel=3

  • 05- Milvus — concepts, connection reference, and the full vector command set