{"id":13452326,"url":"https://github.com/bazelbuild/rules_docker","last_synced_at":"2025-05-14T02:07:20.164Z","repository":{"id":37745873,"uuid":"86749899","full_name":"bazelbuild/rules_docker","owner":"bazelbuild","description":"Rules for building and handling Docker images with Bazel","archived":false,"fork":false,"pushed_at":"2025-04-17T16:40:56.000Z","size":12053,"stargazers_count":1084,"open_issues_count":67,"forks_count":698,"subscribers_count":55,"default_branch":"master","last_synced_at":"2025-05-12T04:52:15.254Z","etag":null,"topics":["bazel","bazel-rules","cloud","docker","docker-image","google"],"latest_commit_sha":null,"homepage":"","language":"Starlark","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/bazelbuild.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":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":"AUTHORS","dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-03-30T21:19:58.000Z","updated_at":"2025-05-10T15:20:48.000Z","dependencies_parsed_at":"2025-01-14T18:59:16.965Z","dependency_job_id":"233e6b66-0f15-49aa-b636-04b1a20bf578","html_url":"https://github.com/bazelbuild/rules_docker","commit_stats":{"total_commits":1220,"total_committers":263,"mean_commits":4.638783269961977,"dds":0.85,"last_synced_commit":"3040e1fd74659a52d1cdaff81359f57ee0e2bb41"},"previous_names":[],"tags_count":37,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bazelbuild%2Frules_docker","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bazelbuild%2Frules_docker/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bazelbuild%2Frules_docker/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bazelbuild%2Frules_docker/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bazelbuild","download_url":"https://codeload.github.com/bazelbuild/rules_docker/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254052802,"owners_count":22006717,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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","bazel-rules","cloud","docker","docker-image","google"],"created_at":"2024-07-31T07:01:20.711Z","updated_at":"2025-05-14T02:07:15.151Z","avatar_url":"https://github.com/bazelbuild.png","language":"Starlark","readme":"# Bazel Container Image Rules\n\n| Bazel CI |\n| :------: |\n[![Build status](https://badge.buildkite.com/693d7892250cfd44beea3cd95573388200935906a28cd3146d.svg?branch=master)](https://buildkite.com/bazel/docker-rules-docker-postsubmit)\n\n## Status\n\n🚨 rules_docker is maintained on an as-needed basis. Please see\n[rules_oci](https://github.com/bazel-contrib/rules_oci) for an alternative. This\nrepo was previously archived in Oct 2023, then unarchived Nov 2024 as\nrules_docker remains a dependency for many projects.  Having it in an unarchived\nstate permits the community to post new issues, workarounds, and maintainance\nand security pull requests.\n\n## Basic Rules\n\n* [container_image](/docs/container.md#container_image) ([example](#container_image))\n* [container_bundle](/docs/container.md#container_bundle) ([example](#container_bundle))\n* [container_import](/docs/container.md#container_import)\n* [container_load](/docs/container.md#container_load)\n* [container_pull](/docs/container.md#container_pull) ([example](#container_pull))\n* [container_push](/docs/container.md#container_push) ([example](#container_push))\n\nThese rules used to be `docker_build`, `docker_push`, etc. and the aliases for\nthese (mostly) legacy names still exist largely for backwards-compatibility.  We\nalso have **early-stage** `oci_image`, `oci_push`, etc. aliases for folks that\nenjoy the consistency of a consistent rule prefix.  The only place the\nformat-specific names currently do any more than alias things is in `foo_push`,\nwhere they also specify the appropriate format as which to publish the image.\n\n### Overview\n\nThis repository contains a set of rules for pulling down base images, augmenting\nthem with build artifacts and assets, and publishing those images.\n**These rules do not require / use Docker for pulling, building, or pushing\nimages.**  This means:\n\n* They can be used to develop Docker containers on OSX without\n`boot2docker` or `docker-machine` installed. Note use of these rules on Windows\nis currently not supported.\n* They do not require root access on your workstation.\n\nAlso, unlike traditional container builds (e.g. Dockerfile), the Docker images\nproduced by `container_image` are deterministic / reproducible.\n\nTo get started with building Docker images, check out the\n[examples](https://github.com/bazelbuild/rules_docker/tree/master/testing/examples)\nthat build the same images using both rules_docker and a Dockerfile.\n\n__NOTE:__ `container_push` and `container_pull` make use of\n[google/go-containerregistry](https://github.com/google/go-containerregistry) for\nregistry interactions.\n\n## Language Rules\n\n* [py_image](#py_image) ([signature](\nhttps://docs.bazel.build/versions/master/be/python.html#py_binary))\n* [py3_image](#py3_image) ([signature](\nhttps://docs.bazel.build/versions/master/be/python.html#py_binary))\n* [nodejs_image](#nodejs_image) ([usage](\nhttps://github.com/bazelbuild/rules_nodejs#usage))\n* [java_image](#java_image) ([signature](\nhttps://docs.bazel.build/versions/master/be/java.html#java_binary))\n* [war_image](#war_image) ([signature](\nhttps://docs.bazel.build/versions/master/be/java.html#java_library))\n* [scala_image](#scala_image) ([signature](\nhttps://github.com/bazelbuild/rules_scala#scala_binary))\n* [groovy_image](#groovy_image) ([signature](\nhttps://github.com/bazelbuild/rules_groovy#groovy_binary))\n* [cc_image](#cc_image) ([signature](\nhttps://docs.bazel.build/versions/master/be/c-cpp.html#cc_binary))\n* [go_image](#go_image) ([signature](\nhttps://github.com/bazelbuild/rules_go#go_binary))\n* [rust_image](#rust_image) ([signature](\nhttps://github.com/bazelbuild/rules_rust#rust_binary))\n* [d_image](#d_image) ([signature](\nhttps://github.com/bazelbuild/rules_d#d_binary))\n\nIt is notable that: `cc_image`, `go_image`, `rust_image`, and `d_image`\nalso allow you to specify an external binary target.\n\n## Docker Rules\n\nThis repo now includes rules that provide additional functionality\nto install packages and run commands inside docker containers. These\nrules, however, require a docker binary is present and properly\nconfigured. These rules include:\n\n* [Package manager rules](docker/package_managers/README.md): rules to install\n  apt-get packages.\n* [Docker run rules](docker/util/README.md): rules to run commands inside docker\n  containers.\n\n### Overview\n\nIn addition to low-level rules for building containers, this repository\nprovides a set of higher-level rules for containerizing applications.  The idea\nbehind these rules is to make containerizing an application built via a\n`lang_binary` rule as simple as changing it to `lang_image`.\n\nBy default these higher level rules make use of the [`distroless`](\nhttps://github.com/googlecloudplatform/distroless) language runtimes, but these\ncan be overridden via the `base=\"...\"` attribute (e.g. with a `container_pull`\nor `container_image` target).\n\nNote also that these rules do not expose any docker related attributes. If you\nneed to add a custom `env` or `symlink` to a `lang_image`, you must use\n`container_image` targets for this purpose. Specifically, you can use as base for your\n`lang_image` target a `container_image` target that adds e.g., custom `env` or `symlink`.\nPlease see \u003ca href=#go_image-custom-base\u003ego_image (custom base)\u003c/a\u003e for an example.\n\n## Setup\n\nAdd the following to your `WORKSPACE` file to add the external repositories:\n\n```python\nload(\"@bazel_tools//tools/build_defs/repo:http.bzl\", \"http_archive\")\n\nhttp_archive(\n  # Get copy paste instructions for the http_archive attributes from the\n  # release notes at https://github.com/bazelbuild/rules_docker/releases\n)\n\n# OPTIONAL: Call this to override the default docker toolchain configuration.\n# This call should be placed BEFORE the call to \"container_repositories\" below\n# to actually override the default toolchain configuration.\n# Note this is only required if you actually want to call\n# docker_toolchain_configure with a custom attr; please read the toolchains\n# docs in /toolchains/docker/ before blindly adding this to your WORKSPACE.\n# BEGIN OPTIONAL segment:\nload(\"@io_bazel_rules_docker//toolchains/docker:toolchain.bzl\",\n    docker_toolchain_configure=\"toolchain_configure\"\n)\ndocker_toolchain_configure(\n  name = \"docker_config\",\n  # OPTIONAL: Bazel target for the build_tar tool, must be compatible with build_tar.py\n  build_tar_target=\"\u003center absolute path (i.e., must start with repo name @...//:...) to an executable build_tar target\u003e\",\n  # OPTIONAL: Path to a directory which has a custom docker client config.json.\n  # See https://docs.docker.com/engine/reference/commandline/cli/#configuration-files\n  # for more details.\n  client_config=\"\u003center Bazel label to your docker config.json here\u003e\",\n  # OPTIONAL: Path to the docker binary.\n  # Should be set explicitly for remote execution.\n  docker_path=\"\u003center absolute path to the docker binary (in the remote exec env) here\u003e\",\n  # OPTIONAL: Path to the gzip binary.\n  gzip_path=\"\u003center absolute path to the gzip binary (in the remote exec env) here\u003e\",\n  # OPTIONAL: Bazel target for the gzip tool.\n  gzip_target=\"\u003center absolute path (i.e., must start with repo name @...//:...) to an executable gzip target\u003e\",\n  # OPTIONAL: Path to the xz binary.\n  # Should be set explicitly for remote execution.\n  xz_path=\"\u003center absolute path to the xz binary (in the remote exec env) here\u003e\",\n  # OPTIONAL: Bazel target for the xz tool.\n  # Either xz_path or xz_target should be set explicitly for remote execution.\n  xz_target=\"\u003center absolute path (i.e., must start with repo name @...//:...) to an executable xz target\u003e\",\n  # OPTIONAL: List of additional flags to pass to the docker command.\n  docker_flags = [\n    \"--tls\",\n    \"--log-level=info\",\n  ],\n\n)\n# End of OPTIONAL segment.\n\nload(\n    \"@io_bazel_rules_docker//repositories:repositories.bzl\",\n    container_repositories = \"repositories\",\n)\ncontainer_repositories()\n\nload(\"@io_bazel_rules_docker//repositories:deps.bzl\", container_deps = \"deps\")\n\ncontainer_deps()\n\nload(\n    \"@io_bazel_rules_docker//container:container.bzl\",\n    \"container_pull\",\n)\n\ncontainer_pull(\n  name = \"java_base\",\n  registry = \"gcr.io\",\n  repository = \"distroless/java\",\n  # 'tag' is also supported, but digest is encouraged for reproducibility.\n  digest = \"sha256:deadbeef\",\n)\n```\n\n### Known Issues\n\n* Bazel does not deal well with diamond dependencies.\n\n\nIf the repositories that are imported by `container_repositories()` have already been\nimported (at a different version) by other rules you called in your `WORKSPACE`, which\nare placed above the call to `container_repositories()`, arbitrary errors might\noccur. If you get errors related to external repositories, you will likely\nnot be able to use `container_repositories()` and will have to import\ndirectly in your `WORKSPACE` all the required dependencies (see the most up\nto date impl of `container_repositories()` for details).\n\n* ImportError: No module named moves.urllib.parse\n\nThis is an example of an error due to a diamond dependency. If you get this\nerror, make sure to import rules_docker before other libraries, so that\n_six_ can be patched properly.\n\n  See https://github.com/bazelbuild/rules_docker/issues/1022 for more details.\n\n* Ensure your project has a `BUILD` or `BUILD.bazel` file at the top level. This\ncan be a blank file if necessary. Otherwise you might see an error that looks\nlike:\n```\nUnable to load package for //:WORKSPACE: BUILD file not found in any of the following directories.\n```\n\n* rules_docker uses transitions to build your containers using toolchains the correct\narchitecture and operating system. If you run into issues with toolchain resolutions,\nyou can disable this behaviour, by adding this to your .bazelrc:\n```\nbuild --@io_bazel_rules_docker//transitions:enable=false\n```\n## Using with Docker locally.\n\nSuppose you have a `container_image` target `//my/image:helloworld`:\n\n```python\ncontainer_image(\n    name = \"helloworld\",\n    ...\n)\n```\n\nYou can load this into your local Docker client by running:\n`bazel run my/image:helloworld`.\n\nFor the `lang_image` targets, this will also **run** the\ncontainer using `docker run` to maximize compatibility with `lang_binary` rules.\n\nArguments to this command are forwarded to docker, meaning the command\n\n```bash\nbazel run my/image:helloworld -- -p 8080:80 -- arg0\n```\n\nperforms the following steps:\n* load the `my/image:helloworld` target into your local Docker client\n* start a container using this image where `arg0` is passed to the image entrypoint\n* port forward 8080 on the host to port 80 on the container, as per `docker run` documentation\n\nYou can suppress this behavior by passing the single flag: `bazel run :foo -- --norun`\n\nAlternatively, you can build a `docker load` compatible bundle with:\n`bazel build my/image:helloworld.tar`.  This will produce a tar file\nin your `bazel-out` directory that can be loaded into your local Docker\nclient. Building this target can be expensive for large images. You will\nfirst need to query the ouput file location.\n\n```bash\nTARBALL_LOCATION=$(bazel cquery my/image:helloworld.tar \\\n    --output starlark \\\n    --starlark:expr=\"target.files.to_list()[0].path\")\ndocker load -i $TARBALL_LOCATION\n```\n\nThese work with both `container_image`, `container_bundle`, and the\n`lang_image` rules.  For everything except `container_bundle`, the image\nname will be `bazel/my/image:helloworld`. The `container_bundle` rule will\napply the tags you have specified.\n\n## Authentication\n\nYou can use these rules to access private images using standard Docker\nauthentication methods.  e.g. to utilize the [Google Container Registry](\nhttps://gcr.io). See\n[here](https://cloud.google.com/container-registry/docs/advanced-authentication) for authentication methods.\n\nSee also:\n * [Amazon ECR Docker Credential Helper](\n https://github.com/awslabs/amazon-ecr-credential-helper)\n * [Azure Docker Credential Helper](\n https://github.com/Azure/acr-docker-credential-helper)\n\nOnce you've setup your docker client configuration, see [here](#container_pull-custom-client-configuration)\nfor an example of how to use `container_pull` with custom docker authentication credentials\nand [here](#container_push-custom-client-configuration) for an example of how\nto use `container_push` with custom docker authentication credentials.\n\n## Varying image names\n\nA common request from folks using\n`container_push`, `container_bundle`, or `container_image` is to\nbe able to vary the tag that is pushed or embedded.  There are two options\nat present for doing this.\n\n### Stamping\n\nThe first option is to use stamping.\nStamping is enabled when bazel is run with `--stamp`.\nThis enables replacements in stamp-aware attributes.\nA python format placeholder (e.g. `{BUILD_USER}`)\nis replaced by the value of the corresponding workspace-status variable.\n\n```python\n# A common pattern when users want to avoid trampling\n# on each other's images during development.\ncontainer_push(\n  name = \"publish\",\n  format = \"Docker\",\n\n  # Any of these components may have variables.\n  registry = \"gcr.io\",\n  repository = \"my-project/my-image\",\n  # This will be replaced with the current user when built with --stamp\n  tag = \"{BUILD_USER}\",\n)\n```\n\n\u003e Rules that are sensitive to stamping can also be forced to stamp or non-stamp mode\n\u003e irrespective of the `--stamp` flag to Bazel. Use the `build_context_data` rule\n\u003e to make a target that provides `StampSettingInfo`, and pass this to the\n\u003e `build_context_data` attribute.\n\nThe next natural question is: \"Well what variables can I use?\"  This\noption consumes the workspace-status variables Bazel defines in\n`bazel-out/stable-status.txt` and `bazel-out/volatile-status.txt`.\n\n\u003e Note that changes to the stable-status file\n\u003e cause a rebuild of the action, while volatile-status does not.\n\nYou can add more stamp variables via `--workspace_status_command`,\nsee the [bazel docs](https://docs.bazel.build/versions/master/user-manual.html#workspace_status).\nA common example is to provide the current git SHA, with\n`--workspace_status_command=\"echo STABLE_GIT_SHA $(git rev-parse HEAD)\"`\n\nThat flag is typically passed in the `.bazelrc` file, see for example [`.bazelrc` in kubernetes](https://github.com/kubernetes/kubernetes/blob/81ce94ae1d8f5d04058eeb214e9af498afe78ff2/build/root/.bazelrc#L6).\n\n\n### Make variables\n\nThe second option is to employ `Makefile`-style variables:\n\n```python\ncontainer_bundle(\n  name = \"bundle\",\n\n  images = {\n    \"gcr.io/$(project)/frontend:latest\": \"//frontend:image\",\n    \"gcr.io/$(project)/backend:latest\": \"//backend:image\",\n  }\n)\n```\n\nThese variables are specified on the CLI using:\n\n```shell\n   bazel build --define project=blah //path/to:bundle\n```\n\n## Debugging `lang_image` rules\n\nBy default the `lang_image` rules use the `distroless` base runtime images,\nwhich are optimized to be the minimal set of things your application needs\nat runtime.  That can make debugging these containers difficult because they\nlack even a basic shell for exploring the filesystem.\n\nTo address this, we publish variants of the `distroless` runtime images tagged\n`:debug`, which are the exact-same images, but with additions such as `busybox`\nto make debugging easier.\n\nFor example (in this repo):\n\n```shell\n$ bazel run -c dbg testdata:go_image\n...\nINFO: Build completed successfully, 5 total actions\n\nINFO: Running command line: bazel-bin/testdata/go_image\nLoaded image ID: sha256:9c5c2167a1db080a64b5b401b43b3c5cdabb265b26cf7a60aabe04a20da79e24\nTagging 9c5c2167a1db080a64b5b401b43b3c5cdabb265b26cf7a60aabe04a20da79e24 as bazel/testdata:go_image\nHello, world!\n\n$ docker run -ti --rm --entrypoint=sh bazel/testdata:go_image -c \"echo Hello, busybox.\"\nHello, busybox.\n```\n\n\n## Examples\n\n### container_image\n\n```python\ncontainer_image(\n    name = \"app\",\n    # References container_pull from WORKSPACE (above)\n    base = \"@java_base//image\",\n    files = [\"//java/com/example/app:Hello_deploy.jar\"],\n    cmd = [\"Hello_deploy.jar\"]\n)\n```\n\nHint: if you want to put files in specific directories inside the image\nuse \u003ca href=\"https://docs.bazel.build/versions/master/be/pkg.html\"\u003e`pkg_tar` rule\u003c/a\u003e\nto create the desired directory structure and pass that to `container_image` via\n`tars` attribute. Note you might need to set `strip_prefix = \".\"` or `strip_prefix = \"{some directory}\"`\nin your rule for the files to not be flattened.\nSee \u003ca href=\"https://github.com/bazelbuild/bazel/issues/2176\"\u003eBazel upstream issue 2176\u003c/a\u003e and\n \u003ca href=\"https://github.com/bazelbuild/rules_docker/issues/317\"\u003erules_docker issue 317\u003c/a\u003e\nfor more details.\n\n\n### cc_image\n\nTo use `cc_image`, add the following to `WORKSPACE`:\n\n```python\nload(\n    \"@io_bazel_rules_docker//repositories:repositories.bzl\",\n    container_repositories = \"repositories\",\n)\n\ncontainer_repositories()\n\nload(\n    \"@io_bazel_rules_docker//cc:image.bzl\",\n    _cc_image_repos = \"repositories\",\n)\n\n_cc_image_repos()\n```\n\nThen in your `BUILD` file, simply rewrite `cc_binary` to `cc_image` with the\nfollowing import:\n\n```python\nload(\"@io_bazel_rules_docker//cc:image.bzl\", \"cc_image\")\n\ncc_image(\n    name = \"cc_image\",\n    srcs = [\"cc_image.cc\"],\n    deps = [\":cc_image_library\"],\n)\n```\n\n### cc_image (external binary)\n\nTo use `cc_image` (or `go_image`, `d_image`, `rust_image`) with an external\n`cc_binary` (or the like) target, then your `BUILD` file should instead look\nlike:\n\n```python\nload(\"@io_bazel_rules_docker//cc:image.bzl\", \"cc_image\")\n\ncc_binary(\n    name = \"cc_binary\",\n    srcs = [\"cc_binary.cc\"],\n    deps = [\":cc_library\"],\n)\n\ncc_image(\n    name = \"cc_image\",\n    binary = \":cc_binary\",\n)\n```\n\nIf you need to modify somehow the container produced by\n`cc_image` (e.g., `env`, `symlink`), see note above in\n\u003ca href=#overview-1\u003eLanguage Rules Overview\u003c/a\u003e about how to do this\nand see \u003ca href=#go_image-custom-base\u003ego_image (custom base)\u003c/a\u003e example below.\n\n### py_image\n\nTo use `py_image`, add the following to `WORKSPACE`:\n\n```python\nload(\n    \"@io_bazel_rules_docker//repositories:repositories.bzl\",\n    container_repositories = \"repositories\",\n)\n\ncontainer_repositories()\n\nload(\n    \"@io_bazel_rules_docker//python:image.bzl\",\n    _py_image_repos = \"repositories\",\n)\n\n_py_image_repos()\n```\n\nThen in your `BUILD` file, simply rewrite `py_binary` to `py_image` with the\nfollowing import:\n\n```python\nload(\"@io_bazel_rules_docker//python:image.bzl\", \"py_image\")\n\npy_image(\n    name = \"py_image\",\n    srcs = [\"py_image.py\"],\n    deps = [\":py_image_library\"],\n    main = \"py_image.py\",\n)\n```\n\nIf you need to modify somehow the container produced by\n`py_image` (e.g., `env`, `symlink`), see note above in\n\u003ca href=#overview-1\u003eLanguage Rules Overview\u003c/a\u003e about how to do this\nand see \u003ca href=#go_image-custom-base\u003ego_image (custom base)\u003c/a\u003e example below.\n\nIf you are using `py_image` with a custom base that has python tools installed\nin a location different to the default base, please see\n\u003ca href=#python-tools\u003ePython tools\u003c/a\u003e.\n\n### py_image (fine layering)\n\nFor Python and Java's `lang_image` rules, you can factor\ndependencies that don't change into their own layers by overriding the\n`layers=[]` attribute.  Consider this sample from the `rules_k8s` repository:\n\n```python\npy_image(\n    name = \"server\",\n    srcs = [\"server.py\"],\n    # \"layers\" is just like \"deps\", but it also moves the dependencies each into\n    # their own layer, which can dramatically improve developer cycle time. For\n    # example here, the grpcio layer is ~40MB, but the rest of the app is only\n    # ~400KB.  By partitioning things this way, the large grpcio layer remains\n    # unchanging and we can reduce the amount of image data we repush by ~99%!\n    layers = [\n        requirement(\"grpcio\"),\n        \"//examples/hellogrpc/proto:py\",\n    ],\n    main = \"server.py\",\n)\n```\n\nYou can also implement more complex fine layering strategies by using the\n`py_layer` or `java_layer` rules and their `filter` attribute.  For example:\n\n```python\n# Suppose that we are synthesizing an image that depends on a complex set\n# of libraries that we want to break into layers.\nLIBS = [\n    \"//pkg/complex_library\",\n    # ...\n]\n# First, we extract all transitive dependencies of LIBS that are under //pkg/common.\npy_layer(\n    name = \"common_deps\",\n    deps = LIBS,\n    filter = \"//pkg/common\",\n)\n# Then, we further extract all external dependencies of the deps under //pkg/common.\npy_layer(\n    name = \"common_external_deps\",\n    deps = [\":common_deps\"],\n    filter = \"@\",\n)\n# We also extract all external dependencies of LIBS, which is a superset of\n# \":common_external_deps\".\npy_layer(\n    name = \"external_deps\",\n    deps = LIBS,\n    filter = \"@\",\n)\n# Finally, we create the image, stacking the above filtered layers on top of one\n# another in the \"layers\" attribute.  The layers are applied in order, and any\n# dependencies already added to the image will not be added again.  Therefore,\n# \":external_deps\" will only add the external dependencies not present in\n# \":common_external_deps\".\npy_image(\n    name = \"image\",\n    deps = LIBS,\n    layers = [\n        \":common_external_deps\",\n        \":common_deps\",\n        \":external_deps\",\n    ],\n    # ...\n)\n```\n\n### py3_image\n\nTo use a Python 3 runtime instead of the default of Python 2, use `py3_image`,\ninstead of `py_image`.  The other semantics are identical.\n\nIf you need to modify somehow the container produced by\n`py3_image` (e.g., `env`, `symlink`), see note above in\n\u003ca href=#overview-1\u003eLanguage Rules Overview\u003c/a\u003e about how to do this\nand see \u003ca href=#go_image-custom-base\u003ego_image (custom base)\u003c/a\u003e example below.\n\nIf you are using `py3_image` with a custom base that has python tools installed\nin a location different to the default base, please see\n\u003ca href=#python-tools\u003ePython tools\u003c/a\u003e.\n\n### nodejs_image\n\n**It is notable that unlike the other image rules, `nodejs_image` is not\ncurrently using the `gcr.io/distroless/nodejs` image for a handful of reasons.**\nThis is a switch we plan to make, when we can manage it.  We are currently\nutilizing the `gcr.io/google-appengine/debian9` image as our base.\n\nTo use `nodejs_image`, add the following to `WORKSPACE`:\n\n```python\nload(\"@bazel_tools//tools/build_defs/repo:http.bzl\", \"http_archive\")\n\nhttp_archive(\n    name = \"build_bazel_rules_nodejs\",\n    # Replace with a real SHA256 checksum\n    sha256 = \"{SHA256}\"\n    # Replace with a real release version\n    urls = [\"https://github.com/bazelbuild/rules_nodejs/releases/download/{VERSION}/rules_nodejs-{VERSION}.tar.gz\"],\n)\n\n\nload(\"@build_bazel_rules_nodejs//:index.bzl\", \"npm_install\")\n\n# Install your declared Node.js dependencies\nnpm_install(\n    name = \"npm\",\n    package_json = \"//:package.json\",\n    yarn_lock = \"//:yarn.lock\",\n)\n\nload(\n    \"@io_bazel_rules_docker//repositories:repositories.bzl\",\n    container_repositories = \"repositories\",\n)\n\ncontainer_repositories()\n\nload(\n    \"@io_bazel_rules_docker//nodejs:image.bzl\",\n    _nodejs_image_repos = \"repositories\",\n)\n\n_nodejs_image_repos()\n```\n\nNote: See note about diamond dependencies in \u003ca href=#setup\u003esetup\u003c/a\u003e\nif you run into issues related to external repos after adding these\nlines to your `WORKSPACE`.\n\nThen in your `BUILD` file, simply rewrite `nodejs_binary` to `nodejs_image` with\nthe following import:\n\n```python\nload(\"@io_bazel_rules_docker//nodejs:image.bzl\", \"nodejs_image\")\n\nnodejs_image(\n    name = \"nodejs_image\",\n    entry_point = \"@your_workspace//path/to:file.js\",\n    # npm deps will be put into their own layer\n    data = [\":file.js\", \"@npm//some-npm-dep\"],\n    ...\n)\n```\n\n`nodejs_image` also supports the `launcher` and `launcher_args` attributes which are passed to `container_image` and used to prefix the image's `entry_point`.\n\nIf you need to modify somehow the container produced by\n`nodejs_image` (e.g., `env`, `symlink`), see note above in\n\u003ca href=#overview-1\u003eLanguage Rules Overview\u003c/a\u003e about how to do this\nand see \u003ca href=#go_image-custom-base\u003ego_image (custom base)\u003c/a\u003e example below.\n\n### go_image\n\nTo use `go_image`, add the following to `WORKSPACE`:\n\n```python\nload(\"@bazel_tools//tools/build_defs/repo:http.bzl\", \"http_archive\")\n\nload(\n    \"@io_bazel_rules_docker//repositories:repositories.bzl\",\n    container_repositories = \"repositories\",\n)\n\ncontainer_repositories()\n\nload(\n    \"@io_bazel_rules_docker//go:image.bzl\",\n    _go_image_repos = \"repositories\",\n)\n\n_go_image_repos()\n```\n\nNote: See note about diamond dependencies in \u003ca href=#setup\u003esetup\u003c/a\u003e\nif you run into issues related to external repos after adding these\nlines to your `WORKSPACE`.\n\nThen in your `BUILD` file, simply rewrite `go_binary` to `go_image` with the\nfollowing import:\n\n```python\nload(\"@io_bazel_rules_docker//go:image.bzl\", \"go_image\")\n\ngo_image(\n    name = \"go_image\",\n    srcs = [\"main.go\"],\n    importpath = \"github.com/your/path/here\",\n)\n```\nNotice that it is important to explicitly build this target with the\n`--platforms=@io_bazel_rules_go//go/toolchain:linux_amd64` flag\nas the binary should be built for Linux since it will run in a Linux container.\n\nIf you need to modify somehow the container produced by\n`go_image` (e.g., `env`, `symlink`), see note above in\n\u003ca href=#overview-1\u003eLanguage Rules Overview\u003c/a\u003e about how to do this and\nsee example below.\n\n### go_image (custom base)\n\nTo use a custom base image, with any of the `lang_image`\nrules, you can override the default `base=\"...\"` attribute.  Consider this\nmodified sample from the `distroless` repository:\n\n```python\nload(\"@rules_pkg//pkg:tar.bzl\", \"pkg_tar\")\n\n# Create a passwd file with a root and nonroot user and uid.\npasswd_entry(\n    username = \"root\",\n    uid = 0,\n    gid = 0,\n    name = \"root_user\",\n)\n\npasswd_entry(\n    username = \"nonroot\",\n    info = \"nonroot\",\n    uid = 1002,\n    name = \"nonroot_user\",\n)\n\npasswd_file(\n    name = \"passwd\",\n    entries = [\n        \":root_user\",\n        \":nonroot_user\",\n    ],\n)\n\n# Create a tar file containing the created passwd file\npkg_tar(\n    name = \"passwd_tar\",\n    srcs = [\":passwd\"],\n    mode = \"0o644\",\n    package_dir = \"etc\",\n)\n\n# Include it in our base image as a tar.\ncontainer_image(\n    name = \"passwd_image\",\n    base = \"@go_image_base//image\",\n    tars = [\":passwd_tar\"],\n    user = \"nonroot\",\n)\n\n# Simple go program to print out the username and uid.\ngo_image(\n    name = \"user\",\n    srcs = [\"user.go\"],\n    # Override the base image.\n    base = \":passwd_image\",\n)\n```\n\n\n### java_image\n\nTo use `java_image`, add the following to `WORKSPACE`:\n\n```python\nload(\n    \"@io_bazel_rules_docker//repositories:repositories.bzl\",\n    container_repositories = \"repositories\",\n)\n\ncontainer_repositories()\n\nload(\n    \"@io_bazel_rules_docker//java:image.bzl\",\n    _java_image_repos = \"repositories\",\n)\n\n_java_image_repos()\n```\n\nThen in your `BUILD` file, simply rewrite `java_binary` to `java_image` with the\nfollowing import:\n\n```python\nload(\"@io_bazel_rules_docker//java:image.bzl\", \"java_image\")\n\njava_image(\n    name = \"java_image\",\n    srcs = [\"Binary.java\"],\n    # Put these runfiles into their own layer.\n    layers = [\":java_image_library\"],\n    main_class = \"examples.images.Binary\",\n)\n```\n\nIf you need to modify somehow the container produced by\n`java_image` (e.g., `env`, `symlink`), see note above in\n\u003ca href=#overview-1\u003eLanguage Rules Overview\u003c/a\u003e about how to do this\nand see \u003ca href=#go_image-custom-base\u003ego_image (custom base)\u003c/a\u003e example.\n\n### war_image\n\nTo use `war_image`, add the following to `WORKSPACE`:\n\n```python\nload(\n    \"@io_bazel_rules_docker//repositories:repositories.bzl\",\n    container_repositories = \"repositories\",\n)\n\ncontainer_repositories()\n\nload(\n    \"@io_bazel_rules_docker//java:image.bzl\",\n    _java_image_repos = \"repositories\",\n)\n\n_java_image_repos()\n```\n\nNote: See note about diamond dependencies in \u003ca href=#setup\u003esetup\u003c/a\u003e\nif you run into issues related to external repos after adding these\nlines to your `WORKSPACE`.\n\nThen in your `BUILD` file, simply rewrite `java_war` to `war_image` with the\nfollowing import:\n\n```python\nload(\"@io_bazel_rules_docker//java:image.bzl\", \"war_image\")\n\nwar_image(\n    name = \"war_image\",\n    srcs = [\"Servlet.java\"],\n    # Put these JARs into their own layers.\n    layers = [\n        \":java_image_library\",\n        \"@javax_servlet_api//jar:jar\",\n    ],\n)\n```\n\nThe produced image uses Jetty 9.x to serve the web application. Servlets included in the web application need to follow the API specification 3.0. For best compatibility, use a [Servlet dependency provided by the Jetty project](https://search.maven.org/search?q=g:org.mortbay.jetty%20AND%20a:servlet-api\u0026core=gav).\n\nA Servlet implementation needs to declare the `@WebServlet` annotation to be auto-discovered. The use of a `web.xml` to declare the Servlet URL mapping is not supported.\n\nIf you need to modify somehow the container produced by\n`war_image` (e.g., `env`, `symlink`), see note above in\n\u003ca href=#overview-1\u003eLanguage Rules Overview\u003c/a\u003e about how to do this\nand see \u003ca href=#go_image-custom-base\u003ego_image (custom base)\u003c/a\u003e example.\n\n### scala_image\n\nTo use `scala_image`, add the following to `WORKSPACE`:\n\n```python\nload(\"@bazel_tools//tools/build_defs/repo:http.bzl\", \"http_archive\")\n\n# You *must* import the Scala rules before setting up the scala_image rules.\nhttp_archive(\n    name = \"io_bazel_rules_scala\",\n    # Replace with a real SHA256 checksum\n    sha256 = \"{SHA256}\"\n    # Replace with a real commit SHA\n    strip_prefix = \"rules_scala-{HEAD}\",\n    urls = [\"https://github.com/bazelbuild/rules_scala/archive/{HEAD}.tar.gz\"],\n)\n\nload(\"@io_bazel_rules_scala//scala:scala.bzl\", \"scala_repositories\")\n\nscala_repositories()\n\nload(\n    \"@io_bazel_rules_docker//repositories:repositories.bzl\",\n    container_repositories = \"repositories\",\n)\n\ncontainer_repositories()\n\nload(\n    \"@io_bazel_rules_docker//scala:image.bzl\",\n    _scala_image_repos = \"repositories\",\n)\n\n_scala_image_repos()\n```\n\nNote: See note about diamond dependencies in \u003ca href=#setup\u003esetup\u003c/a\u003e\nif you run into issues related to external repos after adding these\nlines to your `WORKSPACE`.\n\nThen in your `BUILD` file, simply rewrite `scala_binary` to `scala_image` with the\nfollowing import:\n\n```python\nload(\"@io_bazel_rules_docker//scala:image.bzl\", \"scala_image\")\n\nscala_image(\n    name = \"scala_image\",\n    srcs = [\"Binary.scala\"],\n    main_class = \"examples.images.Binary\",\n)\n```\n\nIf you need to modify somehow the container produced by\n`scala_image` (e.g., `env`, `symlink`), see note above in\n\u003ca href=#overview-1\u003eLanguage Rules Overview\u003c/a\u003e about how to do this\nand see \u003ca href=#go_image-custom-base\u003ego_image (custom base)\u003c/a\u003e example.\n\n### groovy_image\n\nTo use `groovy_image`, add the following to `WORKSPACE`:\n\n```python\nload(\"@bazel_tools//tools/build_defs/repo:http.bzl\", \"http_archive\")\n\n# You *must* import the Groovy rules before setting up the groovy_image rules.\nhttp_archive(\n    name = \"io_bazel_rules_groovy\",\n    # Replace with a real SHA256 checksum\n    sha256 = \"{SHA256}\"\n    # Replace with a real commit SHA\n    strip_prefix = \"rules_groovy-{HEAD}\",\n    urls = [\"https://github.com/bazelbuild/rules_groovy/archive/{HEAD}.tar.gz\"],\n)\n\nload(\"@io_bazel_rules_groovy//groovy:groovy.bzl\", \"groovy_repositories\")\n\ngroovy_repositories()\n\nload(\n    \"@io_bazel_rules_docker//repositories:repositories.bzl\",\n    container_repositories = \"repositories\",\n)\n\ncontainer_repositories()\n\nload(\n    \"@io_bazel_rules_docker//groovy:image.bzl\",\n    _groovy_image_repos = \"repositories\",\n)\n\n_groovy_image_repos()\n```\n\nNote: See note about diamond dependencies in \u003ca href=#setup\u003esetup\u003c/a\u003e\nif you run into issues related to external repos after adding these\nlines to your `WORKSPACE`.\n\nThen in your `BUILD` file, simply rewrite `groovy_binary` to `groovy_image` with the\nfollowing import:\n\n```python\nload(\"@io_bazel_rules_docker//groovy:image.bzl\", \"groovy_image\")\n\ngroovy_image(\n    name = \"groovy_image\",\n    srcs = [\"Binary.groovy\"],\n    main_class = \"examples.images.Binary\",\n)\n```\n\nIf you need to modify somehow the container produced by\n`groovy_image` (e.g., `env`, `symlink`), see note above in\n\u003ca href=#overview-1\u003eLanguage Rules Overview\u003c/a\u003e about how to do this\nand see \u003ca href=#go_image-custom-base\u003ego_image (custom base)\u003c/a\u003e example.\n\n### rust_image\n\nTo use `rust_image`, add the following to `WORKSPACE`:\n\n```python\nload(\"@bazel_tools//tools/build_defs/repo:http.bzl\", \"http_archive\")\n\n# You *must* import the Rust rules before setting up the rust_image rules.\nhttp_archive(\n    name = \"rules_rust\",\n    # Replace with a real SHA256 checksum\n    sha256 = \"{SHA256}\"\n    # Replace with a real commit SHA\n    strip_prefix = \"rules_rust-{HEAD}\",\n    urls = [\"https://github.com/bazelbuild/rules_rust/archive/{HEAD}.tar.gz\"],\n)\n\nload(\"@rules_rust//rust:repositories.bzl\", \"rust_repositories\")\n\nrust_repositories()\n\nload(\n    \"@io_bazel_rules_docker//repositories:repositories.bzl\",\n    container_repositories = \"repositories\",\n)\n\ncontainer_repositories()\n\nload(\n    \"@io_bazel_rules_docker//rust:image.bzl\",\n    _rust_image_repos = \"repositories\",\n)\n\n_rust_image_repos()\n```\n\nNote: See note about diamond dependencies in \u003ca href=#setup\u003esetup\u003c/a\u003e\nif you run into issues related to external repos after adding these\nlines to your `WORKSPACE`.\n\nThen in your `BUILD` file, simply rewrite `rust_binary` to `rust_image` with the\nfollowing import:\n\n```python\nload(\"@io_bazel_rules_docker//rust:image.bzl\", \"rust_image\")\n\nrust_image(\n    name = \"rust_image\",\n    srcs = [\"main.rs\"],\n)\n```\n\nIf you need to modify somehow the container produced by\n`rust_image` (e.g., `env`, `symlink`), see note above in\n\u003ca href=#overview-1\u003eLanguage Rules Overview\u003c/a\u003e about how to do this\nand see \u003ca href=#go_image-custom-base\u003ego_image (custom base)\u003c/a\u003e example.\n\n### d_image\n\nTo use `d_image`, add the following to `WORKSPACE`:\n\n```python\nload(\"@bazel_tools//tools/build_defs/repo:http.bzl\", \"http_archive\")\n\n# You *must* import the D rules before setting up the d_image rules.\nhttp_archive(\n    name = \"io_bazel_rules_d\",\n    # Replace with a real SHA256 checksum\n    sha256 = \"{SHA256}\"\n    # Replace with a real commit SHA\n    strip_prefix = \"rules_d-{HEAD}\",\n    urls = [\"https://github.com/bazelbuild/rules_d/archive/{HEAD}.tar.gz\"],\n)\n\nload(\"@io_bazel_rules_d//d:d.bzl\", \"d_repositories\")\n\nd_repositories()\n\nload(\n    \"@io_bazel_rules_docker//repositories:repositories.bzl\",\n    container_repositories = \"repositories\",\n)\n\ncontainer_repositories()\n\nload(\n    \"@io_bazel_rules_docker//d:image.bzl\",\n    _d_image_repos = \"repositories\",\n)\n\n_d_image_repos()\n```\n\nNote: See note about diamond dependencies in \u003ca href=#setup\u003esetup\u003c/a\u003e\nif you run into issues related to external repos after adding these\nlines to your `WORKSPACE`.\n\nThen in your `BUILD` file, simply rewrite `d_binary` to `d_image` with the\nfollowing import:\n\n```python\nload(\"@io_bazel_rules_docker//d:image.bzl\", \"d_image\")\n\nd_image(\n    name = \"d_image\",\n    srcs = [\"main.d\"],\n)\n```\n\nIf you need to modify somehow the container produced by\n`d_image` (e.g., `env`, `symlink`), see note above in\n\u003ca href=#overview-1\u003eLanguage Rules Overview\u003c/a\u003e about how to do this\nand see \u003ca href=#go_image-custom-base\u003ego_image (custom base)\u003c/a\u003e example.\n\n\u003e NOTE: all application image rules support the `args` string_list\n\u003e attribute.  If specified, they will be appended directly after the\n\u003e container ENTRYPOINT binary name.\n\n### container_bundle\n\n```python\ncontainer_bundle(\n    name = \"bundle\",\n    images = {\n        # A set of images to bundle up into a single tarball.\n        \"gcr.io/foo/bar:bazz\": \":app\",\n        \"gcr.io/foo/bar:blah\": \"//my:sidecar\",\n        \"gcr.io/foo/bar:booo\": \"@your//random:image\",\n    }\n)\n```\n\n### container_pull\n\nIn `WORKSPACE`:\n\n```python\ncontainer_pull(\n    name = \"base\",\n    registry = \"gcr.io\",\n    repository = \"my-project/my-base\",\n    # 'tag' is also supported, but digest is encouraged for reproducibility.\n    digest = \"sha256:deadbeef\",\n)\n```\n\nThis can then be referenced in `BUILD` files as `@base//image`.\n\nTo get the correct digest one can run `docker manifest inspect gcr.io/my-project/my-base:tag` once [experimental docker cli features are enabled](https://docs.docker.com/engine/reference/commandline/manifest_inspect).\n\nSee [here](#container_pull-custom-client-configuration) for an example of how\nto use container_pull with custom docker authentication credentials.\n\n### container_push\n\nThis target pushes on `bazel run :push_foo`:\n\n``` python\ncontainer_push(\n   name = \"push_foo\",\n   image = \":foo\",\n   format = \"Docker\",\n   registry = \"gcr.io\",\n   repository = \"my-project/my-image\",\n   tag = \"dev\",\n)\n```\n\nWe also support the `docker_push` (from `docker/docker.bzl`) and `oci_push`\n(from `oci/oci.bzl`) aliases, which bake in the `format = \"...\"` attribute.\n\nSee [here](#container_push-custom-client-configuration) for an example of how\nto use container_push with custom docker authentication credentials.\n\n### container_push (Custom client configuration)\nIf you wish to use container_push using custom docker authentication credentials,\nin `WORKSPACE`:\n\n```python\n# Download the rules_docker repository\nhttp_archive(\n    name = \"io_bazel_rules_docker\",\n    ...\n)\n\n# Load the macro that allows you to customize the docker toolchain configuration.\nload(\"@io_bazel_rules_docker//toolchains/docker:toolchain.bzl\",\n    docker_toolchain_configure=\"toolchain_configure\"\n)\n\ndocker_toolchain_configure(\n  name = \"docker_config\",\n  # Replace this with a Bazel label to the config.json file. Note absolute or relative\n  # paths are not supported. Docker allows you to specify custom authentication credentials\n  # in the client configuration JSON file.\n  # See https://docs.docker.com/engine/reference/commandline/cli/#configuration-files\n  # for more details.\n  client_config=\"@//path/to/docker:config.json\",\n)\n```\nIn `BUILD` file:\n\n```python\nload(\"@io_bazel_rules_docker//container:container.bzl\", \"container_push\")\n\ncontainer_push(\n   name = \"push_foo\",\n   image = \":foo\",\n   format = \"Docker\",\n   registry = \"gcr.io\",\n   repository = \"my-project/my-image\",\n   tag = \"dev\",\n)\n```\n\n### container_pull (DockerHub)\n\nIn `WORKSPACE`:\n\n```python\ncontainer_pull(\n    name = \"official_ubuntu\",\n    registry = \"index.docker.io\",\n    repository = \"library/ubuntu\",\n    tag = \"14.04\",\n)\n```\n\nThis can then be referenced in `BUILD` files as `@official_ubuntu//image`.\n\n### container_pull (Quay.io)\n\nIn `WORKSPACE`:\n\n```python\ncontainer_pull(\n    name = \"etcd\",\n    registry = \"quay.io\",\n    repository = \"coreos/etcd\",\n    tag = \"latest\",\n)\n```\n\nThis can then be referenced in `BUILD` files as `@etcd//image`.\n\n### container_pull (Bintray.io)\n\nIn `WORKSPACE`:\n\n```python\ncontainer_pull(\n    name = \"artifactory\",\n    registry = \"docker.bintray.io\",\n    repository = \"jfrog/artifactory-pro\",\n)\n```\n\nThis can then be referenced in `BUILD` files as `@artifactory//image`.\n\n### container_pull (Gitlab)\n\nIn `WORKSPACE`:\n\n```python\ncontainer_pull(\n    name = \"gitlab\",\n    registry = \"registry.gitlab.com\",\n    repository = \"username/project/image\",\n    tag = \"tag\",\n)\n```\n\nThis can then be referenced in `BUILD` files as `@gitlab//image`.\n\n### container_pull (Custom client configuration)\n\nIf you specified a docker client directory using the `client_config` attribute\nto the docker toolchain configuration described \u003ca href=\"#setup\"\u003ehere\u003c/a\u003e, you\ncan use a container_pull that uses the authentication credentials from the\nspecified docker client directory as follows:\n\nIn `WORKSPACE`:\n\n```python\nload(\"@io_bazel_rules_docker//toolchains/docker:toolchain.bzl\",\n    docker_toolchain_configure=\"toolchain_configure\"\n)\n\n# Configure the docker toolchain.\ndocker_toolchain_configure(\n  name = \"docker_config\",\n  # Bazel label to a custom docker client config.json with\n  # authentication credentials for registry.gitlab.com (used in this example).\n  client_config=\"@//path/to/docker/client:config.json\",\n)\n\n# Load the custom version of container_pull created by the docker toolchain\n# configuration.\nload(\"@docker_config//:pull.bzl\", authenticated_container_pull=\"container_pull\")\n\nauthenticated_container_pull(\n    name = \"gitlab\",\n    registry = \"registry.gitlab.com\",\n    repository = \"username/project/image\",\n    tag = \"tag\",\n)\n```\n\nThis can then be referenced in `BUILD` files as `@gitlab//image`.\n\n**NOTE:** This should only be used if a custom `client_config` was set. If you want\n          to use the DOCKER_CONFIG env variable or the default home directory\n\t  use the standard `container_pull` rule.\n\n**NOTE:** This will only work on systems with Python \u003e2.7.6\n\n## Python tools\n\nStarting with Bazel 0.25.0 it's possible to configure python toolchains\nfor `rules_docker`.\n\nTo use these features you need to enable the flags in the `.bazelrc`\nfile at the root of this project.\n\nUse of these features require a python toolchain to be registered.\n`//py_images/image.bzl:deps` and `//py3_images/image.bzl:deps` register a\ndefault python toolchain (`//toolchains:container_py_toolchain`)\nthat defines the path to python tools inside the default container used\nfor these rules.\n\n### Known issues\n\nIf you are using a custom base for `py_image` or `py3_image` builds that has\npython tools installed in a different location to those defined in\n`//toolchains:container_py_toolchain`, you will need to create a\ntoolchain that points to these paths and register it _before_ the call to\n`py*_images/image.bzl:deps` in your `WORKSPACE`.\n\nUse of python toolchain features, currently, only supports picking one\nversion of python for execution of host tools. `rules_docker` heavily depends\non execution of python host tools that are only compatible with python 2.\nFlags in the recommended `.bazelrc` file force all host tools to use python 2.\nIf your project requires using host tools that are only compatible with\npython 3 you will not be able to use these features at the moment. We\nexpect this issue to be resolved before use of python toolchain features\nbecomes the default.\n\n## Updating the `distroless` base images.\n\nThe digest references to the `distroless` base images must be updated over time\nto pick up bug fixes and security patches.  To facilitate this, the files\ncontaining the digest references are generated by `tools/update_deps.py`.  To\nupdate all of the dependencies, please run (from the root of the repository):\n\n```shell\n./update_deps.sh\n```\n\nImage references should not be updated individually because these images have\nshared layers and letting them diverge could result in sub-optimal push and pull\n performance.\n\n\u003ca name=\"container_pull\"\u003e\u003c/a\u003e\n## container_pull\n\n**MOVED**: See [docs/container.md](/docs/container.md#container_pull)\n\n\u003ca name=\"container_push\"\u003e\u003c/a\u003e\n## container_push\n\n**MOVED**: See [docs/container.md](/docs/container.md#container_push)\n\n\u003ca name=\"container_layer\"\u003e\u003c/a\u003e\n## container_layer\n\n**MOVED**: See [docs/container.md](/docs/container.md#container_layer)\n\n\u003ca name=\"container_image\"\u003e\u003c/a\u003e\n## container_image\n\n**MOVED**: See [docs/container.md](/docs/container.md#container_image)\n\n\u003ca name=\"container_bundle\"\u003e\u003c/a\u003e\n## container_bundle\n\n**MOVED**: See [docs/container.md](/docs/container.md#container_bundle)\n\n\u003ca name=\"container_import\"\u003e\u003c/a\u003e\n## container_import\n\n**MOVED**: See [docs/container.md](/docs/container.md#container_import)\n\n\u003ca name=\"container_load\"\u003e\u003c/a\u003e\n## container_load\n\n**MOVED**: See [docs/container.md](/docs/container.md#container_load)\n\n\n## Adopters\nHere's a (non-exhaustive) list of companies that use `rules_docker` in production. Don't see yours? [You can add it in a PR!](https://github.com/bazelbuild/rules_docker/edit/master/README.md)\n  * [Amaiz](https://github.com/amaizfinance)\n  * [Aura Devices](https://auradevices.io/)\n  * [Button](https://usebutton.com)\n  * [Domino Data Lab](https://www.dominodatalab.com/)\n  * [Canva](https://canva.com)\n  * [Etsy](https://www.etsy.com)\n  * [Evertz](https://evertz.com/)\n  * [Jetstack](https://www.jetstack.io/)\n  * [Kubernetes Container Image Promoter](https://github.com/kubernetes-sigs/k8s-container-image-promoter)\n  * [Nordstrom](https://nordstrom.com)\n  * [Prow](https://github.com/kubernetes/test-infra/tree/master/prow)\n  * [Tink](https://www.tink.com)\n  * [Wix](https://www.wix.com)\n","funding_links":[],"categories":["Starlark","Deployment","Python"],"sub_categories":["Google projects"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbazelbuild%2Frules_docker","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbazelbuild%2Frules_docker","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbazelbuild%2Frules_docker/lists"}