Skip to content

Latest commit

 

History

History
222 lines (179 loc) · 19.8 KB

File metadata and controls

222 lines (179 loc) · 19.8 KB

Public API for container image push rules.

image_push

load("@rules_img//img:push.bzl", "image_push")

image_push(name, build_settings, cross_mount_from, deploy_tool, destination_file, image,
           manifest_tags, referrers, registry, repository, stamp, strategy, tag, tag_file, tag_list,
           tool_cfg)

Pushes container images to a registry.

This rule creates an executable target that uploads OCI images to container registries. It supports multiple push strategies optimized for different use cases, from simple uploads to advanced content-addressable storage integration.

Key features:

  • Multiple push strategies: Choose between eager, lazy, CAS-based, or BES-integrated pushing
  • Template expansion: Dynamic registry, repository, and tag values using build settings
  • Stamping support: Include build information in image tags
  • Incremental uploads: Skip blobs that already exist in the registry

The rule produces an executable that can be run with bazel run.

Example:

load("@rules_img//img:push.bzl", "image_push")

# Simple push to Docker Hub
image_push(
    name = "push_app",
    image = ":my_app",
    registry = "index.docker.io",
    repository = "myorg/myapp",
    tag = "latest",
)

# Push multi-platform image with multiple tags
image_push(
    name = "push_multiarch",
    image = ":my_app_index",  # References an image_index
    registry = "gcr.io",
    repository = "my-project/my-app",
    tag_list = ["latest", "v1.0.0"],
)

# Dynamic push with build settings
image_push(
    name = "push_dynamic",
    image = ":my_app",
    registry = "{{.REGISTRY}}",
    repository = "{{.PROJECT}}/my-app",
    tag = "{{.VERSION}}",
    build_settings = {
        "REGISTRY": "//settings:registry",
        "PROJECT": "//settings:project",
        "VERSION": "//settings:version",
    },
)

# Push with stamping for unique tags
image_push(
    name = "push_stamped",
    image = ":my_app",
    registry = "index.docker.io",
    repository = "myorg/myapp",
    tag = "latest-{{.BUILD_TIMESTAMP}}",
    stamp = "force",
)

# Digest-only push (no tag)
image_push(
    name = "push_by_digest",
    image = ":my_app",
    registry = "gcr.io",
    repository = "my-project/my-app",
    # No tag specified - will push by digest only
)

# Push using a destination file (instead of registry/repository attributes)
image_push(
    name = "push_from_file",
    image = ":my_app",
    destination_file = ":push_destination.txt",
    tag = "latest",
)

Push strategies:

  • eager: Materializes all layers next to push binary. Simple, correct, but may be inefficient.
  • lazy: Layers are not stored locally. Missing layers are streamed from Bazel's remote cache.
  • cas_registry: Uses content-addressable storage for extreme efficiency. Requires CAS-enabled infrastructure.
  • bes: Image is pushed as side-effect of Build Event Stream upload. No "bazel run" command needed. Requires Build Event Service integration.

See push strategies documentation for detailed comparisons.

Runtime usage:

# Push to registry
bazel run //path/to:push_app

# The push command will output the image digest

ATTRIBUTES

Name Description Type Mandatory Default
name A unique name for this target. Name required
build_settings Build settings for template expansion.

Maps template variable names to string_flag targets. These values can be used in registry, repository, and tag attributes using {{.VARIABLE_NAME}} syntax (Go template).

Example:
build_settings = {
    "REGISTRY": "//settings:docker_registry",
    "VERSION": "//settings:app_version",
}


See template expansion for more details.
Dictionary: String -> Label optional {}
cross_mount_from An image_push target whose layers may be cross-mounted during push. Label optional None
deploy_tool Optional label of a deploy tool target providing DeployToolInfo (created with img_deploy_tool from @rules_img//img:deploy_tool.bzl). When set, overrides tool_cfg. Label optional None
destination_file File containing the push destination as {registry}/{repository}.

The file should contain a single line with the registry and repository separated by the first /. For example: gcr.io/my-project/my-app.

The content is read as a literal string without Go template expansion. Trailing newlines and whitespace are stripped.

Cannot be used together with registry or repository attributes.
Label optional None
image Image to push. Should provide ImageManifestInfo or ImageIndexInfo. Label required
manifest_tags Per-platform tag templates for multi-platform (image_index) pushes.

Only valid when image provides ImageIndexInfo. For each entry in this list, the deploy command produces one tag per child manifest in the index by expanding the entry against the platform descriptor of that manifest.

Available template variables (lowercase):

- {{.os}} — platform OS (e.g. linux) - {{.architecture}}, {{.arch}}, {{.cpu}} — architecture (e.g. amd64, arm64) - {{.variant}} — architecture variant (e.g. v8), if set

The tags in tag / tag_list / tag_file continue to point at the index as a whole; manifest_tags complement those by publishing additional tags that each resolve to a single child manifest.

Example:

image_push(
    name = "push_multiarch",
    image = ":my_app_index",
    registry = "gcr.io",
    repository = "my-project/my-app",
    tag_list = ["latest", "v1.0.0"],
    manifest_tags = [
        "latest-{{.os}}-{{.architecture}}",
        "v1.0.0-{{.os}}-{{.architecture}}",
    ],
)


Templates are expanded at build time per child manifest, so build_settings and stamping variables are available (and override any platform variable of the same name). The expanded tags are emitted as registry_tag operations in the deploy manifest, so non-CLI strategies like bes can honor them.
List of strings optional []
referrers Additional manifests or indexes to push as referrers to the main image.

Each referrer is pushed to the same registry and repository as the main image, but without tags (referrers are discovered via the OCI referrers API by digest).

Each target must provide ImageManifestInfo or ImageIndexInfo and must have its subject field set to reference the main image being pushed.

Example:
image_push(
    name = "push",
    image = ":my_app",
    referrers = [
        ":sbom_manifest",
        ":signature_manifest",
    ],
    registry = "ghcr.io",
    repository = "myorg/myapp",
    tag = "latest",
)
List of labels optional []
registry Registry URL to push the image to.

Common registries: - Docker Hub: index.docker.io - Google Container Registry: gcr.io or us.gcr.io - GitHub Container Registry: ghcr.io - Amazon ECR: 123456789.dkr.ecr.us-east-1.amazonaws.com

Subject to template expansion.
String optional ""
repository Repository path within the registry.

Subject to template expansion.
String optional ""
stamp Controls build stamping for template expansion.

- auto (default): Defers to the global --@rules_img//img/settings:stamp setting. - force: Always stamp if templates contain {{}} placeholders, ignoring Bazel's --stamp flag. - disabled: Never include stamp information.

See template expansion for available stamp variables.
String optional "auto"
strategy Push strategy to use.

See push strategies documentation for detailed information.
String optional "auto"
tag Tag to apply to the pushed image.

Optional - if omitted, the image is pushed by digest only.

Subject to template expansion.
String optional ""
tag_file File containing newline-delimited tags to apply to the pushed image.

The file should contain one tag per line. Empty lines are ignored. Tags from this file are merged with tags specified via tag or tag_list attributes.

Example file content:
latest
v1.0.0
stable


Can be combined with tag or tag_list to merge tags from multiple sources. Each tag is subject to template expansion.
Label optional None
tag_list List of tags to apply to the pushed image.

Useful for applying multiple tags in a single push:

tag_list = ["latest", "v1.0.0", "stable"]


Cannot be used together with tag. Can be combined with tag_file to merge tags from both sources. Each tag is subject to template expansion.
List of strings optional []
tool_cfg Configuration of the pusher executable platform.

Available options: - host (default): Pusher executable matches the host platform. - target: Pusher executable matches the target platform(s) specified via --platforms.
String optional "host"

image_push_spec

load("@rules_img//img:push.bzl", "image_push_spec")

image_push_spec(name, build_settings, cross_mount_from, destination_file, manifest_tags, referrers,
                registry, repository, stamp, strategy, tag, tag_file, tag_list)

Defines push configuration for container images without referencing a specific image.

This rule captures registry, repository, tag, and strategy settings that can be attached to image_manifest or image_index targets via their push_specs attribute. Template strings using Go template syntax ({{.VAR}}) are accepted but not expanded — expansion happens when the deployment is consumed by the image rule. Note that the template strings {{.image_target_package}} and {{.image_target_name}} are especially useful here.

This enables an inverted dependency pattern: instead of image_push depending on the image, the image itself carries its deployment configuration, making it directly usable with multi_deploy.

Example:

load("@rules_img//img:push.bzl", "image_push_spec")

image_push_spec(
    name = "push_config",
    registry = "gcr.io",
    repository = "my-project/{{.image_target_package}}/{{.image_target_name}}",
    tag = "{{.VERSION}}",
    build_settings = {
        "VERSION": "//settings:version",
    },
    stamp = "force",
)

# Attach to an image:
image_manifest(
    name = "my_app_a",
    base = "@distroless_cc",
    layers = [":app_layer"],
    push_specs = [":push_config"],
)

# Attach to another image:
image_manifest(
    name = "my_app_b",
    base = "@distroless_cc",
    layers = [":app_layer"],
    push_specs = [":push_config"],
)

# Now usable directly in multi_deploy:
multi_deploy(
    name = "deploy",
    operations = [
        ":my_app_a",
        ":my_app_b",
    ],
)

ATTRIBUTES

Name Description Type Mandatory Default
name A unique name for this target. Name required
build_settings Build settings for template expansion.

Maps template variable names to string_flag targets. These values can be used in registry, repository, and tag attributes using {{.VARIABLE_NAME}} syntax (Go template).

Example:
build_settings = {
    "REGISTRY": "//settings:docker_registry",
    "VERSION": "//settings:app_version",
}


See template expansion for more details.
Dictionary: String -> Label optional {}
cross_mount_from An image_push target whose layers may be cross-mounted during push. Label optional None
destination_file File containing the push destination as {registry}/{repository}.

The file should contain a single line with the registry and repository separated by the first /. For example: gcr.io/my-project/my-app.

The content is read as a literal string without Go template expansion. Trailing newlines and whitespace are stripped.

Cannot be used together with registry or repository attributes.
Label optional None
manifest_tags Per-platform tag templates for multi-platform (image_index) pushes.

Only valid when image provides ImageIndexInfo. For each entry in this list, the deploy command produces one tag per child manifest in the index by expanding the entry against the platform descriptor of that manifest.

Available template variables (lowercase):

- {{.os}} — platform OS (e.g. linux) - {{.architecture}}, {{.arch}}, {{.cpu}} — architecture (e.g. amd64, arm64) - {{.variant}} — architecture variant (e.g. v8), if set

The tags in tag / tag_list / tag_file continue to point at the index as a whole; manifest_tags complement those by publishing additional tags that each resolve to a single child manifest.

Example:

image_push(
    name = "push_multiarch",
    image = ":my_app_index",
    registry = "gcr.io",
    repository = "my-project/my-app",
    tag_list = ["latest", "v1.0.0"],
    manifest_tags = [
        "latest-{{.os}}-{{.architecture}}",
        "v1.0.0-{{.os}}-{{.architecture}}",
    ],
)


Templates are expanded at build time per child manifest, so build_settings and stamping variables are available (and override any platform variable of the same name). The expanded tags are emitted as registry_tag operations in the deploy manifest, so non-CLI strategies like bes can honor them.
List of strings optional []
referrers Additional manifests or indexes to push as referrers to the main image.

Each referrer is pushed to the same registry and repository as the main image, but without tags (referrers are discovered via the OCI referrers API by digest).

Each target must provide ImageManifestInfo or ImageIndexInfo and must have its subject field set to reference the main image being pushed.

Example:
image_push(
    name = "push",
    image = ":my_app",
    referrers = [
        ":sbom_manifest",
        ":signature_manifest",
    ],
    registry = "ghcr.io",
    repository = "myorg/myapp",
    tag = "latest",
)
List of labels optional []
registry Registry URL to push the image to.

Common registries: - Docker Hub: index.docker.io - Google Container Registry: gcr.io or us.gcr.io - GitHub Container Registry: ghcr.io - Amazon ECR: 123456789.dkr.ecr.us-east-1.amazonaws.com

Subject to template expansion.
String optional ""
repository Repository path within the registry.

Subject to template expansion.
String optional ""
stamp Controls build stamping for template expansion.

- auto (default): Defers to the global --@rules_img//img/settings:stamp setting. - force: Always stamp if templates contain {{}} placeholders, ignoring Bazel's --stamp flag. - disabled: Never include stamp information.

See template expansion for available stamp variables.
String optional "auto"
strategy Push strategy to use.

See push strategies documentation for detailed information.
String optional "auto"
tag Tag to apply to the pushed image.

Optional - if omitted, the image is pushed by digest only.

Subject to template expansion.
String optional ""
tag_file File containing newline-delimited tags to apply to the pushed image.

The file should contain one tag per line. Empty lines are ignored. Tags from this file are merged with tags specified via tag or tag_list attributes.

Example file content:
latest
v1.0.0
stable


Can be combined with tag or tag_list to merge tags from multiple sources. Each tag is subject to template expansion.
Label optional None
tag_list List of tags to apply to the pushed image.

Useful for applying multiple tags in a single push:

tag_list = ["latest", "v1.0.0", "stable"]


Cannot be used together with tag. Can be combined with tag_file to merge tags from both sources. Each tag is subject to template expansion.
List of strings optional []