This guide provides a practical, executable single-node Milvus deployment workflow. It focuses on common pain points such as slow image pulls, invalid version tags, and inaccessible ports in WSL or virtual machines, then walks through Attu integration and pymilvus connectivity. Keywords: Milvus, Docker, vector database.
Technical Specifications at a Glance
| Parameter | Description |
|---|---|
| Core Languages | Bash, Python |
| Deployment Model | Docker Standalone |
| Communication Protocols | gRPC, HTTP |
| Key Ports | 19530, 9091, 2379 |
| Supported Environments | Linux, WSL 2, virtual machines, cloud servers |
| Core Dependencies | Docker, Milvus, Attu, pymilvus |
| Reference Versions | Milvus v2.6.2, Attu v2.6.1 |
| GitHub Stars | Not provided in the source content |
This deployment path is designed for stable operation in real network environments
Milvus is an open source vector database built for similarity search. It is widely used in RAG, semantic search, recommendation systems, and multimodal retrieval. The real challenge is rarely the install command itself. In most cases, the harder problems involve regional network conditions, image version availability, and host-level network connectivity.
The main value of this workflow is that it breaks “getting it running” into four parts: clean the old environment, pull images reliably, pin a working version, and verify external access. Once these four steps are done correctly, Attu and SDK integration usually become straightforward.
Cleaning up failed installs first significantly reduces reinstallation cost
If you have already tried other tutorials, stale containers, incorrect images, and leftover data directories may cause Milvus to restart repeatedly. Before reinstalling, do a full cleanup. That is far more effective than rerunning startup scripts blindly.
# Stop and remove old containers
docker stop milvus-standalone 2>/dev/null
docker rm milvus-standalone 2>/dev/null
# Remove potentially corrupted images or images with invalid tags
docker rmi milvusdb/milvus:v2.6.2 2>/dev/null
docker rmi milvusdb/milvus:v2.4.6 2>/dev/null
# Clean up leftover scripts and configuration files
rm -f standalone_embed.sh embedEtcd.yaml user.yaml
rm -rf ./volumes
This script reclaims old containers, old images, and persistent directories so that the next deployment runs in a clean environment.
Docker image acceleration is a prerequisite for a successful deployment
A very common reason Milvus installation fails is not a bad command, but slow Docker Hub access or pull timeouts. After you configure Docker registry mirrors, the deployment script becomes much more reliable.
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": [
"https://docker.xuanyuan.me",
"https://docker.1ms.run",
"https://docker.m.daocloud.io"
]
}
EOF
# Reload and restart the Docker service
sudo systemctl daemon-reload
sudo systemctl restart docker
This configuration assigns multiple registry mirrors to Docker and reduces the chance of Milvus image pull timeouts.
You should avoid direct GitHub access issues when downloading the official script
In some network environments, raw.githubusercontent.com is unreachable. It is safer to use a CDN distribution URL to download the official script. After downloading, inspect the image tag in the script immediately so that you do not reference a version that has not yet been pushed to Docker Hub.
# Download the startup script through a CDN
curl -sfL https://cdn.jsdelivr.net/gh/milvus-io/milvus/scripts/standalone_embed.sh -o standalone_embed.sh
chmod +x standalone_embed.sh
# Check the image version used by the script
grep -n "MILVUS_IMAGE\|milvusdb/milvus" standalone_embed.sh
# Replace it with a known stable tag if necessary
sed -i 's|milvusdb/milvus:.*|milvusdb/milvus:v2.6.2|' standalone_embed.sh
These commands download, inspect, and pin the Milvus image version to avoid Unable to find image errors.
After starting Milvus, you must immediately verify port responsibilities
After you run the startup script, Milvus usually needs about 90 seconds to finish initialization. A successful deployment is not defined by the existence of the container alone. You should also confirm that the logs are stable and that the required ports are available.
# Start standalone Milvus
bash standalone_embed.sh start
# Check container status
docker ps --filter name=milvus-standalone
# Follow startup logs
docker logs -f milvus-standalone
These commands start the service and verify whether the container has entered a stable running state.
A standalone Milvus deployment typically involves at least three ports: 19530 exposes the gRPC interface for SDK access, 9091 provides the WebUI entry point, and 2379 is the embedded etcd port, which usually does not need to be exposed directly to application users.
Host network connectivity determines whether the WebUI and SDK are actually usable
WSL 2, virtual machine NAT, and cloud server networking all behave differently. As a result, “the container is running” does not always mean “the service is reachable from the host.” A practical troubleshooting order is: check port listening first, then firewall rules, and finally host-side forwarding.
WSL 2 is usually the easiest option, but you still need to watch Windows Firewall
In WSL 2, Docker ports are usually mapped to the Windows host. In theory, you can access http://localhost:9091/webui/ directly. If the browser cannot open it, the most common cause is that Windows Firewall is blocking 9091 or 19530.
Virtual machine NAT mode requires explicit port forwarding
In VMware or VirtualBox NAT mode, the host cannot directly reach guest ports by default. You must forward host ports 19530 and 9091 to the same ports inside the virtual machine, and you must also allow them through the system firewall.
# Open the Milvus WebUI and gRPC ports
sudo firewall-cmd --zone=public --add-port=9091/tcp --permanent
sudo firewall-cmd --zone=public --add-port=19530/tcp --permanent
sudo firewall-cmd --reload
These commands open the required Milvus ports in a Linux virtual machine so external clients can access the service.
Attu provides the lowest-cost visual management entry point
Attu is the official GUI for Milvus. It is useful for verifying connectivity, creating collections, inspecting field schemas, and running search experiments. For beginners, it is often a better environment validation tool than writing SDK code first.
If you use the desktop version of Attu, the connection address is usually 127.0.0.1:19530. If Milvus is deployed on a remote server, use the corresponding public IP address instead. In the default standalone setup, you can usually leave the database field empty, and username and password are typically not required.
docker run -d --name attu \
-e MILVUS_URL=http://host.docker.internal:19530 \
-p 8000:3000 \
zilliz/attu:v2.6.1
This command runs Attu in a container and exposes a browser access point on port 8000.
If you use Compose, Attu is best orchestrated together with Milvus
attu:
container_name: attu
image: zilliz/attu:v2.6.1
environment:
MILVUS_URL: "standalone:19530"
ports:
- "8000:3000"
depends_on:
- standalone
This configuration adds Attu to your Compose stack so you can start and maintain it alongside Milvus.
A successful pymilvus connection means the service path is fully closed-loop
After visual validation, the next step is to establish a connection through the Python SDK. If pymilvus can reach port 19530, your deployment, port mapping, and network policy are all likely configured correctly.
from pymilvus import connections
# Connect to the local Milvus gRPC service
connections.connect(host="localhost", port="19530")
# Print a confirmation message after a successful connection
print("Milvus connected successfully")
This code verifies whether a Python application can connect to Milvus successfully over gRPC.
Operations and upgrades should always follow a rollback-first principle
Common tasks include checking container status, following logs, stopping services, and performing upgrades. The default data directory is volumes/milvus. Before an upgrade, confirm that this directory has been preserved or backed up.
# Check runtime status
docker ps --filter name=milvus-standalone
# Stop, restart, and upgrade
bash standalone_embed.sh stop
bash standalone_embed.sh restart
bash standalone_embed.sh upgrade
These commands cover the minimum operational set for daily inspection, restart, and version upgrades in a standalone deployment.
Common failures can be diagnosed quickly by symptom
Unable to find image usually means the image tag does not exist. In that case, fall back to a stable version such as v2.6.2. If image pulls time out, the registry mirrors are probably not taking effect. If Attu cannot connect to 127.0.0.1:19530, check port listening first, then Windows Firewall or NAT forwarding.
If the container keeps restarting, do not edit the script first. Run docker logs -f milvus-standalone and inspect the startup logs. In most cases, the root cause is ultimately a port conflict, directory permission issue, or image corruption.
FAQ
1. Why can’t I open the WebUI in my browser even though the Milvus script started successfully?
The most common reason is that port 9091 is not actually reachable from the host. In WSL 2, check Windows Firewall. In a virtual machine using NAT, add port forwarding. On a cloud server, open both the security group and the system firewall.
2. Why should I pin the Milvus image version instead of using the latest version directly?
Because the “latest” tag referenced by the startup script may not yet be synchronized to Docker Hub. Pinning to a verified existing version significantly reduces pull failures and startup issues.
3. Attu can connect, but pymilvus cannot. What does that usually indicate?
It usually means the web access path is working, but the Python-to-gRPC path on port 19530 is blocked. Focus on the SDK connection address, port mapping, firewall rules, and container logs.
AI Readability Summary
This guide reconstructs a practical standalone Milvus deployment workflow for local machines, WSL, virtual machines, and cloud servers. It covers environment cleanup, Docker image acceleration, script download, version pinning, network access, Attu-based visual validation, pymilvus programmatic connectivity, and common troubleshooting. It is well suited for developers who need to quickly build a vector database environment for RAG and retrieval applications.