- Notifications
You must be signed in to change notification settings - Fork695
Rules for building and handling Docker images with Bazel
License
bazelbuild/rules_docker
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
| Bazel CI |
|---|
🚨 rules_docker is maintained on an as-needed basis. Please seerules_oci for an alternative. Thisrepo was previously archived in Oct 2023, then unarchived Nov 2024 asrules_docker remains a dependency for many projects. Having it in an unarchivedstate permits the community to post new issues, workarounds, and maintainanceand security pull requests.
- container_image (example)
- container_bundle (example)
- container_import
- container_load
- container_pull (example)
- container_push (example)
These rules used to bedocker_build,docker_push, etc. and the aliases forthese (mostly) legacy names still exist largely for backwards-compatibility. Wealso haveearly-stageoci_image,oci_push, etc. aliases for folks thatenjoy the consistency of a consistent rule prefix. The only place theformat-specific names currently do any more than alias things is infoo_push,where they also specify the appropriate format as which to publish the image.
This repository contains a set of rules for pulling down base images, augmentingthem with build artifacts and assets, and publishing those images.These rules do not require / use Docker for pulling, building, or pushingimages. This means:
- They can be used to develop Docker containers on OSX without
boot2dockerordocker-machineinstalled. Note use of these rules on Windowsis currently not supported. - They do not require root access on your workstation.
Also, unlike traditional container builds (e.g. Dockerfile), the Docker imagesproduced bycontainer_image are deterministic / reproducible.
To get started with building Docker images, check out theexamplesthat build the same images using both rules_docker and a Dockerfile.
NOTE:container_push andcontainer_pull make use ofgoogle/go-containerregistry forregistry interactions.
- py_image (signature)
- py3_image (signature)
- nodejs_image (usage)
- java_image (signature)
- war_image (signature)
- scala_image (signature)
- groovy_image (signature)
- cc_image (signature)
- go_image (signature)
- rust_image (signature)
- d_image (signature)
It is notable that:cc_image,go_image,rust_image, andd_imagealso allow you to specify an external binary target.
This repo now includes rules that provide additional functionalityto install packages and run commands inside docker containers. Theserules, however, require a docker binary is present and properlyconfigured. These rules include:
- Package manager rules: rules to installapt-get packages.
- Docker run rules: rules to run commands inside dockercontainers.
In addition to low-level rules for building containers, this repositoryprovides a set of higher-level rules for containerizing applications. The ideabehind these rules is to make containerizing an application built via alang_binary rule as simple as changing it tolang_image.
By default these higher level rules make use of thedistroless language runtimes, but thesecan be overridden via thebase="..." attribute (e.g. with acontainer_pullorcontainer_image target).
Note also that these rules do not expose any docker related attributes. If youneed to add a customenv orsymlink to alang_image, you must usecontainer_image targets for this purpose. Specifically, you can use as base for yourlang_image target acontainer_image target that adds e.g., customenv orsymlink.Please seego_image (custom base) for an example.
Add the following to yourWORKSPACE file to add the external repositories:
load("@bazel_tools//tools/build_defs/repo:http.bzl","http_archive")http_archive(# Get copy paste instructions for the http_archive attributes from the# release notes at https://github.com/bazelbuild/rules_docker/releases)# OPTIONAL: Call this to override the default docker toolchain configuration.# This call should be placed BEFORE the call to "container_repositories" below# to actually override the default toolchain configuration.# Note this is only required if you actually want to call# docker_toolchain_configure with a custom attr; please read the toolchains# docs in /toolchains/docker/ before blindly adding this to your WORKSPACE.# BEGIN OPTIONAL segment:load("@io_bazel_rules_docker//toolchains/docker:toolchain.bzl",docker_toolchain_configure="toolchain_configure")docker_toolchain_configure(name="docker_config",# OPTIONAL: Bazel target for the build_tar tool, must be compatible with build_tar.pybuild_tar_target="<enter absolute path (i.e., must start with repo name @...//:...) to an executable build_tar target>",# OPTIONAL: Path to a directory which has a custom docker client config.json.# See https://docs.docker.com/engine/reference/commandline/cli/#configuration-files# for more details.client_config="<enter Bazel label to your docker config.json here>",# OPTIONAL: Path to the docker binary.# Should be set explicitly for remote execution.docker_path="<enter absolute path to the docker binary (in the remote exec env) here>",# OPTIONAL: Path to the gzip binary.gzip_path="<enter absolute path to the gzip binary (in the remote exec env) here>",# OPTIONAL: Bazel target for the gzip tool.gzip_target="<enter absolute path (i.e., must start with repo name @...//:...) to an executable gzip target>",# OPTIONAL: Path to the xz binary.# Should be set explicitly for remote execution.xz_path="<enter absolute path to the xz binary (in the remote exec env) here>",# OPTIONAL: Bazel target for the xz tool.# Either xz_path or xz_target should be set explicitly for remote execution.xz_target="<enter absolute path (i.e., must start with repo name @...//:...) to an executable xz target>",# OPTIONAL: List of additional flags to pass to the docker command.docker_flags= ["--tls","--log-level=info", ],)# End of OPTIONAL segment.load("@io_bazel_rules_docker//repositories:repositories.bzl",container_repositories="repositories",)container_repositories()load("@io_bazel_rules_docker//repositories:deps.bzl",container_deps="deps")container_deps()load("@io_bazel_rules_docker//container:container.bzl","container_pull",)container_pull(name="java_base",registry="gcr.io",repository="distroless/java",# 'tag' is also supported, but digest is encouraged for reproducibility.digest="sha256:deadbeef",)
- Bazel does not deal well with diamond dependencies.
If the repositories that are imported bycontainer_repositories() have already beenimported (at a different version) by other rules you called in yourWORKSPACE, whichare placed above the call tocontainer_repositories(), arbitrary errors mightoccur. If you get errors related to external repositories, you will likelynot be able to usecontainer_repositories() and will have to importdirectly in yourWORKSPACE all the required dependencies (see the most upto date impl ofcontainer_repositories() for details).
- ImportError: No module named moves.urllib.parse
This is an example of an error due to a diamond dependency. If you get thiserror, make sure to import rules_docker before other libraries, so thatsix can be patched properly.
See#1022 for more details.
- Ensure your project has a
BUILDorBUILD.bazelfile at the top level. Thiscan be a blank file if necessary. Otherwise you might see an error that lookslike:
Unable to load package for //:WORKSPACE: BUILD file not found in any of the following directories.- rules_docker uses transitions to build your containers using toolchains the correctarchitecture and operating system. If you run into issues with toolchain resolutions,you can disable this behaviour, by adding this to your .bazelrc:
build --@io_bazel_rules_docker//transitions:enable=falseSuppose you have acontainer_image target//my/image:helloworld:
container_image(name="helloworld", ...)
You can load this into your local Docker client by running:bazel run my/image:helloworld.
For thelang_image targets, this will alsorun thecontainer usingdocker run to maximize compatibility withlang_binary rules.
Arguments to this command are forwarded to docker, meaning the command
bazel run my/image:helloworld -- -p 8080:80 -- arg0
performs the following steps:
- load the
my/image:helloworldtarget into your local Docker client - start a container using this image where
arg0is passed to the image entrypoint - port forward 8080 on the host to port 80 on the container, as per
docker rundocumentation
You can suppress this behavior by passing the single flag:bazel run :foo -- --norun
Alternatively, you can build adocker load compatible bundle with:bazel build my/image:helloworld.tar. This will produce a tar filein yourbazel-out directory that can be loaded into your local Dockerclient. Building this target can be expensive for large images. You willfirst need to query the ouput file location.
TARBALL_LOCATION=$(bazel cquery my/image:helloworld.tar \ --output starlark \ --starlark:expr="target.files.to_list()[0].path")docker load -i$TARBALL_LOCATION
These work with bothcontainer_image,container_bundle, and thelang_image rules. For everything exceptcontainer_bundle, the imagename will bebazel/my/image:helloworld. Thecontainer_bundle rule willapply the tags you have specified.
You can use these rules to access private images using standard Dockerauthentication methods. e.g. to utilize theGoogle Container Registry. Seehere for authentication methods.
See also:
Once you've setup your docker client configuration, seeherefor an example of how to usecontainer_pull with custom docker authentication credentialsandhere for an example of howto usecontainer_push with custom docker authentication credentials.
A common request from folks usingcontainer_push,container_bundle, orcontainer_image is tobe able to vary the tag that is pushed or embedded. There are two optionsat present for doing this.
The first option is to use stamping.Stamping is enabled when bazel is run with--stamp.This enables replacements in stamp-aware attributes.A python format placeholder (e.g.{BUILD_USER})is replaced by the value of the corresponding workspace-status variable.
# A common pattern when users want to avoid trampling# on each other's images during development.container_push(name="publish",format="Docker",# Any of these components may have variables.registry="gcr.io",repository="my-project/my-image",# This will be replaced with the current user when built with --stamptag="{BUILD_USER}",)
Rules that are sensitive to stamping can also be forced to stamp or non-stamp modeirrespective of the
--stampflag to Bazel. Use thebuild_context_dataruleto make a target that providesStampSettingInfo, and pass this to thebuild_context_dataattribute.
The next natural question is: "Well what variables can I use?" Thisoption consumes the workspace-status variables Bazel defines inbazel-out/stable-status.txt andbazel-out/volatile-status.txt.
Note that changes to the stable-status filecause a rebuild of the action, while volatile-status does not.
You can add more stamp variables via--workspace_status_command,see thebazel docs.A common example is to provide the current git SHA, with--workspace_status_command="echo STABLE_GIT_SHA $(git rev-parse HEAD)"
That flag is typically passed in the.bazelrc file, see for example.bazelrc in kubernetes.
The second option is to employMakefile-style variables:
container_bundle(name="bundle",images= {"gcr.io/$(project)/frontend:latest":"//frontend:image","gcr.io/$(project)/backend:latest":"//backend:image", })
These variables are specified on the CLI using:
bazel build --define project=blah //path/to:bundle
By default thelang_image rules use thedistroless base runtime images,which are optimized to be the minimal set of things your application needsat runtime. That can make debugging these containers difficult because theylack even a basic shell for exploring the filesystem.
To address this, we publish variants of thedistroless runtime images tagged:debug, which are the exact-same images, but with additions such asbusyboxto make debugging easier.
For example (in this repo):
$ bazel run -c dbg testdata:go_image...INFO: Build completed successfully, 5 total actionsINFO: Runningcommand line: bazel-bin/testdata/go_imageLoaded image ID: sha256:9c5c2167a1db080a64b5b401b43b3c5cdabb265b26cf7a60aabe04a20da79e24Tagging 9c5c2167a1db080a64b5b401b43b3c5cdabb265b26cf7a60aabe04a20da79e24 as bazel/testdata:go_imageHello, world!$ docker run -ti --rm --entrypoint=sh bazel/testdata:go_image -c"echo Hello, busybox."Hello, busybox.
container_image(name="app",# References container_pull from WORKSPACE (above)base="@java_base//image",files= ["//java/com/example/app:Hello_deploy.jar"],cmd= ["Hello_deploy.jar"])
Hint: if you want to put files in specific directories inside the imageusepkg_tar ruleto create the desired directory structure and pass that tocontainer_image viatars attribute. Note you might need to setstrip_prefix = "." orstrip_prefix = "{some directory}"in your rule for the files to not be flattened.SeeBazel upstream issue 2176 andrules_docker issue 317for more details.
To usecc_image, add the following toWORKSPACE:
load("@io_bazel_rules_docker//repositories:repositories.bzl",container_repositories="repositories",)container_repositories()load("@io_bazel_rules_docker//cc:image.bzl",_cc_image_repos="repositories",)_cc_image_repos()
Then in yourBUILD file, simply rewritecc_binary tocc_image with thefollowing import:
load("@io_bazel_rules_docker//cc:image.bzl","cc_image")cc_image(name="cc_image",srcs= ["cc_image.cc"],deps= [":cc_image_library"],)
To usecc_image (orgo_image,d_image,rust_image) with an externalcc_binary (or the like) target, then yourBUILD file should instead looklike:
load("@io_bazel_rules_docker//cc:image.bzl","cc_image")cc_binary(name="cc_binary",srcs= ["cc_binary.cc"],deps= [":cc_library"],)cc_image(name="cc_image",binary=":cc_binary",)
If you need to modify somehow the container produced bycc_image (e.g.,env,symlink), see note above inLanguage Rules Overview about how to do thisand seego_image (custom base) example below.
To usepy_image, add the following toWORKSPACE:
load("@io_bazel_rules_docker//repositories:repositories.bzl",container_repositories="repositories",)container_repositories()load("@io_bazel_rules_docker//python:image.bzl",_py_image_repos="repositories",)_py_image_repos()
Then in yourBUILD file, simply rewritepy_binary topy_image with thefollowing import:
load("@io_bazel_rules_docker//python:image.bzl","py_image")py_image(name="py_image",srcs= ["py_image.py"],deps= [":py_image_library"],main="py_image.py",)
If you need to modify somehow the container produced bypy_image (e.g.,env,symlink), see note above inLanguage Rules Overview about how to do thisand seego_image (custom base) example below.
If you are usingpy_image with a custom base that has python tools installedin a location different to the default base, please seePython tools.
For Python and Java'slang_image rules, you can factordependencies that don't change into their own layers by overriding thelayers=[] attribute. Consider this sample from therules_k8s repository:
py_image(name="server",srcs= ["server.py"],# "layers" is just like "deps", but it also moves the dependencies each into# their own layer, which can dramatically improve developer cycle time. For# example here, the grpcio layer is ~40MB, but the rest of the app is only# ~400KB. By partitioning things this way, the large grpcio layer remains# unchanging and we can reduce the amount of image data we repush by ~99%!layers= [requirement("grpcio"),"//examples/hellogrpc/proto:py", ],main="server.py",)
You can also implement more complex fine layering strategies by using thepy_layer orjava_layer rules and theirfilter attribute. For example:
# Suppose that we are synthesizing an image that depends on a complex set# of libraries that we want to break into layers.LIBS= ["//pkg/complex_library",# ...]# First, we extract all transitive dependencies of LIBS that are under //pkg/common.py_layer(name="common_deps",deps=LIBS,filter="//pkg/common",)# Then, we further extract all external dependencies of the deps under //pkg/common.py_layer(name="common_external_deps",deps= [":common_deps"],filter="@",)# We also extract all external dependencies of LIBS, which is a superset of# ":common_external_deps".py_layer(name="external_deps",deps=LIBS,filter="@",)# Finally, we create the image, stacking the above filtered layers on top of one# another in the "layers" attribute. The layers are applied in order, and any# dependencies already added to the image will not be added again. Therefore,# ":external_deps" will only add the external dependencies not present in# ":common_external_deps".py_image(name="image",deps=LIBS,layers= [":common_external_deps",":common_deps",":external_deps", ],# ...)
To use a Python 3 runtime instead of the default of Python 2, usepy3_image,instead ofpy_image. The other semantics are identical.
If you need to modify somehow the container produced bypy3_image (e.g.,env,symlink), see note above inLanguage Rules Overview about how to do thisand seego_image (custom base) example below.
If you are usingpy3_image with a custom base that has python tools installedin a location different to the default base, please seePython tools.
It is notable that unlike the other image rules,nodejs_image is notcurrently using thegcr.io/distroless/nodejs image for a handful of reasons.This is a switch we plan to make, when we can manage it. We are currentlyutilizing thegcr.io/google-appengine/debian9 image as our base.
To usenodejs_image, add the following toWORKSPACE:
load("@bazel_tools//tools/build_defs/repo:http.bzl","http_archive")http_archive(name="build_bazel_rules_nodejs",# Replace with a real SHA256 checksumsha256="{SHA256}"# Replace with a real release versionurls= ["https://github.com/bazelbuild/rules_nodejs/releases/download/{VERSION}/rules_nodejs-{VERSION}.tar.gz"],)load("@build_bazel_rules_nodejs//:index.bzl","npm_install")# Install your declared Node.js dependenciesnpm_install(name="npm",package_json="//:package.json",yarn_lock="//:yarn.lock",)load("@io_bazel_rules_docker//repositories:repositories.bzl",container_repositories="repositories",)container_repositories()load("@io_bazel_rules_docker//nodejs:image.bzl",_nodejs_image_repos="repositories",)_nodejs_image_repos()
Note: See note about diamond dependencies insetupif you run into issues related to external repos after adding theselines to yourWORKSPACE.
Then in yourBUILD file, simply rewritenodejs_binary tonodejs_image withthe following import:
load("@io_bazel_rules_docker//nodejs:image.bzl","nodejs_image")nodejs_image(name="nodejs_image",entry_point="@your_workspace//path/to:file.js",# npm deps will be put into their own layerdata= [":file.js","@npm//some-npm-dep"], ...)
nodejs_image also supports thelauncher andlauncher_args attributes which are passed tocontainer_image and used to prefix the image'sentry_point.
If you need to modify somehow the container produced bynodejs_image (e.g.,env,symlink), see note above inLanguage Rules Overview about how to do thisand seego_image (custom base) example below.
To usego_image, add the following toWORKSPACE:
load("@bazel_tools//tools/build_defs/repo:http.bzl","http_archive")load("@io_bazel_rules_docker//repositories:repositories.bzl",container_repositories="repositories",)container_repositories()load("@io_bazel_rules_docker//go:image.bzl",_go_image_repos="repositories",)_go_image_repos()
Note: See note about diamond dependencies insetupif you run into issues related to external repos after adding theselines to yourWORKSPACE.
Then in yourBUILD file, simply rewritego_binary togo_image with thefollowing import:
load("@io_bazel_rules_docker//go:image.bzl","go_image")go_image(name="go_image",srcs= ["main.go"],importpath="github.com/your/path/here",)
Notice that it is important to explicitly build this target with the--platforms=@io_bazel_rules_go//go/toolchain:linux_amd64 flagas the binary should be built for Linux since it will run in a Linux container.
If you need to modify somehow the container produced bygo_image (e.g.,env,symlink), see note above inLanguage Rules Overview about how to do this andsee example below.
To use a custom base image, with any of thelang_imagerules, you can override the defaultbase="..." attribute. Consider thismodified sample from thedistroless repository:
load("@rules_pkg//pkg:tar.bzl","pkg_tar")# Create a passwd file with a root and nonroot user and uid.passwd_entry(username="root",uid=0,gid=0,name="root_user",)passwd_entry(username="nonroot",info="nonroot",uid=1002,name="nonroot_user",)passwd_file(name="passwd",entries= [":root_user",":nonroot_user", ],)# Create a tar file containing the created passwd filepkg_tar(name="passwd_tar",srcs= [":passwd"],mode="0o644",package_dir="etc",)# Include it in our base image as a tar.container_image(name="passwd_image",base="@go_image_base//image",tars= [":passwd_tar"],user="nonroot",)# Simple go program to print out the username and uid.go_image(name="user",srcs= ["user.go"],# Override the base image.base=":passwd_image",)
To usejava_image, add the following toWORKSPACE:
load("@io_bazel_rules_docker//repositories:repositories.bzl",container_repositories="repositories",)container_repositories()load("@io_bazel_rules_docker//java:image.bzl",_java_image_repos="repositories",)_java_image_repos()
Then in yourBUILD file, simply rewritejava_binary tojava_image with thefollowing import:
load("@io_bazel_rules_docker//java:image.bzl","java_image")java_image(name="java_image",srcs= ["Binary.java"],# Put these runfiles into their own layer.layers= [":java_image_library"],main_class="examples.images.Binary",)
If you need to modify somehow the container produced byjava_image (e.g.,env,symlink), see note above inLanguage Rules Overview about how to do thisand seego_image (custom base) example.
To usewar_image, add the following toWORKSPACE:
load("@io_bazel_rules_docker//repositories:repositories.bzl",container_repositories="repositories",)container_repositories()load("@io_bazel_rules_docker//java:image.bzl",_java_image_repos="repositories",)_java_image_repos()
Note: See note about diamond dependencies insetupif you run into issues related to external repos after adding theselines to yourWORKSPACE.
Then in yourBUILD file, simply rewritejava_war towar_image with thefollowing import:
load("@io_bazel_rules_docker//java:image.bzl","war_image")war_image(name="war_image",srcs= ["Servlet.java"],# Put these JARs into their own layers.layers= [":java_image_library","@javax_servlet_api//jar:jar", ],)
The 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 aServlet dependency provided by the Jetty project.
A Servlet implementation needs to declare the@WebServlet annotation to be auto-discovered. The use of aweb.xml to declare the Servlet URL mapping is not supported.
If you need to modify somehow the container produced bywar_image (e.g.,env,symlink), see note above inLanguage Rules Overview about how to do thisand seego_image (custom base) example.
To usescala_image, add the following toWORKSPACE:
load("@bazel_tools//tools/build_defs/repo:http.bzl","http_archive")# You *must* import the Scala rules before setting up the scala_image rules.http_archive(name="io_bazel_rules_scala",# Replace with a real SHA256 checksumsha256="{SHA256}"# Replace with a real commit SHAstrip_prefix="rules_scala-{HEAD}",urls= ["https://github.com/bazelbuild/rules_scala/archive/{HEAD}.tar.gz"],)load("@io_bazel_rules_scala//scala:scala.bzl","scala_repositories")scala_repositories()load("@io_bazel_rules_docker//repositories:repositories.bzl",container_repositories="repositories",)container_repositories()load("@io_bazel_rules_docker//scala:image.bzl",_scala_image_repos="repositories",)_scala_image_repos()
Note: See note about diamond dependencies insetupif you run into issues related to external repos after adding theselines to yourWORKSPACE.
Then in yourBUILD file, simply rewritescala_binary toscala_image with thefollowing import:
load("@io_bazel_rules_docker//scala:image.bzl","scala_image")scala_image(name="scala_image",srcs= ["Binary.scala"],main_class="examples.images.Binary",)
If you need to modify somehow the container produced byscala_image (e.g.,env,symlink), see note above inLanguage Rules Overview about how to do thisand seego_image (custom base) example.
To usegroovy_image, add the following toWORKSPACE:
load("@bazel_tools//tools/build_defs/repo:http.bzl","http_archive")# You *must* import the Groovy rules before setting up the groovy_image rules.http_archive(name="io_bazel_rules_groovy",# Replace with a real SHA256 checksumsha256="{SHA256}"# Replace with a real commit SHAstrip_prefix="rules_groovy-{HEAD}",urls= ["https://github.com/bazelbuild/rules_groovy/archive/{HEAD}.tar.gz"],)load("@io_bazel_rules_groovy//groovy:groovy.bzl","groovy_repositories")groovy_repositories()load("@io_bazel_rules_docker//repositories:repositories.bzl",container_repositories="repositories",)container_repositories()load("@io_bazel_rules_docker//groovy:image.bzl",_groovy_image_repos="repositories",)_groovy_image_repos()
Note: See note about diamond dependencies insetupif you run into issues related to external repos after adding theselines to yourWORKSPACE.
Then in yourBUILD file, simply rewritegroovy_binary togroovy_image with thefollowing import:
load("@io_bazel_rules_docker//groovy:image.bzl","groovy_image")groovy_image(name="groovy_image",srcs= ["Binary.groovy"],main_class="examples.images.Binary",)
If you need to modify somehow the container produced bygroovy_image (e.g.,env,symlink), see note above inLanguage Rules Overview about how to do thisand seego_image (custom base) example.
To userust_image, add the following toWORKSPACE:
load("@bazel_tools//tools/build_defs/repo:http.bzl","http_archive")# You *must* import the Rust rules before setting up the rust_image rules.http_archive(name="rules_rust",# Replace with a real SHA256 checksumsha256="{SHA256}"# Replace with a real commit SHAstrip_prefix="rules_rust-{HEAD}",urls= ["https://github.com/bazelbuild/rules_rust/archive/{HEAD}.tar.gz"],)load("@rules_rust//rust:repositories.bzl","rust_repositories")rust_repositories()load("@io_bazel_rules_docker//repositories:repositories.bzl",container_repositories="repositories",)container_repositories()load("@io_bazel_rules_docker//rust:image.bzl",_rust_image_repos="repositories",)_rust_image_repos()
Note: See note about diamond dependencies insetupif you run into issues related to external repos after adding theselines to yourWORKSPACE.
Then in yourBUILD file, simply rewriterust_binary torust_image with thefollowing import:
load("@io_bazel_rules_docker//rust:image.bzl","rust_image")rust_image(name="rust_image",srcs= ["main.rs"],)
If you need to modify somehow the container produced byrust_image (e.g.,env,symlink), see note above inLanguage Rules Overview about how to do thisand seego_image (custom base) example.
To used_image, add the following toWORKSPACE:
load("@bazel_tools//tools/build_defs/repo:http.bzl","http_archive")# You *must* import the D rules before setting up the d_image rules.http_archive(name="io_bazel_rules_d",# Replace with a real SHA256 checksumsha256="{SHA256}"# Replace with a real commit SHAstrip_prefix="rules_d-{HEAD}",urls= ["https://github.com/bazelbuild/rules_d/archive/{HEAD}.tar.gz"],)load("@io_bazel_rules_d//d:d.bzl","d_repositories")d_repositories()load("@io_bazel_rules_docker//repositories:repositories.bzl",container_repositories="repositories",)container_repositories()load("@io_bazel_rules_docker//d:image.bzl",_d_image_repos="repositories",)_d_image_repos()
Note: See note about diamond dependencies insetupif you run into issues related to external repos after adding theselines to yourWORKSPACE.
Then in yourBUILD file, simply rewrited_binary tod_image with thefollowing import:
load("@io_bazel_rules_docker//d:image.bzl","d_image")d_image(name="d_image",srcs= ["main.d"],)
If you need to modify somehow the container produced byd_image (e.g.,env,symlink), see note above inLanguage Rules Overview about how to do thisand seego_image (custom base) example.
NOTE: all application image rules support the
argsstring_listattribute. If specified, they will be appended directly after thecontainer ENTRYPOINT binary name.
container_bundle(name="bundle",images= {# A set of images to bundle up into a single tarball."gcr.io/foo/bar:bazz":":app","gcr.io/foo/bar:blah":"//my:sidecar","gcr.io/foo/bar:booo":"@your//random:image", })
InWORKSPACE:
container_pull(name="base",registry="gcr.io",repository="my-project/my-base",# 'tag' is also supported, but digest is encouraged for reproducibility.digest="sha256:deadbeef",)
This can then be referenced inBUILD files as@base//image.
To get the correct digest one can rundocker manifest inspect gcr.io/my-project/my-base:tag onceexperimental docker cli features are enabled.
Seehere for an example of howto use container_pull with custom docker authentication credentials.
This target pushes onbazel run :push_foo:
container_push(name="push_foo",image=":foo",format="Docker",registry="gcr.io",repository="my-project/my-image",tag="dev",)
We also support thedocker_push (fromdocker/docker.bzl) andoci_push(fromoci/oci.bzl) aliases, which bake in theformat = "..." attribute.
Seehere for an example of howto use container_push with custom docker authentication credentials.
If you wish to use container_push using custom docker authentication credentials,inWORKSPACE:
# Download the rules_docker repositoryhttp_archive(name="io_bazel_rules_docker", ...)# Load the macro that allows you to customize the docker toolchain configuration.load("@io_bazel_rules_docker//toolchains/docker:toolchain.bzl",docker_toolchain_configure="toolchain_configure")docker_toolchain_configure(name="docker_config",# Replace this with a Bazel label to the config.json file. Note absolute or relative# paths are not supported. Docker allows you to specify custom authentication credentials# in the client configuration JSON file.# See https://docs.docker.com/engine/reference/commandline/cli/#configuration-files# for more details.client_config="@//path/to/docker:config.json",)
InBUILD file:
load("@io_bazel_rules_docker//container:container.bzl","container_push")container_push(name="push_foo",image=":foo",format="Docker",registry="gcr.io",repository="my-project/my-image",tag="dev",)
InWORKSPACE:
container_pull(name="official_ubuntu",registry="index.docker.io",repository="library/ubuntu",tag="14.04",)
This can then be referenced inBUILD files as@official_ubuntu//image.
InWORKSPACE:
container_pull(name="etcd",registry="quay.io",repository="coreos/etcd",tag="latest",)
This can then be referenced inBUILD files as@etcd//image.
InWORKSPACE:
container_pull(name="artifactory",registry="docker.bintray.io",repository="jfrog/artifactory-pro",)
This can then be referenced inBUILD files as@artifactory//image.
InWORKSPACE:
container_pull(name="gitlab",registry="registry.gitlab.com",repository="username/project/image",tag="tag",)
This can then be referenced inBUILD files as@gitlab//image.
If you specified a docker client directory using theclient_config attributeto the docker toolchain configuration describedhere, youcan use a container_pull that uses the authentication credentials from thespecified docker client directory as follows:
InWORKSPACE:
load("@io_bazel_rules_docker//toolchains/docker:toolchain.bzl",docker_toolchain_configure="toolchain_configure")# Configure the docker toolchain.docker_toolchain_configure(name="docker_config",# Bazel label to a custom docker client config.json with# authentication credentials for registry.gitlab.com (used in this example).client_config="@//path/to/docker/client:config.json",)# Load the custom version of container_pull created by the docker toolchain# configuration.load("@docker_config//:pull.bzl",authenticated_container_pull="container_pull")authenticated_container_pull(name="gitlab",registry="registry.gitlab.com",repository="username/project/image",tag="tag",)
This can then be referenced inBUILD files as@gitlab//image.
NOTE: This should only be used if a customclient_config was set. If you wantto use the DOCKER_CONFIG env variable or the default home directoryuse the standardcontainer_pull rule.
NOTE: This will only work on systems with Python >2.7.6
Starting with Bazel 0.25.0 it's possible to configure python toolchainsforrules_docker.
To use these features you need to enable the flags in the.bazelrcfile at the root of this project.
Use of these features require a python toolchain to be registered.//py_images/image.bzl:deps and//py3_images/image.bzl:deps register adefault python toolchain (//toolchains:container_py_toolchain)that defines the path to python tools inside the default container usedfor these rules.
If you are using a custom base forpy_image orpy3_image builds that haspython tools installed in a different location to those defined in//toolchains:container_py_toolchain, you will need to create atoolchain that points to these paths and register itbefore the call topy*_images/image.bzl:deps in yourWORKSPACE.
Use of python toolchain features, currently, only supports picking oneversion of python for execution of host tools.rules_docker heavily dependson execution of python host tools that are only compatible with python 2.Flags in the recommended.bazelrc file force all host tools to use python 2.If your project requires using host tools that are only compatible withpython 3 you will not be able to use these features at the moment. Weexpect this issue to be resolved before use of python toolchain featuresbecomes the default.
The digest references to thedistroless base images must be updated over timeto pick up bug fixes and security patches. To facilitate this, the filescontaining the digest references are generated bytools/update_deps.py. Toupdate all of the dependencies, please run (from the root of the repository):
./update_deps.sh
Image references should not be updated individually because these images haveshared layers and letting them diverge could result in sub-optimal push and pullperformance.
MOVED: Seedocs/container.md
MOVED: Seedocs/container.md
MOVED: Seedocs/container.md
MOVED: Seedocs/container.md
MOVED: Seedocs/container.md
MOVED: Seedocs/container.md
MOVED: Seedocs/container.md
Here's a (non-exhaustive) list of companies that userules_docker in production. Don't see yours?You can add it in a PR!
About
Rules for building and handling Docker images with Bazel
Topics
Resources
License
Contributing
Security policy
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Uh oh!
There was an error while loading.Please reload this page.