Docker images typically bundle build artifacts, such as PEX files, wheels, loose files, and so on, with other runtime requirements, such as a Python interpreter.
Pants makes it easy to embed the artifacts Pants builds into your Docker images, for easy deployment.
To use Pants's Docker support you must enable the appropriate backend:
backend_packages = [ ... "pants.backend.experimental.docker", ... ]
We expect the Docker backend to graduate out of the "experimental" area soon!
A Docker image is built from a recipe specified by a Dockerfile. When you build Docker images with Pants, instead of running
docker on the Dockerfile directly, you let Pants do that for you.
You can generate initial BUILD files for your Docker images, using tailor:
$ ./pants tailor Created src/docker/app1/BUILD: - Add docker_image target docker Created src/docker/app2/BUILD: - Add docker_image target docker
Or you can add them manually, such as:
A Dockerfile executes in a context - a set of files that the commands in the Dockerfile can reference, e.g., by copying them into the image).
When you run
docker directly, the context is usually a directory within your repo. That directory must contain the Dockerfile (typically at the root of the context) and any files that the build requires. If those files are themselves the product of a build step, or if they are sources from elsewhere in the repo, then you have to copy them into the context.
Pants, however, takes care of assembling the context for you. It does so using the dependencies of the
docker_image can depend on loose files belonging to
files targets, and on artifacts packaged from a variety of targets, such as
archive, or any other target that can be built via the package goal.
The context is assembled as follows:
- The sources of
filestargets are assembled at their relative path from the repo root.
- The artifacts of any packageable targets are built, as if by running
./pants package, and placed in the context using the artifact's
output_pathdefaults to the scheme
COPY PEX binaries into your image, the dependency on the
pex_binary target will be inferred, so you don't have to add that explicitly to the list of
dependencies on your
For example, the
src/python/helloworld/bin.pex has the default
src.python.helloworld/bin.pex. So, Pants can infer a dependecy based on the line
COPY src.python.helloworld/bin.pex /bin/helloworld.
You build Docker images using the
$ ./pants package path/to/Dockerfile
To provide values to any build
ARGs in the Dockerfile, you can list them in the
[docker].build_args configuration option which will apply for all images, and list any image specific build args in the field
extra_build_args for the
The build args use the same syntax as the docker build --build-arg command line option:
VARNAME=VALUE, where the value is optional, and if left out, the value is taken from the environment instead.
[docker] build_args = [ "VAR1=value1", "VAR2" ]
docker_image( name="docker", extra_build_args=["VAR1=my_value", "VAR3"] )
FROM python:3.8 ARG VAR1 ARG VAR2 ARG VAR3=default ...
This example copies both a
file(name="msg", source="msg.txt") docker_image( name="docker", dependencies=[":msg", "src/python/hw:bin"], )
FROM python:3.8 ENTRYPOINT ["/bin/helloworld"] COPY src/docker/hw/msg.txt /var/msg COPY src.python.hw/bin.pex /bin/helloworld
python_sources(name="lib") pex_binary(name="bin", entry_point="main.py")
import os msg = "Hello" if os.path.exists("/var/msg"): with open("/var/msg") as fp: msg = fp.read().strip() print(msg)
❯ ./pants package src/docker/hw/Dockerfile [...] 18:07:29.66 [INFO] Completed: Building src.python.hw/bin.pex 18:07:31.83 [INFO] Completed: Building docker image helloworld:latest 18:07:31.83 [INFO] Built docker image: helloworld:latest
You can ask Pants to run a Docker image on your local system with the
❯ ./pants run src/docker/hw/Dockerfile Hello, Docker!
Pants can push your images to registries using
❯ ./pants publish src/docker/hw:helloworld # Will build the image and push it to all registries, with all tags.
See here for how to set up registries.
To configure the Docker binary, set
[docker].env_vars in your
pants.toml configuration file. You use that key to list environment variables such as
DOCKER_HOST, that will be set in the environment of the
docker binary when Pants runs it. Each listed value can be of the form
NAME=value, or just
NAME, in which case the value will be inherited from the Pants process's own environment.
[docker] env_vars = [ "DOCKER_CONTEXT=pants_context", "DOCKER_HOST" ]
Pants can run Hadolint on your Dockerfiles to check for errors and mistakes:
$ ./pants lint src/docker/hw/Dockerfile
This must first be enabled by activating the Hadolint backend:
[GLOBAL] backend_packages.add = ["pants.backend.experimental.docker.lint.hadolint"]
Updated 8 months ago