dockerbazelrules-oci

How to use rules_oci to run an image local via Docker?


I want to use rules_oci to build a (docker) image that I can run locally as a container. Here is my try:

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

If run:

# List all images
docker image ls
# Create an image
bazel run //:tarball
# Run docker container and delete it on quit
sudo docker run vertexwahn/my_example:v0.0.1

I get the following error:

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.

Any ideas on how to solve this issue? I can also live with a bzlmod solution.

The code can also be found here.


Solution

  • The answer provided above was mildly incorrect. Here is a full correction for BUILD.bazel:

    load("@rules_oci//oci:defs.bzl", "oci_image", "oci_push", "oci_tarball")
    load("@rules_pkg//:pkg.bzl", "pkg_tar")
    
    pkg_tar(
        name = "app",
        srcs = ["test.sh"],
        mode = "0755",
        package_dir = "/usr/bin"
    )
    
    oci_image(
        name = "image",
        base = "@ubuntu",
        cmd = ["test.sh"],
        tars = [":app"],
    )
    
    oci_tarball(
        name = "tarball",
        image = ":image",
        repo_tags = ["vertexwahn/my_example:v0.0.1"],
    )
    
    oci_push(
        name = "push",
        image = ":image",
        remote_tags = ["v0.0.1"],
        repository = "vertexwahn/my_example",
    )
    

    And, for test.sh:

    #!/usr/bin/sh
    
    echo "Hello World!"
    

    The previous answer struggled to get the execution working properly (path issue and stuff).

    Note: you can use docker save to get the image in some kind of archive format and typically use mc (midnight commander) to navigate within the archive and the archive in the archive. You'll see that there is no /bin folder but only /usr/bin. Hence the fix. A shebang can't hurt, too...