首页
/ Milvus 容器化构建指南:基于 builder.sh 与 Dev Container 的构建、测试与调试流程

Milvus 容器化构建指南:基于 builder.sh 与 Dev Container 的构建、测试与调试流程

2026-09-05 09:32:20作者:范垣楠Rhoda

本篇技术指南基于 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 composedocker-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-checkMakefile#L238),即构建 C++ 核心、静态检查与格式检查的组合;
  • unittest = test-cpp test-goMakefile#L329),同时覆盖 C++ 与 Go 单测;
  • milvus = build-cpp print-build-info build-goMakefile#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"一节描述的实际执行链:

  1. 定位仓库根目录:脚本通过自身路径推导出 toplevel,随后 pushd 进入根目录,这解释了"所有脚本必须从根目录执行"的要求;

  2. 加载 .env:若仓库根目录存在 .env,其中所有变量会自动导出,供 docker-compose.yml 插值使用;

  3. 处理特殊子命令build/builder.sh pull 仅拉取 builder 镜像,build/builder.sh down 直接 docker compose down

  4. 准备缓存目录:在 .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 依赖,这就是"跨运行缓存第三方包与编译缓存、加速增量构建"的实现;

  5. 拉取/构建 builder 镜像:默认执行 docker compose pull builder;设置 CHECK_BUILDER=1 时会额外执行 build 以强制重建镜像;

  6. 执行命令:最终以 docker compose run --no-deps --rm builder "$@" 运行传入的参数。

4.1 通过环境变量定制构建环境

.envdocker-compose.yml 中可配置的关键变量:

变量 默认值/示例 说明
IMAGE_REPO milvusdb builder 镜像的 registry/命名空间
OS_NAME .envubuntu22.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/ 下目前提供 amazonlinux2023rockylinux9ubuntu20.04ubuntu22.04ubuntu24.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 可以完整使用容器内的工具链与文件系统——连接不同容器即可切换整套开发环境。

准备:

  1. 安装 Visual Studio Code;
  2. 安装 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 操作步骤

  1. 启动 VS Code,在命令面板(F1)中输入并选择 "Remote-Containers: Open Folder in Container",然后选择包含 .devcontainer.json 的项目目录(也可点击右下角远程按钮 > < 选择同一命令);
  2. VS Code 开始加载并构建 Dev Container,进度条显示构建状态;
  3. 构建完成后 VS Code 自动连接到容器,此后可像在宿主机一样编码与调试;
  4. 也可以打开 Terminal >> New Terminal 直接进入容器终端执行命令。

VS Code 远程容器工作区

7.3 按需调整 Go 扩展设置

路径为 code -> preference -> settings,常用项:

"go.testFlags": ["-v"]   // 运行单元测试时输出详细信息
"go.coverOnSave": true  // 保存时显示覆盖率
"go.lintOnSave": true    // 保存时自动 golint 与代码风格检查

八、要点回顾

  • 一条命令完成构建/验证/测试build/builder.sh makemake verifiersmake unittestmake 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 Containerscripts/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

登录后查看全文
热门项目推荐
相关项目推荐