Build context (original) (raw)

The docker build and docker buildx build commands build Docker images from aDockerfile and a context.

What is a build context?

The build context is the set of files that your build can access. The positional argument that you pass to the build command specifies the context that you want to use for the build:

You can pass any of the following inputs as the context for a build:

Filesystem contexts

When your build context is a local directory, a remote Git repository, or a tar file, then that becomes the set of files that the builder can access during the build. Build instructions such as COPY and ADD can refer to any of the files and directories in the context.

A filesystem build context is processed recursively:

For more information about the different types of filesystem contexts that you can use with your builds, see:

Text file contexts

When your build context is a plain-text file, the builder interprets the file as a Dockerfile. With this approach, the build doesn't use a filesystem context.

For more information, seeempty build context.

Local context

To use a local build context, you can specify a relative or absolute filepath to the docker build command. The following example shows a build command that uses the current directory (.) as a build context:

This makes files and directories in the current working directory available to the builder. The builder loads the files it needs from the build context when needed.

You can also use local tarballs as build context, by piping the tarball contents to the docker build command. SeeTarballs.

Local directories

Consider the following directory structure:

Dockerfile instructions can reference and include these files in the build if you pass this directory as a context.

Local context with Dockerfile from stdin

Use the following syntax to build an image using files on your local filesystem, while using a Dockerfile from stdin.

The syntax uses the -f (or --file) option to specify the Dockerfile to use, and it uses a hyphen (-) as filename to instruct Docker to read the Dockerfile from stdin.

The following example uses the current directory (.) as the build context, and builds an image using a Dockerfile passed through stdin using a here-document.

Local tarballs

When you pipe a tarball to the build command, the build uses the contents of the tarball as a filesystem context.

For example, given the following project directory:

You can create a tarball of the directory and pipe it to the build for use as a context:

The build resolves the Dockerfile from the tarball context. You can use the--file flag to specify the name and location of the Dockerfile relative to the root of the tarball. The following command builds using test.Dockerfilein the tarball:

Remote context

You can specify the address of a remote Git repository, tarball, or plain-text file as your build context.

If the remote tarball is a text file, the builder receives nofilesystem context, and instead assumes that the remote file is a Dockerfile. SeeEmpty build context.

Git repositories

When you pass a URL pointing to the location of a Git repository as an argument to docker build, the builder uses the repository as the build context.

The builder performs a shallow clone of the repository, downloading only the HEAD commit, not the entire history.

The builder recursively clones the repository and any submodules it contains.

By default, the builder clones the latest commit on the default branch of the repository that you specify.

URL fragments

You can append URL fragments to the Git repository address to make the builder clone a specific branch, tag, and subdirectory of a repository.

The format of the URL fragment is #ref:dir, where:

For example, the following command uses the container branch, and the docker subdirectory in that branch, as the build context:

The following table represents all the valid suffixes with their build contexts:

Build Syntax Suffix Commit Used Build Context Used
myrepo.git refs/heads/ /
myrepo.git#mytag refs/tags/mytag /
myrepo.git#mybranch refs/heads/mybranch /
myrepo.git#pull/42/head refs/pull/42/head /
myrepo.git#:myfolder refs/heads/ /myfolder
myrepo.git#master:myfolder refs/heads/master /myfolder
myrepo.git#mytag:myfolder refs/tags/mytag /myfolder
myrepo.git#mybranch:myfolder refs/heads/mybranch /myfolder

When you use a commit hash as the ref in the URL fragment, use the full, 40-character string SHA-1 hash of the commit. A short hash, for example a hash truncated to 7 characters, is not supported.

Keep .git directory

By default, BuildKit doesn't keep the .git directory when using Git contexts. You can configure BuildKit to keep the directory by setting theBUILDKIT_CONTEXT_KEEP_GIT_DIR build argument. This can be useful to if you want to retrieve Git information during your build:

Private repositories

When you specify a Git context that's also a private repository, the builder needs you to provide the necessary authentication credentials. You can use either SSH or token-based authentication.

Buildx automatically detects and uses SSH credentials if the Git context you specify is an SSH or Git address. By default, this uses $SSH_AUTH_SOCK. You can configure the SSH credentials to use with the--ssh flag.

If you want to use token-based authentication instead, you can pass the token using the--secret flag.

Note

Don't use --build-arg for secrets.

Remote context with Dockerfile from stdin

Use the following syntax to build an image using files on your local filesystem, while using a Dockerfile from stdin.

The syntax uses the -f (or --file) option to specify the Dockerfile to use, and it uses a hyphen (-) as filename to instruct Docker to read the Dockerfile from stdin.

This can be useful in situations where you want to build an image from a repository that doesn't contain a Dockerfile. Or if you want to build with a custom Dockerfile, without maintaining your own fork of the repository.

The following example builds an image using a Dockerfile from stdin, and adds the hello.c file from thehello-worldrepository on GitHub.

Remote tarballs

If you pass the URL to a remote tarball, the URL itself is sent to the builder.

The download operation will be performed on the host where the BuildKit daemon is running. Note that if you're using a remote Docker context or a remote builder, that's not necessarily the same machine as where you issue the build command. BuildKit fetches the context.tar.gz and uses it as the build context. Tarball contexts must be tar archives conforming to the standard tarUnix format and can be compressed with any one of the xz, bzip2, gzip oridentity (no compression) formats.

Empty context

When you use a text file as the build context, the builder interprets the file as a Dockerfile. Using a text file as context means that the build has no filesystem context.

You can build with an empty build context when your Dockerfile doesn't depend on any local files.

How to build without a context

You can pass the text file using a standard input stream, or by pointing at the URL of a remote text file.

When you build without a filesystem context, Dockerfile instructions such asCOPY can't refer to local files:

You can use a .dockerignore file to exclude files or directories from the build context.

This helps avoid sending unwanted files and directories to the builder, improving build speed, especially when using a remote builder.

Filename and location

When you run a build command, the build client looks for a file named.dockerignore in the root directory of the context. If this file exists, the files and directories that match patterns in the files are removed from the build context before it's sent to the builder.

If you use multiple Dockerfiles, you can use different ignore-files for each Dockerfile. You do so using a special naming convention for the ignore-files. Place your ignore-file in the same directory as the Dockerfile, and prefix the ignore-file with the name of the Dockerfile, as shown in the following example.

A Dockerfile-specific ignore-file takes precedence over the .dockerignorefile at the root of the build context if both exist.

Syntax

The .dockerignore file is a newline-separated list of patterns similar to the file globs of Unix shells. Leading and trailing slashes in ignore patterns are disregarded. The following patterns all exclude a file or directory named barin the subdirectory foo under the root of the build context:

If a line in .dockerignore file starts with # in column 1, then this line is considered as a comment and is ignored before interpreted by the CLI.

If you're interested in learning the precise details of the .dockerignorepattern matching logic, check out themoby/patternmatcher repositoryon GitHub, which contains the source code.

Matching

The following code snippet shows an example .dockerignore file.

This file causes the following build behavior:

Rule Behavior
# comment Ignored.
*/temp* Exclude files and directories whose names start with temp in any immediate subdirectory of the root. For example, the plain file /somedir/temporary.txt is excluded, as is the directory /somedir/temp.
*/*/temp* Exclude files and directories starting with temp from any subdirectory that is two levels below the root. For example, /somedir/subdir/temporary.txt is excluded.
temp? Exclude files and directories in the root directory whose names are a one-character extension of temp. For example, /tempa and /tempb are excluded.

Matching is done using Go'sfilepath.Match function rules. A preprocessing step uses Go'sfilepath.Clean functionto trim whitespace and remove . and ... Lines that are blank after preprocessing are ignored.

Note

For historical reasons, the pattern . is ignored.

Beyond Go's filepath.Match rules, Docker also supports a special wildcard string ** that matches any number of directories (including zero). For example, **/*.go excludes all files that end with .go found anywhere in the build context.

You can use the .dockerignore file to exclude the Dockerfile and.dockerignore files. These files are still sent to the builder as they're needed for running the build. But you can't copy the files into the image usingADD, COPY, or bind mounts.

Negating matches

You can prepend lines with a ! (exclamation mark) to make exceptions to exclusions. The following is an example .dockerignore file that uses this mechanism:

All markdown files right under the context directory except README.md are excluded from the context. Note that markdown files under subdirectories are still included.

The placement of ! exception rules influences the behavior: the last line of the .dockerignore that matches a particular file determines whether it's included or excluded. Consider the following example:

No markdown files are included in the context except README files other thanREADME-secret.md.

Now consider this example:

All of the README files are included. The middle line has no effect because!README*.md matches README-secret.md and comes last.

Named contexts

In addition to the default build context (the positional argument to thedocker build command), you can also pass additional named contexts to builds.

Named contexts are specified using the --build-context flag, followed by a name-value pair. This lets you include files and directories from multiple sources during the build, while keeping them logically separated.

In this example:

Using named contexts in a Dockerfile

Dockerfile instructions can reference named contexts as if they are stages in a multi-stage build.

For example, the following Dockerfile:

  1. Uses a COPY instruction to copy files from the default context into the current build stage.
  2. Bind mounts the files in a named context to process the files as part of the build.

Use cases for named contexts

Using named contexts allows for greater flexibility and efficiency when building Docker images. Here are some scenarios where using named contexts can be useful:

Example: combine local and remote sources

You can define separate named contexts for different types of sources. For example, consider a project where the application source code is local, but the deployment scripts are stored in a Git repository:

In the Dockerfile, you can use these contexts independently:

Example: dynamic builds with custom dependencies

In some scenarios, you might need to dynamically inject configuration files or dependencies into the build from external sources. Named contexts make this straightforward by allowing you to mount different configurations without modifying the default build context.

Example Dockerfile:

Example: pin or override images

You can refer to named contexts in a Dockerfile the same way you can refer to an image. That means you can change an image reference in your Dockerfile by overriding it with a named context. For example, given the following Dockerfile:

If you want to force image reference to resolve to a different version, without changing the Dockerfile, you can pass a context with the same name to the build. For example:

The docker-image:// prefix marks the context as an image reference. The reference can be a local image or an image in your registry.

Named contexts with Bake

Bake is a tool built into docker build that lets you manage your build configuration with a configuration file. Bake fully supports named contexts.

To define named contexts in a Bake file:

This is equivalent to the following CLI invocation:

Linking targets with named contexts

In addition to making complex builds more manageable, Bake also provides additional features on top of what you can do with docker build on the CLI. You can use named contexts to create build pipelines, where one target depends on and builds on top of another. For example, consider a Docker build setup where you have two Dockerfiles:

The app.Dockerfile uses the image produced by base.Dockerfile as it's base image:

Normally, you would have to build the base image first, and then either load it to Docker Engine's local image store or push it to a registry. With Bake, you can reference other targets directly, creating a dependency between the apptarget and the base target.

With this configuration, references to mybaseimage in app.Dockerfile use the results from building the base target. Building the app target will also trigger a rebuild of mybaseimage, if necessary:

Further reading

For more information about working with named contexts, see: