mirror of https://github.com/docker/docs.git
Merge pull request #17541 from dvdksn/build/simplify-build-contexts
build: rewrite contexts to better describe pipes/stdin
This commit is contained in:
commit
66f04bf68e
|
@ -9,25 +9,43 @@ The [`docker build`](../../engine/reference/commandline/build.md) or
|
||||||
commands build Docker images from a [Dockerfile](../../engine/reference/builder.md)
|
commands build Docker images from a [Dockerfile](../../engine/reference/builder.md)
|
||||||
and a "context".
|
and a "context".
|
||||||
|
|
||||||
A build's context is the set of files located at the `PATH` or `URL` specified
|
The build context is the argument that you pass to the build command:
|
||||||
as the positional argument to the build command:
|
|
||||||
|
|
||||||
```console
|
```console
|
||||||
$ docker build [OPTIONS] PATH | URL | -
|
$ docker build [OPTIONS] PATH | URL | -
|
||||||
^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^
|
||||||
```
|
```
|
||||||
|
|
||||||
The build process can refer to any of the files in the context. For example,
|
## What is a build context?
|
||||||
your build can use a [`COPY` instruction](../../engine/reference/builder.md#copy)
|
|
||||||
to reference a file in the context or a [`RUN --mount=type=bind` instruction](../../engine/reference/builder.md#run---mounttypebind)
|
|
||||||
for better performance with [BuildKit](../buildkit/index.md). The build context
|
|
||||||
is processed recursively. So, a `PATH` includes any subdirectories and the
|
|
||||||
`URL` includes the repository and its submodules.
|
|
||||||
|
|
||||||
## `PATH` context
|
You can pass any of the following inputs as the context for a build:
|
||||||
|
|
||||||
This example shows a build command that uses the current directory (`.`) as a
|
- The relative or absolute path to a local directory
|
||||||
build context:
|
- The address of a remote Git repository, tarball, or plain-text file
|
||||||
|
- A piped plain-text file or a tarball using standard input
|
||||||
|
|
||||||
|
### 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 can refer to any of the files and directories in the context.
|
||||||
|
For example, when you use a [`COPY` instruction](../../engine/reference/builder.md#copy),
|
||||||
|
the builder copies the file or directory from the build context, into the build container.
|
||||||
|
A filesystem build context is processed recursively:
|
||||||
|
|
||||||
|
- When you specify a local directory or a tarball, all subdirectories are included
|
||||||
|
- When you specify a remote Git repository, the repository and all submodules are included
|
||||||
|
|
||||||
|
### Text file contexts
|
||||||
|
|
||||||
|
When your build context is a plain-text file, the builder interprets the file
|
||||||
|
as a Dockerfile. With this approach, the builder doesn't receive a filesystem context.
|
||||||
|
For more information about building with a text file context, see [Text files](#text-files).
|
||||||
|
|
||||||
|
## Local directories and tarballs
|
||||||
|
|
||||||
|
The following example shows a build command that uses the current directory
|
||||||
|
(`.`) as a build context:
|
||||||
|
|
||||||
```console
|
```console
|
||||||
$ docker build .
|
$ docker build .
|
||||||
|
@ -38,39 +56,35 @@ $ docker build .
|
||||||
...
|
...
|
||||||
```
|
```
|
||||||
|
|
||||||
With the following Dockerfile:
|
This makes files and directories in the current working directory available
|
||||||
|
to the builder. The builder loads the files that it needs from the build context,
|
||||||
|
when it needs them.
|
||||||
|
|
||||||
```dockerfile
|
For example, given the following directory structure:
|
||||||
# syntax=docker/dockerfile:1
|
|
||||||
FROM busybox
|
|
||||||
WORKDIR /src
|
|
||||||
COPY foo .
|
|
||||||
```
|
|
||||||
|
|
||||||
And this directory structure:
|
|
||||||
|
|
||||||
```
|
```
|
||||||
.
|
.
|
||||||
|
├── index.ts
|
||||||
|
├── src/
|
||||||
├── Dockerfile
|
├── Dockerfile
|
||||||
├── bar
|
├── package.json
|
||||||
├── foo
|
└── package-lock.json
|
||||||
└── node_modules
|
|
||||||
```
|
```
|
||||||
|
|
||||||
The legacy builder sends the entire directory to the daemon, including `bar`
|
Dockerfile instructions can reference and include these files in the build
|
||||||
and `node_modules` directories, even though the `Dockerfile` does not use
|
if you pass the directory as a context.
|
||||||
them. When using [BuildKit](../buildkit/index.md), the client only sends the
|
|
||||||
files required by the `COPY` instructions, in this case `foo`.
|
|
||||||
|
|
||||||
In some cases you may want to send the entire context:
|
|
||||||
|
|
||||||
```dockerfile
|
```dockerfile
|
||||||
# syntax=docker/dockerfile:1
|
# syntax=docker/dockerfile:1
|
||||||
FROM busybox
|
FROM node:latest
|
||||||
WORKDIR /src
|
WORKDIR /src
|
||||||
COPY . .
|
COPY package.json package-lock.json .
|
||||||
|
RUN npm ci
|
||||||
|
COPY index.ts src .
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### `.dockerignore`
|
||||||
|
|
||||||
You can use a [`.dockerignore`](../../engine/reference/builder.md#dockerignore-file)
|
You can use a [`.dockerignore`](../../engine/reference/builder.md#dockerignore-file)
|
||||||
file to exclude some files or directories from being sent:
|
file to exclude some files or directories from being sent:
|
||||||
|
|
||||||
|
@ -80,24 +94,38 @@ node_modules
|
||||||
bar
|
bar
|
||||||
```
|
```
|
||||||
|
|
||||||
> **Warning**
|
A `.dockerignore` file located at the root of build context is automatically
|
||||||
>
|
detected and used.
|
||||||
> Avoid using your root directory, `/`, as the `PATH` for your build context,
|
|
||||||
> as it causes the build to transfer the entire contents of your hard drive to
|
|
||||||
> the daemon.
|
|
||||||
{:.warning}
|
|
||||||
|
|
||||||
## `URL` context
|
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.
|
||||||
|
|
||||||
The `URL` parameter can refer to three kinds of resources:
|
For example:
|
||||||
* [Git repositories](#git-repositories)
|
|
||||||
* Pre-packaged [tarball contexts](#tarball-contexts)
|
|
||||||
* Plain [text files](#text-files)
|
|
||||||
|
|
||||||
### Git repositories
|
```console
|
||||||
|
.
|
||||||
|
├── index.ts
|
||||||
|
├── src/
|
||||||
|
├── docker
|
||||||
|
│ ├── build.Dockerfile
|
||||||
|
│ ├── build.Dockerfile.dockerignore
|
||||||
|
│ ├── lint.Dockerfile
|
||||||
|
│ ├── lint.Dockerfile.dockerignore
|
||||||
|
│ ├── test.Dockerfile
|
||||||
|
│ └── test.Dockerfile.dockerignore
|
||||||
|
├── package.json
|
||||||
|
└── package-lock.json
|
||||||
|
```
|
||||||
|
|
||||||
When the `URL` parameter points to the location of a Git repository, the
|
A Dockerfile-specific ignore-file takes precedence over the `.dockerignore`
|
||||||
repository acts as the build context.
|
file at the root of the build context if both exist.
|
||||||
|
|
||||||
|
## 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 builder performs a shallow clone of the repository, downloading only
|
||||||
the HEAD commit, not the entire history.
|
the HEAD commit, not the entire history.
|
||||||
|
@ -111,7 +139,7 @@ $ docker build https://github.com/user/myrepo.git
|
||||||
By default, the builder clones the latest commit on the default branch of the
|
By default, the builder clones the latest commit on the default branch of the
|
||||||
repository that you specify.
|
repository that you specify.
|
||||||
|
|
||||||
#### URL fragments
|
### URL fragments
|
||||||
|
|
||||||
You can append URL fragments to the Git repository address to make the builder
|
You can append URL fragments to the Git repository address to make the builder
|
||||||
clone a specific branch, tag, and subdirectory of a repository.
|
clone a specific branch, tag, and subdirectory of a repository.
|
||||||
|
@ -142,7 +170,7 @@ contexts:
|
||||||
| `myrepo.git#mytag:myfolder` | `refs/tags/mytag` | `/myfolder` |
|
| `myrepo.git#mytag:myfolder` | `refs/tags/mytag` | `/myfolder` |
|
||||||
| `myrepo.git#mybranch:myfolder` | `refs/heads/mybranch` | `/myfolder` |
|
| `myrepo.git#mybranch:myfolder` | `refs/heads/mybranch` | `/myfolder` |
|
||||||
|
|
||||||
#### Keep `.git` directory
|
### Keep `.git` directory
|
||||||
|
|
||||||
By default, BuildKit doesn't keep the `.git` directory when using Git contexts.
|
By default, BuildKit doesn't keep the `.git` directory when using Git contexts.
|
||||||
You can configure BuildKit to keep the directory by setting the
|
You can configure BuildKit to keep the directory by setting the
|
||||||
|
@ -163,7 +191,7 @@ $ docker build \
|
||||||
https://github.com/user/myrepo.git#main
|
https://github.com/user/myrepo.git#main
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Private repositories
|
### Private repositories
|
||||||
|
|
||||||
When you specify a Git context that's also a private repository, the builder
|
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
|
needs you to provide the necessary authentication credentials. You can use
|
||||||
|
@ -193,9 +221,9 @@ $ GIT_AUTH_TOKEN=<token> docker buildx build \
|
||||||
> Don't use `--build-arg` for secrets, except for
|
> Don't use `--build-arg` for secrets, except for
|
||||||
> [HTTP proxies](../../network/proxy.md#set-proxy-using-the-cli)
|
> [HTTP proxies](../../network/proxy.md#set-proxy-using-the-cli)
|
||||||
|
|
||||||
### Tarball contexts
|
### Remote tarballs
|
||||||
|
|
||||||
If you pass a `URL` to a remote tarball, the `URL` itself is sent to the daemon:
|
If you pass the URL to a remote tarball, then the URL itself is sent to the builder.
|
||||||
|
|
||||||
```console
|
```console
|
||||||
$ docker build http://server/context.tar.gz
|
$ docker build http://server/context.tar.gz
|
||||||
|
@ -210,39 +238,132 @@ $ docker build http://server/context.tar.gz
|
||||||
The download operation will be performed on the host the daemon is running on,
|
The download operation will be performed on the host the daemon is running on,
|
||||||
which is not necessarily the same host from which the build command is being
|
which is not necessarily the same host from which the build command is being
|
||||||
issued. The daemon will fetch `context.tar.gz` and use it as the build context.
|
issued. The daemon will fetch `context.tar.gz` and use it as the build context.
|
||||||
Tarball contexts must be tar archives conforming to the standard `tar` UNIX
|
Tarball contexts must be tar archives conforming to the standard `tar` Unix
|
||||||
format and can be compressed with any one of the `xz`, `bzip2`, `gzip` or
|
format and can be compressed with any one of the `xz`, `bzip2`, `gzip` or
|
||||||
`identity` (no compression) formats.
|
`identity` (no compression) formats.
|
||||||
|
|
||||||
|
## Pipes
|
||||||
|
|
||||||
|
When you pass a single dash `-` as the argument to the build command, you can
|
||||||
|
pipe a plain-text file or a tarball as the context:
|
||||||
|
|
||||||
|
```console
|
||||||
|
$ docker build - PIPE
|
||||||
|
```
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
|
```console
|
||||||
|
$ docker build - < Dockerfile
|
||||||
|
$ docker build - < archive.tar
|
||||||
|
$ docker build - <<EOF
|
||||||
|
FROM node:alpine
|
||||||
|
COPY . .
|
||||||
|
RUN npm ci
|
||||||
|
EOF
|
||||||
|
```
|
||||||
|
|
||||||
|
### 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:
|
||||||
|
|
||||||
|
```
|
||||||
|
.
|
||||||
|
├── Dockerfile
|
||||||
|
├── Makefile
|
||||||
|
├── README.md
|
||||||
|
├── main.c
|
||||||
|
├── scripts
|
||||||
|
├── src
|
||||||
|
└── test.Dockerfile
|
||||||
|
```
|
||||||
|
|
||||||
|
You can create a tarball of the directory and pipe it to the build for use as
|
||||||
|
a context:
|
||||||
|
|
||||||
|
```console
|
||||||
|
$ tar czf foo.tar.gz *
|
||||||
|
$ docker build - < foo.tar.gz
|
||||||
|
```
|
||||||
|
|
||||||
|
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.Dockerfile`
|
||||||
|
in the tarball:
|
||||||
|
|
||||||
|
```console
|
||||||
|
$ docker build --file test.Dockerfile - < foo.tar.gz
|
||||||
|
```
|
||||||
|
|
||||||
### Text files
|
### Text files
|
||||||
|
|
||||||
Instead of specifying a context, you can pass a single `Dockerfile` in the
|
When you use a text file as the build context, the builder interprets the file
|
||||||
`URL` or pipe the file in via `STDIN`. To pipe a `Dockerfile` from `STDIN`:
|
as a Dockerfile. Using a text file as context means that the build has no
|
||||||
|
filesystem context. This can be useful when your build doesn't require any
|
||||||
|
local files. This means there's no filesystem context when building.
|
||||||
|
|
||||||
|
You can pass the text file using a standard input stream, or by pointing at the
|
||||||
|
URL of a remote text file.
|
||||||
|
|
||||||
```console
|
```console
|
||||||
$ docker build - < Dockerfile
|
$ docker build - < Dockerfile
|
||||||
```
|
```
|
||||||
|
|
||||||
With Powershell on Windows, you can run:
|
With PowerShell on Windows, you can run:
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
Get-Content Dockerfile | docker build -
|
Get-Content Dockerfile | docker build -
|
||||||
```
|
```
|
||||||
|
|
||||||
If you use `STDIN` or specify a `URL` pointing to a plain text file, the system
|
To use a remote text file, pass the URL of the text file as the argument to the
|
||||||
places the contents into a file called `Dockerfile`, and any `-f`, `--file`
|
build command:
|
||||||
option is ignored. In this scenario, there is no context.
|
|
||||||
|
```console
|
||||||
|
$ docker build https://raw.githubusercontent.com/dvdksn/clockbox/main/Dockerfile
|
||||||
|
```
|
||||||
|
|
||||||
|
Again, this means that the build has no filesystem context,
|
||||||
|
so Dockerfile commands such as `COPY` can't refer to local files:
|
||||||
|
|
||||||
|
```console
|
||||||
|
$ ls
|
||||||
|
main.c
|
||||||
|
$ docker build -<<< $'FROM scratch\nCOPY main.c .'
|
||||||
|
[+] Building 0.0s (4/4) FINISHED
|
||||||
|
=> [internal] load build definition from Dockerfile 0.0s
|
||||||
|
=> => transferring dockerfile: 64B 0.0s
|
||||||
|
=> [internal] load .dockerignore 0.0s
|
||||||
|
=> => transferring context: 2B 0.0s
|
||||||
|
=> [internal] load build context 0.0s
|
||||||
|
=> => transferring context: 2B 0.0s
|
||||||
|
=> ERROR [1/1] COPY main.c . 0.0s
|
||||||
|
------
|
||||||
|
> [1/1] COPY main.c .:
|
||||||
|
------
|
||||||
|
Dockerfile:2
|
||||||
|
--------------------
|
||||||
|
1 | FROM scratch
|
||||||
|
2 | >>> COPY main.c .
|
||||||
|
3 |
|
||||||
|
--------------------
|
||||||
|
ERROR: failed to solve: failed to compute cache key: failed to calculate checksum of ref 7ab2bb61-0c28-432e-abf5-a4c3440bc6b6::4lgfpdf54n5uqxnv9v6ymg7ih: "/main.c": not found
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Build using heredocs
|
||||||
|
|
||||||
The following example builds an image using a `Dockerfile` that is passed
|
The following example builds an image using a `Dockerfile` that is passed
|
||||||
through stdin. No files are sent as build context to the daemon.
|
through standard input using
|
||||||
|
[shell heredocs](https://en.wikipedia.org/wiki/Here_document){: target="_blank" rel="noopener"}:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker build -t myimage:latest -<<EOF
|
docker build -t myimage:latest - <<EOF
|
||||||
FROM busybox
|
FROM busybox
|
||||||
RUN echo "hello world"
|
RUN echo "hello world"
|
||||||
EOF
|
EOF
|
||||||
```
|
```
|
||||||
|
|
||||||
Omitting the build context can be useful in situations where your `Dockerfile`
|
This approach is useful when you want to quickly run a build command with a
|
||||||
does not require files to be copied into the image, and improves the build-speed,
|
Dockerfile that's short and concise.
|
||||||
as no files are sent to the daemon.
|
|
||||||
|
|
Loading…
Reference in New Issue