Most “open source vector database” write-ups bury you in architecture slides before you ever get a listening port. That’s backwards. If you can’t deploy it tonight, the feature list doesn’t matter. Here’s how to stand up Milvus 3.0.0 – the current open source vector database release as of the July 29, 2026 cut – with the exact commands, floors, and traps that actually break first-time installs.
Milvus is the path when Lite’s single-file mode is too small and a managed cloud bill isn’t on the table yet. v3.0.0 also ships a sparse-index rewrite built around algorithms like SINDI (see the release notes). You’re still installing a server. Treat it like one.
System requirements before you pull images
Per the official hardware checklist (as of that doc set for the 3.0 line), standalone isn’t a laptop toy if you plan real inserts:
| Resource | Minimum | Recommended |
|---|---|---|
| CPU | Intel 2nd Gen Core+ or Apple Silicon; SIMD (SSE4.2 / AVX / AVX2 / AVX-512) | 4+ cores standalone |
| RAM | 8 GB | 16 GB standalone |
| Disk | SATA 3.0 SSD+ | NVMe; etcd wants strong fsync |
| OS / runtime | Linux + Docker 19.03+ / Compose 1.25.1+; macOS 10.14+ Docker Desktop; Windows + WSL2 + Docker Desktop | Compose V2; macOS VM ≥2 vCPU / 8 GB RAM |
etcd is picky about disk. Those same prerequisites suggest testing with fio and aiming for over 500 IOPS and under 10 ms p99 fsync on the volume that holds etcd data. Slow spinning disks don’t just feel slow – they trigger leadership churn that looks like random flakiness.
On macOS, if Docker Desktop still has the default 2 GB memory slider, the install often fails before Milvus ever becomes healthy. Bump it first. That’s the difference between “container created” and “healthy.”
Download sources for Milvus 3.0.0
Use only official artifacts:
- Release and Compose file: github.com/milvus-io/milvus/releases/tag/v3.0.0
- Image tag you’ll see in practice:
milvusdb/milvus:v3.0.0(Docker Hub under milvusdb/milvus) - Embed script (single-container path):
https://raw.githubusercontent.com/milvus-io/milvus/master/scripts/standalone_embed.sh - Compose YAML pin:
https://github.com/milvus-io/milvus/releases/download/v3.0.0/milvus-standalone-docker-compose.yml
I use Compose for anything that lives past a weekend – separate etcd/MinIO volumes, clearer backup story. The embed script wins when you want one container and fewer moving parts. Different ops shape, same image family.
Install open source vector database: Docker Compose (recommended)
From an empty working directory on Linux (or WSL2):
# Pull the v3.0.0 standalone Compose file
wget https://github.com/milvus-io/milvus/releases/download/v3.0.0/milvus-standalone-docker-compose.yml -O docker-compose.yml
# Start etcd + MinIO + milvus-standalone
sudo docker compose up -d
# Confirm health
docker compose ps
You should see three services: milvus-etcd, milvus-minio, milvus-standalone, all healthy. Standalone publishes 19530 (client gRPC) and 9091 (metrics / WebUI). Data lands under ./volumes/{etcd,minio,milvus} in the current folder – details in the Compose install guide.
Default message queue in this v3.0.0 stack is Woodpecker (embedded) with MinIO as the WAL backend – no Pulsar or Kafka container required. People skip this when they paste a 2024 blog’s YAML and still expect RocksMQ-era layout.
Alternative: single-container embed script
curl -sfL https://raw.githubusercontent.com/milvus-io/milvus/master/scripts/standalone_embed.sh -o standalone_embed.sh
bash standalone_embed.sh start
That script runs milvusdb/milvus:v3.0.0 as milvus-standalone, embeds etcd, maps 19530/9091/2379, and health-checks with curl -f http://localhost:9091/healthz. Woodpecker here uses the local filesystem as WAL, not MinIO. Persistence and backup look nothing like the three-container Compose layout – plan dumps accordingly.
Pro tip: Always re-download the embed script or the versioned Compose file for the release you want. Stale YAML is how people “install 3.0” and silently run a 2.x image for a week.
First-time configuration (minimum viable)
Out of the box you’re listening. Two knobs worth knowing on day one:
Compose path – override inside the container
docker exec -it milvus-standalone bash
cat << EOF > /milvus/configs/user.yaml
# Extra config to override default milvus.yaml
proxy:
healthCheckTimeout: 1000
EOF
exit
docker restart milvus-standalone
Embed script path – local user.yaml next to the script
cat << EOF > user.yaml
proxy:
healthCheckTimeout: 1000
EOF
bash standalone_embed.sh restart
Leave Storage V3 alone until you need Snapshots or TEXT LOB features. v3.0.0 release notes are blunt: Storage V3 is off by default, and once you enable format-changing features, rolling back to 2.6 is off the table.
That’s a one-way door. Walk through it on purpose – not because a tutorial flipped a flag “for performance.”
Verify the install works
Three checks, in order:
# 1) Process health
docker compose ps
# or: docker ps --filter name=milvus
# 2) HTTP healthz (expect OK)
curl -s http://127.0.0.1:9091/healthz
# 3) WebUI loads
# open http://127.0.0.1:9091/webui/
Then hit it from Python. PyMilvus 3.0.1 is the SDK matched to server 3.0.0; it wants Python 3.9+:
python3 -m pip install pymilvus==3.0.1
python3 - <<'PY'
from pymilvus import MilvusClient
client = MilvusClient(uri="http://localhost:19530", token="root:Milvus")
print(client.get_server_version())
client.create_collection(collection_name="install_smoke", dimension=8)
print("collections:", client.list_collections())
client.drop_collection("install_smoke")
print("ok")
PY
Version string prints and the collection round-trip succeeds? Install’s done. Schema and indexing are a different job.
Common install errors and fixes
bind: address already in useon 19530 or 2379 – Another Milvus (or random etcd) is already bound.docker ps -a | grep milvus, stop the old stack, or change host port mappings in Compose. Community threads hit this constantly when a background standalone was never deleted.- Containers exit / disconnect during bulk insert – Often host RAM or CPU pegged. GitHub reports show standalone dying under multi-million entity inserts when the machine is undersized. Raise Docker memory, lower insert batch size, watch
docker stats. - Compose V1 vs V2 – If
docker composefails weirdly, you may still have the olddocker-composebinary. Move to Compose V2; the install notes expect it. - Client can’t connect while
docker pslooks fine – Confirm healthz first. On Docker Desktop, preferlocalhostover brittle container IPs; Windows firewall has bitten people connecting Attu or pymilvus from the host. - macOS: never healthy – Re-check Docker VM CPUs/RAM (2 / 8 GB floor). Put bind mounts on the Linux filesystem side under WSL2 on Windows, not a slow
/mnt/cpath.
Boot problems: docker logs milvus-standalone (or the Compose service name) before you rewrite YAML. Most “Milvus is broken” tickets are port collisions or starved VMs.
Upgrade from 2.6.x and uninstall
Upgrade (Compose, validated path for 2.6.x → 3.0.0): back up Compose + volumes first. Keep etcd, MinIO, Woodpecker, and volume paths untouched. Change only the standalone image:
cp docker-compose.yml docker-compose-before-upgrade.yml
# edit services.standalone.image -> milvusdb/milvus:v3.0.0
docker compose pull standalone
docker compose up --detach standalone
docker compose ps
docker compose images standalone
docker compose logs --tail 100 standalone
You must keep the existing message-queue choice. Switching MQ mid-upgrade isn’t supported (as of the v3.0.0 standalone upgrade guide). RocksMQ holdouts coming from 2.5.x need mq.type: rocksmq pinned in user overrides before moving onto the 2.6/3.0 Woodpecker-default line. After 3.0 writes data, a casual image downgrade can fail to read state – plan recovery from backups, not from retagging.
Embed script upgrade:bash standalone_embed.sh upgrade re-pulls script + image and restarts while keeping mapped data (confirm interactively when prompted).
Uninstall / cleanup
# Compose
sudo docker compose down
sudo rm -rf volumes # destroys data
# Embed script
bash standalone_embed.sh stop
bash standalone_embed.sh delete
FAQ
Should I start with Milvus Lite or full standalone Docker?
Lite for notebooks. Standalone Docker when you need a real server port, multi-process clients, or connection code that still works when you grow past one laptop.
Why did my upgrade complain about the message queue?
Because MQ type can’t change during the jump – pin RocksMQ first if that’s what you run. Full steps are in the upgrade section above. Classic fail: months-old 2.5 Compose, drop in a 3.0 YAML, metadata looks drunk.
Is port 9091 safe to expose?
9091 serves healthz, metrics, and WebUI (WebUI docs). Don’t casually publish it on a public interface. Bind to localhost or put it behind your usual network controls; use 19530 for app traffic with auth configured when you leave the laptop.
Next action: empty directory → Compose wget + docker compose up -d → pymilvus smoke test. When get_server_version() returns a 3.0.x string, stop reading and load your first real collection.