运行 Docker 构建#
我们的大多数基于 Linux 的持续集成任务都使用 Docker 和 Docker Compose 与公共 CI 服务解耦。 保持 CI 配置最小化可以实现本地可重复性。
用法#
有多种方法可以执行基于 Docker 的构建。推荐的方法是使用 Archery 工具。
示例#
列出可用镜像
archery docker images
执行构建
archery docker run conda-python
Archery 调用以下 docker compose 命令
docker compose pull --ignore-pull-failures conda-cpp
docker compose pull --ignore-pull-failures conda-python
docker compose build conda-cpp
docker compose build conda-python
docker compose run --rm conda-python
显示 Docker Compose 命令而不是执行它们
archery docker run --dry-run conda-python
禁用镜像拉取
archery docker run --no-cache conda-python
转换为
docker compose build --no-cache conda-cpp
docker compose build --no-cache conda-python
docker compose run --rm conda-python
仅为叶镜像禁用缓存
这对于强制构建依赖项的开发版本很有用。 在下面的示例中,该命令构建镜像树的 conda-cpp > conda-python > conda-python-pandas
分支,其中叶镜像是 conda-python-pandas
。
PANDAS=upstream_devel archery docker run --no-leaf-cache conda-python-pandas
转换为
export PANDAS=upstream_devel
docker compose pull --ignore-pull-failures conda-cpp
docker compose pull --ignore-pull-failures conda-python
docker compose build conda-cpp
docker compose build conda-python
docker compose build --no-cache conda-python-pandas
docker compose run --rm conda-python-pandas
请注意,它不会拉取 conda-python-pandas 镜像,也不会在构建它时禁用缓存。
PANDAS
是一个构建参数,请参阅 .env
文件中的默认值。
完全跳过镜像构建
根据版本、cache_from
构建条目和使用的后端 (docker-py、docker-cli、docker-cli 和 buildkit),docker-compose 的层缓存机制可能不如 docker 可靠。 这可能导致不同的层哈希值 - 即使重复执行相同的构建命令 - 最终导致缓存未命中和完整的镜像重建。
如果镜像已经构建但缓存无法正常工作,跳过构建阶段可能很有用
# first run ensures that the image is built
archery docker run conda-python
# if the second run tries the build the image again and none of the files
# referenced in the relevant dockerfile have changed, then it indicates a
# cache miss caused by the issue described above
archery docker run conda-python
# since the image is properly built with the first command, there is no
# need to rebuild it, so manually disable the pull and build phases to
# spare the some time
archery docker run --no-pull --no-build conda-python
将环境变量传递给容器
容器内使用的大多数构建脚本都可以通过环境变量进行配置。 使用 --env
或 -e
CLI 选项传递它们 - 类似于 docker run
和 docker compose run
接口。
archery docker run --env CMAKE_BUILD_TYPE=release ubuntu-cpp
有关 C++ 构建中可用的环境变量,请参阅 ci/scripts/cpp_build.sh
脚本。
使用自定义命令运行镜像
自定义 docker 命令可以作为第二个参数传递给 archery docker run
。
以下示例在容器中启动一个交互式 bash
会话 - 这对以交互方式调试构建很有用
archery docker run ubuntu-cpp bash
使用增加的调试输出构建镜像
要启用额外的日志输出以进行调试,请将 --debug
标志传递给 archery
。
archery --debug docker run ubuntu-cpp
除了启用 DEBUG
级别的日志记录外,这还会将 --progress=plain
传递给 docker(-compose) build 命令。
Docker 卷缓存#
大多数 compose 容器都将特定目录从主机挂载以重用 ccache
和 maven
工件。 这些 docker 卷位于 .docker
目录中。
要清理缓存,只需删除一个或多个目录(或整个 .docker
目录)。
开发#
Docker Compose 配置针对使用分层镜像的可重用开发容器进行了调整。 例如,多种语言绑定依赖于 C++ 实现,因此在构建 Glib、Ruby、R 和 Python 绑定时,我们可以重用完全相同的 C++ 基础镜像,而不是重新定义 C++ 环境和多个 Dockerfile。 这减少了重复并简化了维护,但使 Docker Compose 配置更加复杂。
Docker 构建参数#
构建时参数被下推到 dockerfile 以使镜像构建更灵活。 这些参数通常被称为 docker build args,但我们将这些值作为环境变量传递给 docker-compose.yml。 构建参数广泛用于
定义用于缓存的 docker 注册表
平台架构
操作系统和版本
定义各种版本的依赖项
默认参数值存储在顶级 .env 文件中。 有关详细示例,请参阅 docker-compose.yml。
构建脚本#
在 ci/scripts 目录下维护的脚本应该保持参数化,但应尽可能最小化,以清晰地封装其负责的任务。 例如
cpp_build.sh
:构建 C++ 实现而不运行测试。cpp_test.sh
:执行 C++ 测试。python_build.sh
:构建 Python 绑定而不运行测试。python_test.sh
:执行 Python 测试。docs_build.sh
:构建 Sphinx 文档。integration_dask.sh
:执行 dask 集成测试。integration_pandas.sh
:执行 pandas 集成测试。install_minio.sh
:为多个平台安装 minio 服务器。install_conda.sh
:为多个平台安装 miniconda。install_gcs_testbench.sh
:为多个平台安装 GCS 测试平台。
参数化(如 C++ CMake 选项)是通过具有有用默认值的环境变量来实现的,以保持构建配置的声明性。
一个很好的例子是 cpp_build.sh
构建脚本,它将环境变量转发为 CMake 选项 - 因此可以在各种配置中调用相同的脚本,而无需更改它。 有关示例,请参阅 docker-compose.yml 的 C++ 镜像中如何传递环境变量。
添加新镜像#
请参阅 docker-compose.yml 文件中提供的内联注释。