
1.1 Standalone 实际装下了什么
Compose 拉起的不是「一个叫 milvus 的镜像」这么简单。v3.0.1 官方 YAML 里是三个服务:
| 容器名 | 镜像(本文) | 对主机端口 | 数据目录(相对 compose 目录) |
|---|---|---|---|
milvus-etcd |
quay.io/coreos/etcd:v3.5.25 |
不映射 | ./volumes/etcd |
milvus-minio |
minio/minio:RELEASE.2024-12-18T13-15-44Z |
9000、9001 |
./volumes/minio |
milvus-standalone |
milvusdb/milvus:v3.0.1 |
19530、9091 |
./volumes/milvus |
网络名默认是 milvus。Standalone 通过环境变量找依赖:ETCD_ENDPOINTS=etcd:2379、MINIO_ADDRESS=minio:9000。消息队列类型在该 YAML 里是 MQ_TYPE: woodpecker,入门不必改。
图 2:SDK 只连 Standalone;etcd 与 MinIO 是它的依赖,不是你业务代码要直连的库。

1.2 和 Lite 的替换规则
同一段 Python,只改 uri:
| 目标 | MilvusClient 的 uri |
|---|---|
| Lite | ./milvus.db(本地文件路径) |
| 本文 Standalone | http://127.0.0.1:19530 |
| 远程 / 云 | 厂商给的 HTTPS 端点 + token |
Lite 不 启动上述三个容器,也 不 占用 19530。不要在「已经 compose up」的机器上,又用 ./milvus.db 验收,那连的是另一套库。
1.3 硬件与软件下限
官方 Standalone 门槛可以记成四条。低于这个,常见失败是容器反复重启,而不是 YAML 写错。
| 项 | 下限 | 建议 |
|---|---|---|
| CPU | 4 核;需 SSE4.2 / AVX 等 SIMD 之一 | Apple Silicon 可用 Docker Desktop |
| 内存 | 8 GB | 16 GB |
| 磁盘 | SATA SSD | NVMe;etcd 对 fsync 延迟敏感 |
| 软件 | Docker 19.03+;Compose V2 或 V1 ≥ 1.18 | macOS 把 Docker VM 内存调到 ≥ 8 GB |
Windows:走 Docker Desktop + WSL 2,不要 把数据目录绑在 /mnt/c 这类跨文件系统路径上。Lite 在 Windows 上不要作为本篇默认路径。
内存低于 8 GB 时,先加一块 swap 再启动,否则 Standalone 容易在拉起后立刻 Exited。2 核 / 4 GB 档云主机可以用来走通安装,不能当生产规格。
二、连接与配置属性
应用侧只需要记住三组数:SDK 端口、健康检查、默认账号。其余是 Compose 内部约定。
2.1 端口与 URL
| 用途 | 地址 | 谁用 |
|---|---|---|
| gRPC / SDK | http://127.0.0.1:19530 |
pymilvus、Java / Node SDK |
| 健康检查 | http://127.0.0.1:9091/healthz |
curl、编排探活 |
| WebUI | http://127.0.0.1:9091/webui/ |
浏览器看实例状态 |
| MinIO API / 控制台 | 9000 / 9001 |
排障对象存储;默认账号 minioadmin / minioadmin |
19530 被占用时,Standalone 起不来。先 lsof -iTCP:19530 -sTCP:LISTEN(macOS / Linux)或换端口(见第四章)。
2.2 客户端连接参数
v3.0.x 本机默认用户是 root,密码 Milvus:
python
from pymilvus import MilvusClient
client = MilvusClient(uri="http://127.0.0.1:19530", token="root:Milvus")
依赖与服务器对齐:
bash
pip install -U "pymilvus==3.0.1"
Java 侧对应坐标是 io.milvus:milvus-sdk-java:3.0.9(本文不展开写入代码)。换主版本时,服务器镜像、Compose YAML、SDK 三件一起升,不要只拉新镜像。
2.3 Compose 里真正会改的环境变量
入门只碰这几个;其余保持 Release YAML 原样。
| 变量 / 项 | 默认 | 何时改 |
|---|---|---|
DOCKER_VOLUME_DIRECTORY |
当前目录 . |
数据不想落在 git 工作区 |
ETCD_ENDPOINTS |
etcd:2379 |
几乎不改 |
MINIO_ADDRESS |
minio:9000 |
几乎不改 |
MINIO_REGION |
官方 YAML 可能为空 | 必须写成 us-east-1,否则 Standalone 预检 MinIO 会 FATAL |
端口映射 19530:19530 |
原样 | 主机端口冲突 |
自定义 milvus.yaml |
无 | 改日志级别、quota 等(第四章) |
三、Docker Compose 安装与启动
图 3:检查 Docker → 下载 v3.0.1 YAML →
up -d→ps→healthz。图中 curl 地址以正文命令为准。

3.1 检查 Docker
bash
docker --version
docker compose version || docker-compose version
优先 Compose V2 (docker compose,中间没有连字符)。Linux 发行版里经常只有 V1 的 docker-compose:1.18 及以上可以跑本篇 YAML,不必为了装插件去 GitHub 拉 60 MB 的二进制。下文命令写成 docker compose;只有 V1 时改成 docker-compose。
Docker 未启动时,后面所有命令都会在拉镜像或建网络时报错。macOS / Windows 先打开 Docker Desktop,等到引擎就绪。Linux 用 systemctl start docker。
3.2 下载官方 YAML 并钉死版本
单独建目录,避免把 volumes/ 散落到无关项目里。
bash
mkdir -p ~/milvus && cd ~/milvus
curl -L "https://github.com/milvus-io/milvus/releases/download/v3.0.1/milvus-standalone-docker-compose.yml" -o docker-compose.yml
没有 curl 时用 wget:
bash
wget "https://github.com/milvus-io/milvus/releases/download/v3.0.1/milvus-standalone-docker-compose.yml" -O docker-compose.yml
打开文件确认三件事:image: milvusdb/milvus:v3.0.1、服务名含 etcd / minio / standalone、端口含 19530。不要随手改成 latest。
v3.0.1 官方 YAML 里 Standalone 往往没有 MINIO_REGION。不补这一项,容器能创建,进程会在预检对象存储时 abort(Exit 134,日志里是 A region must be set when sending requests to S3)。在 standalone.environment 和 minio.environment 各加一行:
yaml
minio:
environment:
MINIO_ACCESS_KEY: minioadmin
MINIO_SECRET_KEY: minioadmin
MINIO_REGION_NAME: us-east-1
standalone:
environment:
ETCD_ENDPOINTS: etcd:2379
MINIO_ADDRESS: minio:9000
MINIO_REGION: us-east-1
MQ_TYPE: woodpecker
数据目录要在启动前建好,并交给镜像内用户 milvus(uid 999 )。否则 FATAL:mkdir /var/lib/milvus/data/: permission denied。
bash
mkdir -p ~/milvus/volumes/milvus/data
chown -R 999:999 ~/milvus/volumes/milvus
国内拉 Docker Hub / quay.io 若很慢,给 Docker 配镜像加速后重启引擎(改完必须 systemctl restart docker 或重开 Docker Desktop):
json
{
"registry-mirrors": [
"https://docker.m.daocloud.io"
]
}
内存不到 8 GB 时补 4 GB swap,再执行下一节 up:
bash
dd if=/dev/zero of=/swapfile bs=1M count=4096
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
echo '/swapfile none swap sw 0 0' >> /etc/fstab
3.3 启动
bash
docker compose up -d
首次会拉 etcd、MinIO、Milvus 三张镜像,视网络可能要几分钟。国内环境若长时间卡在 Pulling,先配上一节的 registry-mirrors 再拉。本机 HTTP 代理有时会干扰容器互访,排障时对 Docker Desktop 或当前 shell 关掉 HTTP_PROXY / HTTPS_PROXY 再试。
启动是异步的。YAML 里 Standalone 的 healthcheck.start_period 是 90 秒 :up 立刻成功不等于 healthz 已经 OK。
3.4 查看容器
bash
docker compose ps
三个名字都应存在,状态为 Up(MinIO / Standalone 还可能带 healthy):
| Name | 期望 |
|---|---|
milvus-etcd |
Up |
milvus-minio |
Up / healthy |
milvus-standalone |
Up,映射 0.0.0.0:19530->19530、9091->9091 |
任一容器 Restarting 或 Exited,先看日志,不要直接改 YAML 端口碰运气:
bash
docker compose logs --tail=80 standalone
docker compose logs --tail=80 etcd
docker compose logs --tail=80 minio
3.5 停止与卸载
| 命令 | 效果 |
|---|---|
docker compose stop |
停容器,保留 ./volumes |
docker compose start |
再起来,数据还在 |
docker compose down |
删容器与默认网络,仍保留 绑定的 ./volumes |
删除 ~/milvus/volumes |
真正清空元数据与段文件;不可恢复 |
开发机日常用 stop / start。down 不等于卸载数据。
四、数据目录与配置定制
默认数据落在 compose 文件所在目录的 volumes/。这是绑定挂载,不是匿名 Volume:你在 Finder / ls 里能直接看到。
4.1 换数据盘
bash
export DOCKER_VOLUME_DIRECTORY=/data/milvus
mkdir -p "$DOCKER_VOLUME_DIRECTORY"
cd ~/milvus
docker compose up -d
之后 etcd / MinIO / Milvus 分别写到 /data/milvus/volumes/{etcd,minio,milvus}。改路径等于换了一套库:原 ~/milvus/volumes 不会自动迁过去。换盘后仍要 chown -R 999:999 新的 milvus 数据目录。
4.2 主机端口冲突
只改 冒号左边 的主机端口,容器内仍是 19530 / 9091。例如主机改到 19531:
yaml
ports:
- "19531:19530"
- "9091:9091"
客户端 URI 跟着改成 http://127.0.0.1:19531。不要只改 YAML 不改 SDK。
4.3 覆盖 milvus.yaml
需要改日志、限流等时,把自定义配置挂进 Standalone 容器。在 standalone.volumes 增加一行(本地文件路径按实际修改):
yaml
volumes:
- ${DOCKER_VOLUME_DIRECTORY:-.}/volumes/milvus:/var/lib/milvus
- ./milvus.yaml:/milvus/configs/milvus.yaml
改配置必须 docker compose up -d 让容器带着新文件重启;当前进程内热更新不是入门默认能力。未改配置则不要挂这个文件,以免空文件覆盖镜像内默认项。
4.4 无 Docker 时的 Lite 备选
仅当本机没有 Docker、且系统是 Linux / macOS 时使用。Windows 跳过本节。
bash
pip install -U "pymilvus==3.0.1"
python
from pymilvus import MilvusClient
client = MilvusClient(uri="./milvus.db")
print(client.list_collections())
Lite 与 Standalone 数据不共享 。验证通过后若要换 Standalone,当作新库重新写入,不要假设 .db 会自动出现在 19530 里。
五、最小可跑通验收
图 4:容器 Up 之后,用 REST 插入两条 FAQ 示意数据,再按 id 查回、按向量搜 Top1。

终点不是「up -d 没报错」或 healthz 返回 OK,而是能写入一条实体,再用 id 原样查回来。动手前先认清查询语言:后面 curl 里的 "filter": "id == 1" 不是 Elasticsearch 那种 JSON DSL。
5.1 查询语言与过滤表达式
REST 报文是一层 JSON 外壳:collectionName、data、outputFields 都是普通字段。真正像「查询语言」的,是里面那串字符串,例如 "id == 1"、title == "退货流程"。
官方不叫 DSL,也不叫 MQL。文档里的名字是 filter expression (过滤表达式),也写作 boolean expression / predicate expression (布尔表达式 / 谓词表达式)。语法按 EBNF 定义,服务端编成 PlanAST 再执行。SDK 老参数名是 expr,现在 REST 和 MilvusClient 多用 filter。
写法更接近 SQL 的 WHERE(比较、and / or / not、in、like),不是 ES Query DSL 那种层层嵌套的 JSON。外壳 JSON 只负责把表达式送进去。
向量检索和标量过滤是两件事,后面验收会各打一次:
| 能力 | 在干什么 | 过滤怎么写 |
|---|---|---|
| Query | 只按标量条件取行 | filter,如下面的 id == 1 |
| Search | 按向量找近邻,可选再收窄 | 同一套过滤表达式;本验收的 search 先不带 filter |
完整算子见官方 Filtering Explained。本验收只用 id == 1 证明写入能按主键取回。
5.2 健康检查
bash
curl -sf http://127.0.0.1:9091/healthz
echo
应打出 OK。刚启动的 1~2 分钟内失败,等 Standalone 变 healthy 再打一次。这一步只证明进程活着,不算装好。

浏览器可打开 http://127.0.0.1:9091/webui/ 看实例页面。真正的验收是下一节的写入和查询。
5.3 测试数据写入、查询
下面每条 curl 都可单独复制执行,打 19530 的 REST。
建 Collection:主键 id、4 维向量、一条标题。向量字段带上 AUTOINDEX + COSINE,后面才能 load / search。
bash
curl -sS -X POST http://127.0.0.1:19530/v2/vectordb/collections/create \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer root:Milvus' \
-d '{
"collectionName": "install_check",
"schema": {
"autoID": false,
"enableDynamicField": false,
"fields": [
{"fieldName": "id", "dataType": "Int64", "isPrimary": true},
{"fieldName": "vector", "dataType": "FloatVector", "elementTypeParams": {"dim": "4"}},
{"fieldName": "title", "dataType": "VarChar", "elementTypeParams": {"max_length": "64"}}
]
},
"indexParams": [
{"fieldName": "vector", "metricType": "COSINE", "indexName": "vector_idx", "params": {"index_type": "AUTOINDEX"}}
]
}'
应看到 "code":0。若提示 collection 已存在,先 drop 再 create:
bash
curl -sS -X POST http://127.0.0.1:19530/v2/vectordb/collections/drop \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer root:Milvus' \
-d '{"collectionName":"install_check"}'
写入两条。做完后 insertCount 必须是 2,insertIds 为 [1,2]。
bash
curl -sS -X POST http://127.0.0.1:19530/v2/vectordb/entities/insert \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer root:Milvus' \
-d '{
"collectionName": "install_check",
"data": [
{"id": 1, "vector": [0.1, 0.2, 0.3, 0.4], "title": "退货流程"},
{"id": 2, "vector": [0.9, 0.8, 0.1, 0.0], "title": "忘记密码"}
]
}'
load 后再查。按主键把 id=1 取回来,title 必须是「退货流程」,向量必须是 [0.1,0.2,0.3,0.4]。
bash
curl -sS -X POST http://127.0.0.1:19530/v2/vectordb/collections/load \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer root:Milvus' \
-d '{"collectionName":"install_check"}'

bash
curl -sS -X POST http://127.0.0.1:19530/v2/vectordb/entities/query \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer root:Milvus' \
-d '{
"collectionName": "install_check",
"filter": "id == 1",
"outputFields": ["id", "title", "vector"]
}'

再搜一次:用 id=1 的同一条向量去近邻,Top1 应仍是「退货流程」,COSINE 下 distance 接近 1。
bash
curl -sS -X POST http://127.0.0.1:19530/v2/vectordb/entities/search \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer root:Milvus' \
-d '{
"collectionName": "install_check",
"data": [[0.1, 0.2, 0.3, 0.4]],
"limit": 1,
"outputFields": ["id", "title"]
}'

query / search 对不上,看 Standalone 日志,不要只看 healthz。系统里有 Python 3.8+ 时,也可以用 pymilvus==3.0.1 做同一组 insert / query,URI 仍是 http://127.0.0.1:19530,token 仍是 root:Milvus。
5.4 常见失败对照
| 现象 | 更可能的原因 | 处理 |
|---|---|---|
Standalone Exited (134),日志 permission denied |
数据目录属主是 root,容器用户是 uid 999 | chown -R 999:999 ~/milvus/volumes/milvus 后 up -d |
Standalone Exited (134),日志 region must be set |
YAML 未写 MINIO_REGION |
Standalone 加 MINIO_REGION: us-east-1 |
up 后 Standalone 一直 Restarting |
内存不够、镜像不完整 | 补 swap;compose logs standalone |
healthz 连接拒绝 |
还在 start_period,或 9091 未映射 |
等 healthy;检查 ps 端口列 |
| pymilvus 装不上 | 系统 Python 低于 3.8 | 用上一节 REST 写入并 query |
| pymilvus 超时 | 连了 Lite 文件、或本机代理劫持 localhost | URI 必须是 http://127.0.0.1:19530;关掉代理再试 |
bind: address already in use |
19530 / 9091 / 9000 被占用 |
改主机端口或停掉旧实例 |
| 拉镜像失败 | 网络 / 镜像源 | 配置 registry-mirrors 后重启 Docker |
| 认证失败 | token 与服务器不一致 | 先用 root:Milvus;自改密码则同步 URI |
六、生产建议与扩展
本机 Standalone 够支撑 RAG 开发闭环:切片写入、近邻召回、换模型重编。把它直接当生产有三条硬边界。
- 故障域是一台机器。 etcd / MinIO / Milvus 任一磁盘满或 Docker 挂了,检索层一起停。生产要 Distributed 或托管,并单独规划对象存储与元数据盘。
- 默认 MinIO 账号不能暴露到公网。
minioadmin只适合本机。端口9000/9001/19530不要映射到无鉴权的公网网卡。 - 版本要钉死。 备份的是
volumes/加上当时的docker-compose.yml。下次用另一条 Release YAML 起同一份数据前,先读该版本的升级说明。
本文未展开:Helm 安装 Distributed、GPU 镜像、standalone_embed.sh、从 Lite dump 再 bulk insert 到 Standalone、TLS 与 RBAC 细化。装好之后,下一步才是写入切片并用改写问句验证召回。
一句话:RAG 检索层在本机的落地形态,就是 Docker Compose 拉起的 Standalone;装好的判据是能写入实体并按 id 查回来,而不是 healthz 打出 OK。
目录:20260911_Milvus下载安装 · 配图:images/ · 2026-09-11