Milvus 容器化构建指南:基于 builder.sh 与 Dev Container 的构建、测试与调试流程
本篇技术指南基于 Milvus 仓库的 build/README.md 及其配套构建脚本展开,完整讲解如何使用容器化构建环境编译 Milvus、运行单元与 E2E 测试、进入 Dev Container 开发,以及用 VS Code 在宿主机上无缝调试。读完后,你可以独立完成:环境自检(Docker 版本、CPU SIMD 指令集)、通过 build/builder.sh 执行各类 make 任务、理解 .docker/ 缓存目录与 builder 镜像的增量构建机制,并在远程容器中编译与测试整个项目。
一、为什么用容器化构建
虽然可以在本地安装 Go 后直接构建 Milvus,但官方推荐的构建流程运行在 Docker 容器内。这样做的好处是:
- 降低初始配置成本:不需要在宿主机上分别安装 Go、C++ 工具链、cmake、conan 等依赖,这些全部预装在 builder 镜像里;
- 构建与测试环境高度一致:本地开发、单元测试、CI 使用同一套容器环境,避免"我机器上能编译"类问题。
Milvus 的构建涉及 Go 与 C++ 两部分:make milvus 目标会依次执行 build-cpp print-build-info build-go(见根目录 Makefile),因此容器镜像中同时包含 GCC 12、cmake、Conan、Go 与 Rust 工具链。
二、开始构建前的环境检查
2.1 Docker 与 Docker Compose 版本
构建前必须确认宿主机满足版本要求:
| 组件 | 最低版本 |
|---|---|
| Docker | 19.03 |
| Docker Compose | 1.25.1 |
不同操作系统的安装注意事项:
- macOS:安装 Docker for Mac,并建议将 Docker VM 分配至少 2 vCPU 和 8GB 初始内存,否则构建很可能失败;
- Linux:按发行版指引本地安装 Docker;
- Windows:使用 Docker Desktop 的 WSL2 后端,且务必将源码存放在本地 Linux 文件系统,而不是
/mnt/c的 Windows 远程挂载目录(否则 I/O 性能会显著影响编译)。
2.2 CPU SIMD 指令集检查
Milvus 的向量计算(索引构建与相似度检索)依赖 CPU 的 SIMD(Single Instruction, Multiple Data)扩展指令集。请确认你的 CPU 至少支持以下指令集之一:
- SSE4.2
- AVX
- AVX2
- AVX512
使用 lscpu 命令检查:
lscpu | grep -e sse4_2 -e avx -e avx2 -e avx512
2.3 可选依赖
- Google Cloud SDK:仅当你需要把构建产物上传到 Google Cloud Storage 时才需要安装并配置,其余场景可安全忽略。
三、build/ 目录结构与关键脚本
构建与测试相关脚本都位于 build/ 目录,且所有脚本都必须在 Milvus 仓库根目录下执行。目录中的关键文件包括:
| 文件 | 作用 |
|---|---|
| build/builder.sh | 在 CPU 构建容器内执行命令 |
| build/builder_gpu.sh | 在 GPU 构建容器内执行命令 |
| build/build_image.sh / build/build_image_gpu.sh | 构建(GPU)构建镜像 |
| build/util.sh | 公共工具函数(自动探测 docker compose 或 docker-compose 命令) |
| build/docker/builder/ | builder 镜像的 Dockerfile(按 OS/架构分目录) |
builder.sh 的常用调用方式:
# 仅在容器内构建 linux 二进制,可透传 make 选项与目标
build/builder.sh make
# 运行提交前的全部验证检查
build/builder.sh make verifiers
# 运行全部单元测试
build/builder.sh make unittest
# 清理所有生成文件
build/builder.sh make clean
注意 Makefile 中这些目标各自的构成:
verifiers=build-cpp getdeps cppcheck rustcheck fmt static-check(Makefile#L238),即构建 C++ 核心、静态检查与格式检查的组合;unittest=test-cpp test-go(Makefile#L329),同时覆盖 C++ 与 Go 单测;milvus=build-cpp print-build-info build-go(Makefile#L115),完整产出一个可运行的 Milvus 二进制。
此外,docker-compose.yml 中 builder 服务的默认 command 为:
/bin/bash -c "make check-proto-product && make verifiers && make unittest"
也就是"proto 生成校验 + 全部验证 + 全部单测",这正是 CI 场景的完整检查链路。
四、builder.sh 的底层执行流程
结合 build/builder.sh 源码,可以看清文档中"Basic Flow"一节描述的实际执行链:
-
定位仓库根目录:脚本通过自身路径推导出 toplevel,随后
pushd进入根目录,这解释了"所有脚本必须从根目录执行"的要求; -
加载
.env:若仓库根目录存在 .env,其中所有变量会自动导出,供docker-compose.yml插值使用; -
处理特殊子命令:
build/builder.sh pull仅拉取 builder 镜像,build/builder.sh down直接docker compose down; -
准备缓存目录:在
.docker/(可用DOCKER_VOLUME_DIRECTORY覆盖)下创建按"架构-操作系统"区分的四个缓存卷目录:mkdir -p "${DOCKER_VOLUME_DIRECTORY:-.docker}/${IMAGE_ARCH}-${OS_NAME}-ccache" mkdir -p "${DOCKER_VOLUME_DIRECTORY:-.docker}/${IMAGE_ARCH}-${OS_NAME}-go-mod" mkdir -p "${DOCKER_VOLUME_DIRECTORY:-.docker}/${IMAGE_ARCH}-${OS_NAME}-vscode-extensions" mkdir -p "${DOCKER_VOLUME_DIRECTORY:-.docker}/${IMAGE_ARCH}-${OS_NAME}-conan2"分别缓存 C++ 编译(ccache)、Go 模块(
/go/pkg/mod)、VS Code 远程扩展与 Conan 2 依赖,这就是"跨运行缓存第三方包与编译缓存、加速增量构建"的实现; -
拉取/构建 builder 镜像:默认执行
docker compose pull builder;设置CHECK_BUILDER=1时会额外执行build以强制重建镜像; -
执行命令:最终以
docker compose run --no-deps --rm builder "$@"运行传入的参数。
4.1 通过环境变量定制构建环境
.env 与 docker-compose.yml 中可配置的关键变量:
| 变量 | 默认值/示例 | 说明 |
|---|---|---|
IMAGE_REPO |
milvusdb |
builder 镜像的 registry/命名空间 |
OS_NAME |
见 .env 中 ubuntu22.04 |
选择 builder 的 OS 变体,决定使用 build/docker/builder/cpu/${OS_NAME}/Dockerfile |
IMAGE_ARCH |
amd64 |
目标架构,镜像 tag 与缓存目录都会带上该值 |
DATE_VERSION / LATEST_DATE_VERSION |
如 20260714-c135601 |
builder 镜像版本号,LATEST_* 用于 cache_from 增量构建 |
ETCD_ENDPOINTS / MINIO_ADDRESS / PULSAR_ADDRESS |
etcd:2379 等 |
单测依赖的元数据/对象存储/消息队列端点 |
IS_NETWORK_MODE_HOST |
可选 true |
置位后 builder 容器改为 host 网络模式 |
CHECK_BUILDER |
可选 1 |
强制重建 builder 镜像而非仅拉取 |
build/docker/builder/cpu/ 下目前提供 amazonlinux2023、rockylinux9、ubuntu20.04、ubuntu22.04、ubuntu24.04 五个 OS 变体的 Dockerfile。文档中示例的切换方式为:
export OS_NAME=amazonlinux2023
build/builder.sh make
以 build/docker/builder/cpu/ubuntu22.04/Dockerfile 为例,镜像内预装:
- GCC 12(
gcc/g++软链到gcc-12/g++-12)、gdb、ccache、clang-format/clang-tidy 15; - cmake 3.31.8、Conan 2(
conan==2.25.1)、Go 1.26.6、Rust 1.92 工具链; - 工作目录固定为
/go/src/github.com/milvus-io/milvus,仓库根目录以delegated模式挂载到该路径。
而 build/docker/builder/entrypoint.sh 负责在容器启动时初始化 $HOME、把当前用户写入 /etc/passwd 与 /etc/group(保证以宿主机 UID 运行、避免生成文件权限问题),最后 exec "$@" 交给实际命令。
4.2 ccache 与卷挂载
docker-compose.yml 通过 YAML anchor 为 builder 注入了统一的 ccache 配置:
x-ccache: &ccache
CCACHE_COMPILERCHECK: content
CCACHE_COMPRESS: 1
CCACHE_COMPRESSLEVEL: 5
CCACHE_MAXSIZE: 2G
CCACHE_DIR: /ccache
配合卷挂载:
volumes:
- .:/go/src/github.com/milvus-io/milvus:delegated
- ${DOCKER_VOLUME_DIRECTORY:-.docker}/${IMAGE_ARCH}-${OS_NAME}-ccache:/ccache:delegated
- ${DOCKER_VOLUME_DIRECTORY:-.docker}/${IMAGE_ARCH}-${OS_NAME}-go-mod:/go/pkg/mod:delegated
- ${DOCKER_VOLUME_DIRECTORY:-.docker}/${IMAGE_ARCH}-${OS_NAME}-vscode-extensions:/home/milvus/.vscode-server/extensions:delegated
- ${DOCKER_VOLUME_DIRECTORY:-.docker}/${IMAGE_ARCH}-${OS_NAME}-conan2:/home/milvus/.conan2:delegated
delegated 挂载模式允许容器内缓存写回宿主机异步进行,兼顾了缓存持久化与写入性能。builder 服务还声明了 shm_size: 2G,并在 depends_on 中列出了单测依赖的 etcd、minio、pulsar、azurite、gcpnative 等服务容器。
五、Dev Container:进入开发容器
除了"一条命令跑一个任务",也可以进入长驻的开发容器。scripts/devcontainer.sh 会先从 docker-compose.yml 生成一份 docker-compose-devcontainer.yml(注释掉 builder 的 build: 与 command: 段,并注入宿主机 UID/GID),再执行 up/down 等操作。
在仓库根目录执行:
./scripts/devcontainer.sh up
预期输出(各容器依次创建):
Creating network "milvus-dev" with the default driver
Creating milvus_jaeger_1 ... done
Creating milvus_minio_1 ... done
Creating milvus_pulsar_1 ... done
Creating milvus_etcd_1 ... done
Creating milvus_builder_1 ... done
检查运行状态:
docker compose -f docker-compose-devcontainer.yml ps
milvus_builder_1 是 Milvus 的开发容器,其余容器(etcd、minio、pulsar、jaeger)是单元测试的依赖。进入容器:
docker exec -ti milvus_builder_1 bash
容器内即可编译并跑单测:
make milvus
make unittest
停止 Dev Container:
./scripts/devcontainer.sh down
六、E2E 测试
Milvus 使用 Python SDK 编写 E2E 用例来验证功能正确性。运行前需要一个可用的 Milvus 实例,文档给出的两条启动路径:
方式一:Docker 部署依赖 + 容器内启动 standalone
cd deployments/docker/dev
docker compose up -d
cd ../../../
build/builder.sh /bin/bash -c "export ROCKSMQ_PATH='/tmp/milvus/rdb_data' && ./scripts/start_standalone.sh && cat"
方式二:容器内直接启动集群模式
build/builder.sh /bin/bash -c "./scripts/start_cluster.sh && cat"
末尾的 && cat 用于保持容器前台存活。随后执行 E2E:
MILVUS_SERVICE_IP=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $(docker compose ps -q builder))
cd tests/docker
docker compose run --rm pytest /bin/bash -c "pytest --host ${MILVUS_SERVICE_IP}"
该命令先动态解析 builder 容器的 IP 作为 MILVUS_SERVICE_IP,再在 tests/docker 的 pytest 容器中运行用例。
七、在宿主机上调试:VS Code 集成 Docker
7.1 原理与准备
VS Code 的 Remote-Containers 扩展会把宿主机目录挂载(或复制)到容器工作区,扩展本体安装在容器内运行,因此宿主机的 VS Code 可以完整使用容器内的工具链与文件系统——连接不同容器即可切换整套开发环境。
准备:
- 安装 Visual Studio Code;
- 安装 Remote Development 扩展包。
仓库根目录的 .devcontainer.json 描述了如何访问/创建开发容器环境:
{
"name": "Milvus Distributed Dev Container Definition",
"dockerComposeFile": ["./docker-compose-devcontainer.yml"],
"service": "builder",
"initializeCommand": "scripts/devcontainer.sh",
"workspaceFolder": "/go/src/github.com/milvus-io/milvus",
"remoteEnv": { "GOPROXY": "https://goproxy.cn" },
"extensions": [
"ms-vscode.cpptools",
"golang.go"
]
}
可以看到它复用 docker-compose-devcontainer.yml 中的 builder 服务(与第五节 Dev Container 同一套环境),initializeCommand 调用 scripts/devcontainer.sh 生成 compose 文件,并预装 C++ 与 Go 两个扩展。
7.2 操作步骤
- 启动 VS Code,在命令面板(F1)中输入并选择 "Remote-Containers: Open Folder in Container",然后选择包含
.devcontainer.json的项目目录(也可点击右下角远程按钮 > < 选择同一命令); - VS Code 开始加载并构建 Dev Container,进度条显示构建状态;
- 构建完成后 VS Code 自动连接到容器,此后可像在宿主机一样编码与调试;
- 也可以打开 Terminal >> New Terminal 直接进入容器终端执行命令。
7.3 按需调整 Go 扩展设置
路径为 code -> preference -> settings,常用项:
"go.testFlags": ["-v"] // 运行单元测试时输出详细信息
"go.coverOnSave": true // 保存时显示覆盖率
"go.lintOnSave": true // 保存时自动 golint 与代码风格检查
八、要点回顾
- 一条命令完成构建/验证/测试:
build/builder.sh make、make verifiers、make unittest、make clean,全部在容器内执行; - 环境一致性来自 builder 镜像:按
${OS_NAME}选择 build/docker/builder/cpu/ 下的 Dockerfile,GCC 12 + cmake + Conan + Go + Rust 工具链齐备; - 增量构建来自
.docker/缓存卷:ccache(2G 上限)、Go mod、VS Code 扩展、Conan 2 四类缓存按"架构-OS"分目录持久化; - 长驻开发用 Dev Container:
scripts/devcontainer.sh up/down管理,docker exec -ti milvus_builder_1 bash进入; - E2E 走 Python SDK:先起 standalone 或 cluster,再用
tests/docker中的 pytest 容器对容器 IP 发起测试; - 远程调试零成本:
.devcontainer.json+ Remote-Containers 扩展即可把整套开发环境搬进容器。
更多编译与单测细节可参考 DEVELOPMENT.md。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0623
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
