如何使用rules_oci构建镜像并通过Docker本地运行?
问题:使用rules_oci构建Docker镜像后运行报错
test.sh: executable file not found in $PATH 我尝试用rules_oci构建可本地运行的Docker镜像,相关配置及操作如下:
WORKSPACE.bazel
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") #------------------------------------------------------- # rules_oci #------------------------------------------------------- http_archive( name = "rules_oci", sha256 = "176e601d21d1151efd88b6b027a24e782493c5d623d8c6211c7767f306d655c8", strip_prefix = "rules_oci-1.2.0", url = "https://github.com/bazel-contrib/rules_oci/releases/download/v1.2.0/rules_oci-v1.2.0.tar.gz", ) load("@rules_oci//oci:dependencies.bzl", "rules_oci_dependencies") rules_oci_dependencies() load("@rules_oci//oci:repositories.bzl", "LATEST_CRANE_VERSION", "LATEST_ZOT_VERSION", "oci_register_toolchains") oci_register_toolchains( name = "oci", crane_version = LATEST_CRANE_VERSION, ) load("@rules_oci//oci:pull.bzl", "oci_pull") oci_pull( name = "ubuntu", digest = "sha256:67211c14fa74f070d27cc59d69a7fa9aeff8e28ea118ef3babc295a0428a6d21", image = "ubuntu", platforms = [ "linux/arm64/v8", "linux/amd64", ], ) #------------------------------------------------------- # rules_pkg #------------------------------------------------------- load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") http_archive( name = "rules_pkg", sha256 = "8f9ee2dc10c1ae514ee599a8b42ed99fa262b757058f65ad3c384289ff70c4b8", urls = [ "https://mirror.bazel.build/github.com/bazelbuild/rules_pkg/releases/download/0.9.1/rules_pkg-0.9.1.tar.gz", "https://github.com/bazelbuild/rules_pkg/releases/download/0.9.1/rules_pkg-0.9.1.tar.gz", ], ) load("@rules_pkg//:deps.bzl", "rules_pkg_dependencies") rules_pkg_dependencies()
BUILD.bazel
load("@rules_oci//oci:defs.bzl", "oci_image", "oci_tarball") load("@rules_pkg//:pkg.bzl", "pkg_tar") pkg_tar( name = "app", srcs = ["test.sh"], ) oci_image( name = "image", base = "@ubuntu", cmd = ["test.sh"], tars = ["app.tar"], ) oci_tarball( name = "tarball", image = ":image", repo_tags = ["vertexwahn/my_example:v0.0.1"], )
test.sh
echo "Hello World!"
.bazelversion
6.3.2
执行命令:
# 创建镜像 bazel run //:tarball # 运行容器 sudo docker run vertexwahn/my_example:v0.0.1
报错信息:
docker: Error response from daemon: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: exec: "test.sh": executable file not found in $PATH: unknown.
解决方案
核心问题分析
pkg_tar默认将文件打包到根目录,但该目录不在容器默认$PATH中,导致无法通过相对路径找到test.shtest.sh未添加可执行权限,即使路径正确也无法运行oci_image的cmd引用了未在$PATH中的相对路径
方案1:修改现有WORKSPACE模式配置
更新BUILD.bazel
调整pkg_tar将文件放到$PATH包含的目录,并添加可执行权限,同时修正tars引用路径:
load("@rules_oci//oci:defs.bzl", "oci_image", "oci_tarball") load("@rules_pkg//:pkg.bzl", "pkg_tar") pkg_tar( name = "app", srcs = ["test.sh"], # 将test.sh安装到容器默认$PATH包含的/usr/local/bin目录 package_dir = "/usr/local/bin", # 给脚本添加可执行权限 mode = "0755", ) oci_image( name = "image", base = "@ubuntu", cmd = ["test.sh"], tars = [":app"], # 直接引用bazel目标,无需手动加.tar后缀 ) oci_tarball( name = "tarball", image = ":image", repo_tags = ["vertexwahn/my_example:v0.0.1"], )
验证执行
重新构建并运行:
bazel run //:tarball sudo docker run vertexwahn/my_example:v0.0.1
方案2:使用Bzlmod模式(Bazel 6+推荐)
替换WORKSPACE为MODULE.bazel
删除原WORKSPACE文件,创建MODULE.bazel:
module( name = "rules_oci_demo", version = "0.0.1", ) bazel_dep(name = "rules_oci", version = "1.2.0") bazel_dep(name = "rules_pkg", version = "0.9.1") # 拉取ubuntu基础镜像 oci_pull( name = "ubuntu", digest = "sha256:67211c14fa74f070d27cc59d69a7fa9aeff8e28ea118ef3babc295a0428a6d21", image = "ubuntu", platforms = [ "linux/arm64/v8", "linux/amd64", ], )
BUILD.bazel保持方案1的修改内容
直接使用方案1中更新后的BUILD.bazel即可。
验证执行
执行相同的构建和运行命令即可。
其他可选方案
如果不想将文件放到/usr/local/bin,也可以:
- 在
oci_image中使用绝对路径指定cmd,比如cmd = ["/test.sh"],同时设置pkg_tar的package_dir = "/"并给文件加可执行权限 - 在
oci_image中添加环境变量扩展$PATH,比如env = {"PATH": "$PATH:/custom/path"},同时将test.sh打包到/custom/path目录
内容的提问来源于stack exchange,提问作者Vertexwahn
相关产品推荐
相关产品推荐

