Travis CI | Bazel CI |
---|---|
This repository contains a set of rules for pulling down base images, augmenting them with build artifacts and assets, and publishing those images. These rules do not require / use Docker for pulling, building, or pushing images. This means:
- They can be used to develop Docker containers on Windows / OSX without
boot2docker
ordocker-machine
installed. - They do not require root access on your workstation.
Also, unlike traditional Docker builds, the Docker images produced by
docker_build
are deterministic / reproducible.
NOTE: docker_push
and docker_pull
make use of
google/containerregistry for
registry interactions.
Add the following to your WORKSPACE
file to add the external repositories:
git_repository(
name = "io_bazel_rules_docker",
remote = "https://github.com/bazelbuild/rules_docker.git",
tag = "v0.1.0",
)
load(
"@io_bazel_rules_docker//docker:docker.bzl",
"docker_repositories", "docker_pull"
)
docker_repositories()
docker_pull(
name = "java_base",
registry = "gcr.io",
repository = "distroless/java",
# 'tag' is also supported, but digest is encouraged for reproducibility.
digest = "sha256:deadbeef",
)
Suppose you have a docker_build
target //my/image:helloworld
:
docker_build(
name = "helloworld",
...
)
You can load this into your local Docker client by running:
bazel run my/image:helloworld
.
Alternately, you can build a docker load
compatible bundle with:
bazel build my/image:helloworld.tar
. This will produce the file:
bazel-genfiles/my/image/helloworld.tar
, which you can load into
your local Docker client by running:
docker load -i bazel-genfiles/my/image/helloworld.tar
. Building
this target can be expensive for large images.
These work with both docker_build
and docker_bundle
. For
docker_build
the image name will be bazel/my/image:helloworld
.
For docker_bundle
, it will apply the tags you have specified.
You can use these rules to access private images using standard Docker authentication methods. e.g. to utilize the Google Container Registry credential helper:
$ gcloud components install docker-credential-gcr
$ docker-credential-gcr configure-docker
A common request from folks using docker_push
or docker_bundle
is to
be able to vary the tag that is pushed or embedded. There are two options
at present for doing this.
The first option is to use stamp = True
.
# A common pattern when users want to avoid trampling
# on each other's images during development.
docker_push(
name = "publish",
# Any of these components may have variables.
registry = "gcr.io",
repository = "my-project/my-image",
tag = "{BUILD_USER}",
# Trigger stamping.
stamp = True,
)
The next natural question is: "Well what variables can I use?" This
option consumes the workspace-status variables Bazel defines in
stable-status.txt
and volatile-status.txt
. These files will appear
in the target's runfiles:
$ bazel build //docker/testdata:push_stamp
...
$ cat bazel-bin/docker/testdata/push_stamp.runfiles/io_bazel_rules_docker/stable-status.txt
BUILD_EMBED_LABEL
BUILD_HOST bazel
BUILD_USER mattmoor
$ cat bazel-bin/docker/testdata/push_stamp.runfiles/io_bazel_rules_docker/volatile-status.txt
BUILD_TIMESTAMP 1498740967769
You can augment these variables via --workspace_status_command
,
including through the use of .bazelrc
.
The second option is to employ Makefile
-style variables:
docker_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
docker_build(
name = "app",
# References docker_pull from WORKSPACE (above)
base = "@java_base//image",
files = ["//java/com/example/app:Hello_deploy.jar"],
cmd = ["Hello_deploy.jar"]
)
docker_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",
}
)
In WORKSPACE
:
docker_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 in BUILD
files as @base//image
.
This target pushes on bazel run :push_foo
:
docker_push(
name = "push_foo",
image = ":foo",
registry = "gcr.io",
repository = "my-project/my-image",
tag = "dev",
)
In WORKSPACE
:
docker_pull(
name = "official_ubuntu",
registry = "index.docker.io",
repository = "library/ubuntu",
tag = "14.04",
)
This can then be referenced in BUILD
files as @official_ubuntu//image
.
In WORKSPACE
:
docker_pull(
name = "etcd",
registry = "quay.io",
repository = "coreos/etcd",
tag = "latest",
)
This can then be referenced in BUILD
files as @etcd//image
.
In WORKSPACE
:
docker_pull(
name = "artifactory",
registry = "docker.bintray.io",
repository = "jfrog/artifactory-pro",
)
This can then be referenced in BUILD
files as @artifactory//image
.
In WORKSPACE
:
docker_pull(
name = "gitlab",
registry = "registry.gitlab.com",
repository = "username/project/image",
tag = "tag",
)
This can then be referenced in BUILD
files as @gitlab//image
.
NOTE: This will only work on systems with Python >2.7.6
docker_pull(name, registry, repository, digest, tag)
A repository rule that pulls down a Docker base image in a manner suitable for
use with docker_build
's base
attribute.
Attributes | |
---|---|
name |
Unique name for this repository rule. |
registry |
The registry from which to pull the base image. |
repository |
The `repository` of images to pull from. |
digest |
The `digest` of the Docker image to pull from the specified `repository`. Note: For reproducible builds, use of `digest` is recommended. |
tag |
The `tag` of the Docker image to pull from the specified `repository`. If neither this nor `digest` is specified, this attribute defaults to `latest`. If both are specified, then `tag` is ignored. Note: For reproducible builds, use of `digest` is recommended. |
docker_push(name, image, registry, repository, tag)
An executable rule that pushes a Docker image to a Docker registry on bazel run
.
Attributes | |
---|---|
name |
Unique name for this rule. |
image |
The label containing a Docker image to publish. |
registry |
The registry to which to publish the image. |
repository |
The `repository` of images to which to push. |
tag |
The `tag` of the Docker image to push to the specified `repository`. This attribute defaults to `latest`. |
stamp |
If true, enable use of workspace status variables
(e.g. These fields are specified in the tag using using Python format
syntax, e.g.
|
docker_build(name, base, data_path, directory, files, legacy_repository_naming, mode, tars, debs, symlinks, entrypoint, cmd, env, labels, ports, volumes, workdir, repository)
Implicit output targets | |
---|---|
name.tar |
The full Docker image
A full Docker image containing all the layers, identical to
what |
name-layer.tar |
An image of the current layer
A Docker image containing only the layer corresponding to that target. It is used for incremental loading of the layer. Note: this target is not suitable for direct consumption. It is used for incremental loading and non-docker rules should depends on the Docker image (name.tar) instead. |
name |
Incremental image loader
The incremental image loader. It will load only changed layers inside the Docker registry. |
Attributes | |
---|---|
name |
Name, required
A unique name for this rule. |
base |
File, optional
The base layers on top of which to overlay this layer, equivalent to FROM. |
data_path |
String, optional
Root path of the files. The directory structure from the files is preserved inside the Docker image, but a prefix path determined by `data_path` is removed from the directory structure. This path can be absolute from the workspace root if starting with a `/` or relative to the rule's directory. A relative path may starts with "./" (or be ".") but cannot use go up with "..". By default, the `data_path` attribute is unused, and all files should have no prefix. |
directory |
String, optional
Target directory. The directory in which to expand the specified files, defaulting to '/'. Only makes sense accompanying one of files/tars/debs. |
files |
List of files, optional
File to add to the layer. A list of files that should be included in the Docker image. |
legacy_repository_naming |
Bool, default to False
Whether to use the legacy strategy for setting the repository name
embedded in the resulting tarball.
e.g. |
mode |
String, default to 0555
Set the mode of files added by the |
tars |
List of files, optional
Tar file to extract in the layer. A list of tar files whose content should be in the Docker image. |
debs |
List of files, optional
Debian package to install. A list of debian packages that will be installed in the Docker image. |
symlinks |
Dictionary, optional
Symlinks to create in the Docker image.
|
user |
String, optional
The user that the image should run as. Because building the image never happens inside a Docker container, this user does not affect the other actions (e.g., adding files). |
entrypoint |
String or string list, optional
|
cmd |
String or string list, optional
|
env |
Dictionary from strings to strings, optional
Dictionary from environment variable names to their values when running the Docker image.
|
labels |
Dictionary from strings to strings, optional
|
ports |
String list, optional
|
volumes |
String list, optional
|
workdir |
String, optional
Initial working directory when running the Docker image. Because building the image never happens inside a Docker container, this working directory does not affect the other actions (e.g., adding files). |
repository |
String, default to `bazel`
The repository for the default tag for the image. Images generated by `docker_build` are tagged by default to `bazel/package_name:target` for a `docker_build` target at `//package/name:target`. Setting this attribute to `gcr.io/dummy` would set the default tag to `gcr.io/dummy/package_name:target`. |
docker_bundle(name, images)
A rule that aliases and saves N images into a single docker save
tarball.
Attributes | |
---|---|
name |
Unique name for this rule. |
images |
A collection of the images to save into the tarball. The keys are the tags with which to alias the image specified by the
value. These tags may contain make variables ( The values may be the output of |
stamp |
If true, enable use of workspace status variables
(e.g. These fields are specified in the tag using using Python format
syntax, e.g.
|
docker_import(name, config, layers)
A rule that imports a docker image into our intermediate form.
Attributes | |
---|---|
name |
Unique name for this rule. |
config |
A json configuration file containing the image's metadata. This appears in `docker save` tarballs as `.json` and is referenced by `manifest.json` in the config field. |
layers |
The list of layer `.tar.gz` files in the order they appear in the `config.json`'s layer section, or in the order that they appear in `docker save` tarballs' `manifest.json` `Layers` field (although these are gzipped). |