使用Bazel构建Docker镜像时含Bazel文件的目录无法拷贝到容器怎么办
问题根因
Bazel 以目录下的 BUILD/BUILD.bazel 文件作为 package 边界,上层 package 中的 glob 规则默认无法穿透到包含构建文件的子 package 中匹配文件。你使用的 glob(["scripts/**"]) 会在匹配到 scripts 目录下存在 Bazel 构建文件时直接终止该路径下的递归匹配,最终匹配结果为空,因此 pkg_tar 打包出来的产物没有任何内容,自然不会有文件被拷贝到容器中。
另外 Bazel 的 glob 函数默认会自动排除所有 Bazel 构建相关文件(包括 *.bzl、BUILD、BUILD.bazel 等),就算匹配到路径也不会默认包含这类文件。
解决方案
根据你的使用场景可以选择以下任意一种方案:
- 方案1:无需保留scripts目录作为独立Bazel package,直接删除scripts目录下的所有
BUILD/BUILD.bazel/*.bzl构建文件即可,该方案你已经验证可以生效。 - 方案2:需要保留scripts目录的构建文件,先在scripts目录的BUILD文件中定义filegroup导出所有需要打包的文件:
# scripts/BUILD 内容 filegroup( name = "all_scripts", srcs = glob(["**"], exclude = []), # exclude设为空可以把构建文件也包含进去 visibility = ["//visibility:public"], )
然后修改上层的pkg_tar配置,直接引用该filegroup:
pkg_tar( name = "scripts-dir", srcs = ["//scripts:all_scripts"], strip_prefix = "scripts", # 去掉本地路径前缀 package_dir = "/scripts", # 容器内对应的挂载路径 )
- 方案3:临时关闭Bazel的package边界匹配限制,在构建命令中添加参数
--incompatible_glob_filter_subpackage_files=false,同时把glob改为glob(["scripts/**"], exclude = [], allow_empty=False),该方案会破坏Bazel的package隔离逻辑,不推荐长期使用。
内容的提问来源于stack exchange,提问作者Mohammed
相关产品推荐
相关产品推荐

