{"id":30339004,"url":"https://github.com/bazel-contrib/rules_img","last_synced_at":"2026-04-14T11:01:19.832Z","repository":{"id":308699827,"uuid":"996792209","full_name":"bazel-contrib/rules_img","owner":"bazel-contrib","description":"Modern Bazel rules for building OCI container images with advanced performance optimizations","archived":false,"fork":false,"pushed_at":"2026-04-10T05:00:27.000Z","size":4718,"stargazers_count":110,"open_issues_count":28,"forks_count":24,"subscribers_count":3,"default_branch":"main","last_synced_at":"2026-04-10T07:09:49.300Z","etag":null,"topics":["bazel","containers","docker","kubernetes","oci"],"latest_commit_sha":null,"homepage":"https://registry.bazel.build/modules/rules_img","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bazel-contrib.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"open_collective":"bazel-rules-authors-sig"}},"created_at":"2025-06-05T13:22:13.000Z","updated_at":"2026-04-09T16:26:57.000Z","dependencies_parsed_at":"2025-08-07T12:02:35.407Z","dependency_job_id":"f0634ee4-5ded-4bed-b14f-980a5f1b193a","html_url":"https://github.com/bazel-contrib/rules_img","commit_stats":null,"previous_names":["tweag/rules_img","bazel-contrib/rules_img"],"tags_count":35,"template":false,"template_full_name":null,"purl":"pkg:github/bazel-contrib/rules_img","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bazel-contrib%2Frules_img","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bazel-contrib%2Frules_img/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bazel-contrib%2Frules_img/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bazel-contrib%2Frules_img/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bazel-contrib","download_url":"https://codeload.github.com/bazel-contrib/rules_img/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bazel-contrib%2Frules_img/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31793225,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-14T02:24:21.117Z","status":"ssl_error","status_checked_at":"2026-04-14T02:24:20.627Z","response_time":153,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bazel","containers","docker","kubernetes","oci"],"created_at":"2025-08-18T07:01:15.148Z","updated_at":"2026-04-14T11:01:19.824Z","avatar_url":"https://github.com/bazel-contrib.png","language":"Go","funding_links":["https://opencollective.com/bazel-rules-authors-sig"],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n![rules_img logo](/.github/logo/light_hero.jpg#gh-light-mode-only)\n![rules_img logo](/.github/logo/dark_hero.jpg#gh-dark-mode-only)\n\n**Modern Bazel rules for building OCI container images with advanced performance optimizations**\n\nSupports both **Bzlmod** and **WORKSPACE** setups. For WORKSPACE setup instructions, see the [releases page](https://github.com/bazel-contrib/rules_img/releases).\n\n`rules_img` was originally written by (and receives ongoing support from) \u003cbr\u003e\n\u003ca target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://tweag.io/#gh-light-mode-only\"\u003e\u003cimg src=\"./docs/visuals/tweag_light_mode.svg\" alt=\"Tweag\" style=\"width: 10rem;\"\u003e\u003c/a\u003e\u003ca target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://tweag.io/#gh-dark-mode-only\"\u003e\u003cimg src=\"./docs/visuals/tweag_dark_mode.svg\" alt=\"Tweag\" style=\"width: 10rem;\"\u003e\u003c/a\u003e.\n\u003c/div\u003e\n\n## Features\n\n- 🚀 **High Performance** - Minimizes data transfer and embraces *Build without the Bytes* from source code to container runtime\n- 📦 **OCI Compliant** - Builds standard OCI images compatible with any container runtime\n- 🔧 **Bazel Native** - No Docker daemon required, fully hermetic builds\n- 🌍 **Multi-Platform** - Native cross-platform support through Bazel transitions\n- ⚡ **eStargz Support** - Lazy pulling optimization for faster container starts\n- 🪶 **Smaller layers** - Deduplicates files using hardlinks\n- 🎯 **Shallow Base Images** - Avoid downloading layers from huge base images like CUDA\n- 🏢 **Enterprise Ready** - Remote Build Execution and Content Addressable Storage integration\n\n## Installation\n\nAdd to your `MODULE.bazel`:\n\n```starlark\nbazel_dep(name = \"rules_img\", version = \"0.3.7\")\n```\n\n\u003cdetails\u003e\n\u003csummary\u003eConfigure default settings (optional) in \u003ccode\u003e.bazelrc\u003c/code\u003e\u003c/summary\u003e\n\n```\n# The compression algorithm to use (\"gzip\" or \"zstd\")\ncommon --@rules_img//img/settings:compress=zstd\n\n# Number of parallel compression workers (gzip only)\n# \"1\" uses single-threaded stdlib gzip, \"auto\" uses compilation mode defaults,\n# \"nproc\" uses all available CPUs, or specify a number (e.g., \"4\").\n# Any number above 1 uses pgzip, which results in slightly larger files,\n# but is otherwise fully compatible with the gzip format.\ncommon --@rules_img//img/settings:compression_jobs=auto\n\n# Compression level\n# gzip: 0-9, where 0=no compression, 1=fast compression, 9=best compression\n# zstd: 1-4, where 1=fast compression, 4=best compressions\n# \"auto\" uses compilation mode defaults (-1 for default, 1 for fastbuild, 9 for opt)\ncommon --@rules_img//img/settings:compression_level=auto\n\n# Support for seekable eStargz layers\n# with the containerd stargz-snapshotter\ncommon --@rules_img//img/settings:estargz=enabled\n\n# Create parent directory entries in tar files for all files\n# When enabled, parent directories are automatically created in the tar for all file entries.\n# This is disabled by default to avoid overwriting existing directory permissions in lower layers.\ncommon --@rules_img//img/settings:create_parent_directories=disabled\n\n# How to handle duplicate tree artifacts (directories) in layers.\n# \"full\" stores each tree at its intended path (no tree-level deduplication).\n# \"deduplicate_symlink\" replaces duplicate trees with symlinks to the first occurrence.\ncommon --@rules_img//img/settings:layer_tree_artifact_handling=full\n\n# Opt-in to stamping of image_push rules\ncommon --@rules_img//img/settings:stamp=disabled\n\n# The push strategy to use (see below for more info).\n# \"eager\", \"lazy\", \"cas_registry\", or \"bes\"\ncommon --@rules_img//img/settings:push_strategy=eager\n\n# The load strategy to use.\n# \"eager\" or \"lazy\"\ncommon --@rules_img//img/settings:load_strategy=eager\n\n# The daemon to target with image_load\n# \"docker\", \"containerd\", \"podman\", or \"generic\"\n# For \"generic\", set LOADER_BINARY environment variable at runtime\ncommon --@rules_img//img/settings:load_daemon=docker\n\n# Bazel remote cache to use for lazy pushing of container images.\n# Uses the same format as Bazel's --remote_cache flag.\n# Falls back to $IMG_REAPI_ENDPOINT env var.\ncommon --@rules_img//img/settings:remote_cache=grpcs://remote.buildbuddy.io\n\n# Credential helper to use for authenticating gRPC connections during push operations\n# in some push strategies.\n# This can be the same as Bazel's credential helper.\n# Falls back to $IMG_CREDENTIAL_HELPER env var.\ncommon --@rules_img//img/settings:credential_helper=tweag-credential-helper\n\n# Path to Docker configuration file for registry authentication.\n# If set, this will be used as REGISTRY_AUTH_FILE for authenticating to registries\n# when downloading image layers during build time (e.g., for lazy base image pulling).\n# Typically set to ~/.docker/config.json or similar.\ncommon --@rules_img//img/settings:docker_config_path=/home/user/.docker/config.json\n```\n\n\u003c/details\u003e\n\u003cbr/\u003e\n\n## Quick Start\n\n### Building a Simple Image\n\nAdd base image to `MODULE.bazel`:\n\n```starlark\npull = use_repo_rule(\"@rules_img//img:pull.bzl\", \"pull\")\n\npull(\n    name = \"ubuntu\",\n    digest = \"sha256:1e622c5f073b4f6bfad6632f2616c7f59ef256e96fe78bf6a595d1dc4376ac02\",\n    registry = \"index.docker.io\",\n    repository = \"library/ubuntu\",\n    tag = \"24.04\",\n)\n\npull(\n    name = \"cuda\",\n    digest = \"sha256:f353ffca86e0cd93ab2470fe274ecf766519c24c37ed58cc2f91d915f7ebe53c\",\n    registry = \"index.docker.io\",\n    repository = \"nvidia/cuda\",\n    tag = \"12.8.1-cudnn-devel-ubuntu20.04\",\n)\n```\n\nCompose images in `BUILD.bazel`:\n\n```starlark\nload(\"@rules_img//img:layer.bzl\", \"image_layer\")\nload(\"@rules_img//img:image.bzl\", \"image_manifest\")\n\n# Create a layer from files...\nimage_layer(\n    name = \"app_layer\",\n    srcs = {\n        \"/app/bin/server\": \"//cmd/server\",\n        \"/app/config\": \"//configs:prod\",\n    },\n    compress = \"zstd\",  # Use zstd compression (optional, uses global default otherwise)\n)\n\n# ... and a second layer (add as many as you need)\nimage_layer(\n    name = \"data_layer\",\n    srcs = {\"/data/logo.png\": \"@static_assets//:logo.png\"},\n)\n\n# Build a container image:\n# This will contain all layers from base (if set) and the layers given in \"layers\" (in the specified order).\n# Try to put frequently changing layers last for better performance.\nimage_manifest(\n    name = \"app_image\",\n    base = \"@ubuntu\", # Optional: build \"from scratch\" without base.\n    layers = [\n        \":data_layer\",\n        \":app_layer\",\n    ],\n    config_fragment = \"config.json\",  # Optional image configuration, uses sane defaults.\n)\n```\n\n### Multi-Platform Images\n\nIn most cases, you can just use the builtin transitions feature:\n\n```starlark\nload(\"@rules_img//img:image.bzl\", \"image_manifest\", \"image_index\")\n\n# Create platform-specific images\nimage_manifest(\n    name = \"app\",\n    layers = [\":app_layer\"],\n)\n\n# Combine into multi-platform index\nimage_index(\n    name = \"multiarch_app\",\n    manifests = [\":app\"],\n    platforms = [\n        \"//:linux_amd64\",\n        \"//:linux_arm64\",\n    ],\n)\n```\n\nFor more details on working with platforms, architecture variants, and building images for macOS Docker daemons, see the [Platforms Guide](docs/platforms.md).\n\n### Pushing to a Registry\n\n```starlark\nload(\"@rules_img//img:push.bzl\", \"image_push\")\n\nimage_push(\n    name = \"push\",\n    image = \":app\",\n    registry = \"ghcr.io\",\n    repository = \"my-project/app\",\n    tag = \"latest\",\n)\n```\n\nRun with:\n```bash\nbazel run //:push\n```\n\n### Registry Authentication\n\n`rules_img` uses [go-containerregistry](https://github.com/google/go-containerregistry) to interact with container registries, which provides automatic credential discovery from standard locations. This means authentication works the same way as with Docker CLI, Podman, and other container tools.\n\n#### Credential Discovery\n\nWhen pushing or pulling images, `rules_img` automatically searches for credentials in the following locations (in order):\n\n1. **`~/.docker/config.json`** - Standard Docker credential file\n2. **`$DOCKER_CONFIG/config.json`** - If the `DOCKER_CONFIG` environment variable is set\n3. **`${XDG_RUNTIME_DIR}/containers/auth.json`** - Podman credential file (typically `/run/user/1000/containers/auth.json`)\n\nAdditionally, for Google Container Registry (gcr.io, pkg.dev, etc.), `rules_img` registers the [Google keychain](https://pkg.go.dev/github.com/google/go-containerregistry/pkg/v1/google#Keychain) alongside the default keychain. This provides automatic authentication using Application Default Credentials (ADC), making it seamless to push/pull from GCR when running on Google Cloud or with `gcloud` configured locally.\n\nFor more details on how credential discovery works, see the [go-containerregistry keychain documentation](https://github.com/google/go-containerregistry/tree/main/pkg/authn#tldr-for-consumers-of-this-package).\n\n#### Setting up Credentials\n\nThe easiest way to configure credentials is using `docker login`:\n\n```bash\n# Login to Docker Hub\ndocker login\n\n# Login to a private registry\ndocker login ghcr.io\ndocker login registry.example.com\n\n# Login with username and password\ndocker login -u myusername registry.example.com\n```\n\nThese commands will store credentials in `~/.docker/config.json`, which `rules_img` will automatically use.\n\n#### Alternative: Podman\n\nIf you're using Podman, credentials are stored in a different location:\n\n```bash\npodman login registry.example.com\n```\n\nThis stores credentials in `${XDG_RUNTIME_DIR}/containers/auth.json`, which `rules_img` also automatically discovers.\n\n#### Bazel Sandbox and Authentication\n\nWhen Bazel runs actions in a sandbox (which is the default behavior), it may hide certain environment information like the current username and home directory. This can prevent `rules_img` from automatically finding your Docker credential files.\n\nIf you encounter authentication failures, you can explicitly configure the path to your Docker configuration file:\n\n```bash\n# In your .bazelrc or on the command line\ncommon --@rules_img//img/settings:docker_config_path=/home/username/.docker/config.json\n```\n\nReplace `/home/username/` with your actual home directory path. This setting affects:\n\n1. **Build-time blob downloads**: When downloading image layers during builds (e.g., lazy base image pulling or the `download_blobs` rule), the `REGISTRY_AUTH_FILE` environment variable is set to this path.\n2. **Push operations**: When running `image_push` targets with `bazel run`, this ensures authentication works correctly.\n3. **Load operations**: When running `image_load` targets with `bazel run`, credentials are available for any required registry access.\n4. **Multi-deploy operations**: When running `multi_deploy` targets, all combined operations can authenticate properly.\n\nAdditionally, the `DOCKER_CONFIG` environment variable is inherited from your shell environment for all push, load, and multi_deploy operations. This means you can also use the standard Docker environment variable as an alternative:\n\n```bash\n# Alternative: use DOCKER_CONFIG environment variable\nexport DOCKER_CONFIG=/path/to/docker/config/dir\nbazel run //:push_image\n```\n\n#### Troubleshooting\n\nIf you're experiencing authentication issues:\n\n1. **Verify credentials exist**: Check that `~/.docker/config.json` or `${XDG_RUNTIME_DIR}/containers/auth.json` contains the registry\n2. **Check permissions**: Ensure the credential file is readable by the user running Bazel\n3. **Environment variables**: If using `$DOCKER_CONFIG`, ensure it points to a directory containing `config.json`\n4. **Test with Docker/Podman**: If `docker pull` or `podman pull` works, `rules_img` should work too\n5. **Bazel sandbox issues**: If authentication works outside Bazel but fails during builds, try setting `--@rules_img//img/settings:docker_config_path` to your Docker config file path\n\nFor advanced authentication scenarios (credential helpers, custom authentication), refer to the [go-containerregistry authentication documentation](https://github.com/google/go-containerregistry/blob/main/cmd/crane/doc/crane.md#authenticating).\n\n### Language-specific examples\n\n* [C++](/e2e/cc/)\n* [Go](/e2e/go/)\n* [JS / TS](/e2e/js/)\n* [Python](/e2e/python/)\n* [Custom Distroless base image](/e2e/generic/custom_distroless_base_image/)\n\n## Comparison with rules_oci\n\nBoth `rules_img` and `rules_oci` are modern Bazel rulesets for building OCI container images. While they share the goal of hermetic, reproducible container builds, they take fundamentally different architectural approaches.\n`rules_oci` uses the [oci image layout][oci-image-layout] as an on-disk representation of container images at every step (base image pull, `oci_image` rule, `oci_image_index` rule).\nAdditionally, `rules_oci` chooses to use only off-the-shelf, pre-built tools for assembling images.\n`rules_img` chooses to use providers that contain just enough information as needed for subsequent steps. We also use customized tools, instead of prebuilt ones.\nThis results in a more complex implementation, but also allows for interesting optimizations.\n\n- ✅ [Shallow base image pulling](#shallow-base-image-pulling)\n- ✅ [Layers are produced in a single action](#single-action-layers)\n- ✅ [Deduplication of layer contents](#layer-optimization)\n- ✅ [Advanced push strategies](#advanced-push-strategies)\n- ✅ [eStargz support for lazy pulling](#estargz-lazy-pulling)\n- ✅ [Incremental loading into daemons](#incremental-loading)\n\n## Documentation\n\n- [API Reference](docs/)\n  - **Layer Rules**\n    - [`image_layer`](docs/layer.md#image_layer) - Create layers from files\n    - [`layer_from_tar`](docs/layer.md#layer_from_tar) - Create layers from tar archives\n    - [`file_metadata`](docs/layer.md#file_metadata) - Helper for specifying file attributes of `image_layer` rule.\n  - **Image Rules**\n    - [`image_manifest`](docs/image.md#image_manifest) - Build single-platform images\n    - [`image_index`](docs/image.md#image_index) - Build multi-platform image indexes\n    - [`image_manifest_from_oci_layout`](docs/convert.md#image_manifest_from_oci_layout) - Convert oci_image to image_manifest\n    - [`image_index_from_oci_layout`](docs/convert.md#image_index_from_oci_layout) - Convert oci_image_index to image_index\n  - **Push, Pull and Load Rules**\n    - [`pull`](docs/pull.md#pull) - Repository rule for pulling base images\n    - [`images.pull`](docs/extensions.md#images) - Module extension for pulling base images (EXPERIMENTAL)\n    - [`image_push`](docs/push.md#image_push) - Push images to registries\n    - [`image_load`](docs/load.md#image_load) - Load images into container daemons\n    - [`multi_deploy`](docs/multi_deploy.md#multi_deploy) - Deploy multiple operations as unified command\n- [Platforms Guide](docs/platforms.md) - Working with Bazel platforms, architecture variants, and multi-platform builds\n- [Migration Guide from rules_oci](docs/migration-from-rules_oci.md)\n\n## Key Differences Explained\n\n### Shallow Base Image Pulling\n\nUnlike rules_oci which downloads all layers of a base image, rules_img uses a \"shallow pull\" approach. When you reference a base image like CUDA (which can be 10+ GB), rules_img only downloads the manifest and config - not the actual layer blobs. The layers are only downloaded when and if they're needed during push operations.\n\nThis results in:\n- **Faster builds** - No waiting for large base image downloads\n- **Reduced bandwidth** - Only download what you actually use\n- **True Build-without-the-bytes** - Other rulesets download base layers to your local machine in a repository rule. This step cannot be remotely executed and is repeated on every machine running Bazel.\n\nExample with a large CUDA base image:\n```starlark\n# This won't download the 10GB of CUDA layers!\npull(\n    name = \"cuda\",\n    digest = \"sha256:...\",\n    registry = \"index.docker.io\",\n    repository = \"nvidia/cuda\",\n)\n```\n\n### Single Action Layers\n\nrules_img produces both the layer blob and its metadata in a single Bazel action. This design has several advantages:\n\n- **Remote execution friendly** - Single action works better with RBE\n- **Image Manifest only depends on metadata** - In rules_oci, image actions depend on the actual blobs of their base image and layers, which must be available during the manifest writing action.\n\nThe metadata includes the layer's digest, size, and diff ID, all computed during layer creation.\n\n### Layer Optimization\n\nWhen writing a tar layer, rules_img uses hardlinks to deduplicate identical files.\nThis allows for smaller container images.\n\n### Advanced Push Strategies\n\nrules_img offers four sophisticated push strategies compared to rules_oci's traditional approach. These strategies enable:\n- **Faster CI/CD** - Avoid unnecesary file transfer\n- **Build without the bytes** - Never materialize container layers on your local machine\n- **Scalability** - Designed for organizations with thousands of builds per day\n\n| Strategy | Description | Use Case | Requirements |\n|----------|-------------|----------|--------------|\n| [`eager`](docs/push-strategies.md#eager-push) | Traditional push, download all blobs to the machine running Bazel, then uploads all blobs. | Simple deployments | Normal container registry |\n| [`lazy`](docs/push-strategies.md#lazy-push) | Checks registry first, skips existing blobs and streams missing blobs from Bazel's remote cache | Faster CI/CD and Build without the Bytes | Bazel remote cache |\n| [`cas_registry`](docs/push-strategies.md#cas-registry-push) | Uses special container registry that is directly connected to Bazel's remote cache | Fast development cycles. | Special container registry (`cmd/registry`), Bazel remote cache |\n| [`bes`](docs/push-strategies.md#bes-push) | Image push happens as side-effect of BES upload. Requires self-hosted BES server. | Extremely fast and efficient for large organizations. | Special BES backend (`cmd/bes`), Bazel remote cache |\n\nSee the [Push Strategies Guide](docs/push-strategies.md) for detailed information about each strategy.\n\n### eStargz Lazy Pulling\n\nrules_img has first-class support for eStargz (enhanced stargz), enabling \"lazy pulling\" at container runtime. This means:\n\n- **Instant container starts** - Containers can start before all layers download\n- **Bandwidth savings** - Only accessed files are downloaded\n- **Seekable layers** - Random access to files within compressed layers\n\nCombined with containerd's stargz-snapshotter, this can reduce container startup time from minutes to seconds for large images.\n\n```starlark\nimage_layer(\n    name = \"optimized_layer\",\n    srcs = {...},\n    estargz = \"enabled\",  # Enable seekable compression\n)\n```\n\nThe same setting can be globally enabled using `--@rules_img//img/settings:estargz=enabled`.\nRead the [stargz-snapshotter documentation][stargz-snapshotter] for more information.\n\n### Incremental Loading\n\nrules_img loads images incrementally and efficiently by directly interfacing with the containerd API. This provides significant performance advantages over traditional approaches:\n\n- **Direct containerd integration** - When Docker is configured with containerd storage, rules_img bypasses `docker load` entirely\n- **Incremental blob loading** - Only new or changed layers are loaded, existing blobs are skipped\n- **Streaming architecture** - No temporary tar files or buffering entire images in memory\n- **Platform selection** - Load only the platforms you need from multi-platform images\n\nThe performance difference is dramatic, especially for large images:\n\n```bash\n# Load only the platform you need\nbazel run //my:image_load -- --platform linux/amd64\n\n# Incremental loading: only new layers are transferred\n# Second load of a slightly modified image is near-instant\nbazel run //my:image_load  # Only changed layers loaded!\n```\n\nWhen Docker doesn't support containerd storage, rules_img automatically falls back to `docker load` with a clear warning about the performance impact.\n\nThis is particularly powerful in development workflows where you're iterating on application layers while keeping large base images (like CUDA) unchanged - subsequent loads only transfer your small application layers.\n\n**Future Docker Support**: Docker is planning to expose its contentstore API in version 29.0.0, which will enable native incremental loading ([moby/moby#44369](https://github.com/moby/moby/issues/44369)). Once this ships, rules_img will adopt it to provide incremental loading performance even when the containerd socket isn't directly accesible by users. This will bring the same efficiency benefits to all Docker users, regardless of their platform or configuration.\n\n## Hacking \u0026 Contributing\n\nWe invite external contributions and are eager to work together with the build systems community. Please refer to the [CONTRIBUTING](/CONTRIBUTING.md) guide to learn more. If you want to check out the code and run a development version, follow the [HACKING](/HACKING.md) guide to get started.\n\n## Acknowledgments\n\nSpecial thanks to **Sushain Cherivirala** from Stripe for the inspiring BazelCon talk [\"Building 1300 Container Images in 4 Minutes\"](https://www.youtube.com/watch?v=c-yvIQooOSA). This talk introduced the groundbreaking idea of using the Build Event Service (BES) to sync container images between the remote cache and registry as a side effect. While their implementation was based on the now-archived rules_docker and was never published, it laid the conceptual foundation for our BES push strategy. Their work demonstrated how to achieve dramatic performance improvements in container image builds at scale, inspiring many of the optimizations in rules_img.\n\n[stargz-snapshotter]: https://github.com/containerd/stargz-snapshotter\n[oci-image-layout]: https://github.com/opencontainers/image-spec/blob/v1.1.1/image-layout.md\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbazel-contrib%2Frules_img","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbazel-contrib%2Frules_img","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbazel-contrib%2Frules_img/lists"}