A repository rule to pull image layers using Bazel's downloader.
Typical usage in WORKSPACE.bazel
:
load("@rules_oci//oci:pull.bzl", "oci_pull")
# A single-arch base image
oci_pull(
name = "distroless_java",
digest = "sha256:161a1d97d592b3f1919801578c3a47c8e932071168a96267698f4b669c24c76d",
image = "gcr.io/distroless/java17",
platforms = ["linux/amd64"], # Optional
)
# A multi-arch base image
oci_pull(
name = "distroless_static",
digest = "sha256:c3c3d0230d487c0ad3a0d87ad03ee02ea2ff0b3dcce91ca06a1019e07de05f12",
image = "gcr.io/distroless/static",
platforms = [
"linux/amd64",
"linux/arm64",
],
)
# A multi-arch base image with variants, note that it won't work with just "linux/arm64"
oci_pull(
name = "distroless_base_nossl_debian12",
digest = "sha256:73c3d3f3030516665c916ebc9baa80f89c1a90e438dc02f1fed525ed246c0c2a",
image = "gcr.io/distroless/base-nossl-debian12",
platforms = [
"linux/amd64",
"linux/arm64/v8",
],
)
Typical usage in MODULE.bazel
:
oci = use_extension("@rules_oci//oci:extensions.bzl", "oci")
# A multi-arch base image with variants, note that it won't work with just "linux/arm64"
oci.pull(
name = "distroless_base_nossl_debian12",
digest = "sha256:73c3d3f3030516665c916ebc9baa80f89c1a90e438dc02f1fed525ed246c0c2a",
image = "gcr.io/distroless/base-nossl-debian12",
platforms = [
"linux/amd64",
"linux/arm64/v8",
],
)
use_repo(
oci,
"distroless_base_nossl_debian12",
"distroless_base_nossl_debian12_linux_amd64",
"distroless_base_nossl_debian12_linux_arm64_v8",
)
Now you can refer to these as a base layer in BUILD.bazel
.
The target is named the same as the external repo, so you can use a short label syntax:
oci_image(
name = "app",
base = "@distroless_static",
...
)
oci_image(
name = "app_arm64_v8",
base = "@distroless_base_nossl_debian12_linux_arm64_v8",
...
)
Docker specifies a standard location where registry credentials are stored: https://docs.docker.com/engine/reference/commandline/cli/#configuration-files
We search for this file in several locations, following the logic at https://github.com/google/go-containerregistry/tree/main/pkg/authn#tldr-for-consumers-of-this-package.
Set --repo_env=DOCKER_CONFIG=/some/other/directory
to cause oci_pull
to look for
config.json
in this directory instead.
Finally, some less-common use cases are afforded with environment variables XDG_RUNTIME_DIR
and REGISTRY_AUTH_FILE
.
See the implementation of _get_auth_file_path
in /oci/private/auth_config_locator.bzl
for the complete reference.
By default oci_pull try to mimic docker pull
authentication mechanism to allow users simply use docker login
for authentication.
However, this doesn't always work due to some limitations of Bazel where response headers can't be read, which prevents us from
performing WWW-Authenticate
challenges, as we don't know which endpoint to hit to complete the challenge. To workaround this
we keep a map of known registries that require us to perform www-auth challenge to acquire a temporary token for authentication.
Fortunately, Bazel supports running external programs to authenticate http requests using the --credential_helper
command line flag.
When the credential helper flag passed, Bazel will call the external program before sending the request to allow additional headers to be set.
An example of this
.bazelrc
common --credential_helper=public.ecr.aws=%workspace%/tools/auth.sh
tools/auth.sh
input=$(cat)
uri=$(jq -r ".uri" <<< $input)
host="$(echo $uri | awk -F[/:] '{print $4}')"
curl -fsSL https://$host/token | jq '{headers:{"Authorization": [("Bearer " + .token)]}}'
This tells bazel to run %workspace%/tools/auth.sh
for any request sent to public.ecr.aws
and add additional headers that may have been
printed to stdout
by the external program.
For more information about the credential helpers checkout the documentation.
See the examples/credential_helper directory for an example of how this work.
oci_pull(name, image, repository, registry, platforms, digest, tag, reproducible, is_bzlmod, config, bazel_tags)
Repository macro to fetch image manifest data from a remote docker registry.
To use the resulting image, you can use the @wkspc
shorthand label, for example
if name = "distroless_base"
, then you can just use base = "@distroless_base"
in rules like oci_image
.
This shorthand syntax is broken on the command-line prior to Bazel 6.2. See bazelbuild/bazel#4385
PARAMETERS