Merge pull request #20489 from crazy-max/update-buildkit

vendor: github.com/moby/buildkit v0.15.1
This commit is contained in:
David Karlsson 2024-07-26 14:00:18 +02:00 committed by GitHub
commit 37339d49d5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 563 additions and 254 deletions

View File

@ -104,6 +104,8 @@ insecure-entitlements = [ "network.host", "security.insecure" ]
# maintain a pool of reusable CNI network namespaces to amortize the overhead
# of allocating and releasing the namespaces
cniPoolSize = 16
# defaultCgroupParent sets the parent cgroup of all containers.
defaultCgroupParent = "buildkit"
[worker.containerd.labels]
"foo" = "bar"

View File

@ -1058,7 +1058,7 @@ the `-p` flag. For example
$ docker run -p 80:80/tcp -p 80:80/udp ...
```
To set up port redirection on the host system, see [using the -P flag](https://docs.docker.com/engine/reference/run/#expose-incoming-ports).
To set up port redirection on the host system, see [using the -P flag](https://docs.docker.com/reference/cli/docker/container/run/#publish).
The `docker network` command supports creating networks for communication among
containers without the need to expose or publish specific ports, because the
containers connected to the network can communicate with each other over any
@ -1100,8 +1100,8 @@ from the resulting image. You can view the values using `docker inspect`, and
change them using `docker run --env <key>=<value>`.
A stage inherits any environment variables that were set using `ENV` by its
parent stage or any ancestor. Refer [here](https://docs.docker.com/build/building/multi-stage/)
for more on multi-staged builds.
parent stage or any ancestor. Refer to the [multi-stage builds section](https://docs.docker.com/build/building/multi-stage/)
in the manual for more information.
Environment variable persistence can cause unexpected side effects. For example,
setting `ENV DEBIAN_FRONTEND=noninteractive` changes the behavior of `apt-get`,
@ -1160,41 +1160,95 @@ The available `[OPTIONS]` are:
- [`--link`](#add---link)
- [`--exclude`](#add---exclude)
The `ADD` instruction copies new files, directories or remote file URLs from `<src>`
and adds them to the filesystem of the image at the path `<dest>`.
The `ADD` instruction copies new files or directories from `<src>` and adds
them to the filesystem of the image at the path `<dest>`. Files and directories
can be copied from the build context, a remote URL, or a Git repository.
Multiple `<src>` resources may be specified but if they are files or
directories, their paths are interpreted as relative to the source of
the context of the build.
The `ADD` and `COPY` instructions are functionally similar, but serve slightly different purposes.
Learn more about the [differences between `ADD` and `COPY`](https://docs.docker.com/build/building/best-practices/#add-or-copy).
Each `<src>` may contain wildcards and matching will be done using Go's
[filepath.Match](https://golang.org/pkg/path/filepath#Match) rules. For example:
### Source
To add all files in the root of the build context starting with "hom":
You can specify multiple source files or directories with `ADD`. The last
argument must always be the destination. For example, to add two files,
`file1.txt` and `file2.txt`, from the build context to `/usr/src/things/` in
the build container:
```dockerfile
ADD hom* /mydir/
ADD file1.txt file2.txt /usr/src/things/
```
In the following example, `?` is a single-character wildcard, matching e.g. "home.txt".
If you specify multiple source files, either directly or using a wildcard, then
the destination must be a directory (must end with a slash `/`).
To add files from a remote location, you can specify a URL or the address of a
Git repository as the source. For example:
```dockerfile
ADD hom?.txt /mydir/
ADD https://example.com/archive.zip /usr/src/things/
ADD git@github.com:user/repo.git /usr/src/things/
```
The `<dest>` is an absolute path, or a path relative to `WORKDIR`, into which
the source will be copied inside the destination container.
BuildKit detects the type of `<src>` and processes it accordingly.
The example below uses a relative path, and adds "test.txt" to `<WORKDIR>/relativeDir/`:
- If `<src>` is a local file or directory, the contents of the directory are
copied to the specified destination. See [Adding files from the build context](#adding-files-from-the-build-context).
- If `<src>` is a local tar archive, it is decompressed and extracted to the
specified destination. See [Adding local tar archives](#adding-local-tar-archives).
- If `<src>` is a URL, the contents of the URL are downloaded and placed at
the specified destination. See [Adding files from a URL](#adding-files-from-a-url).
- If `<src>` is a Git repository, the repository is cloned to the specified
destination. See [Adding files from a Git repository](#adding-files-from-a-git-repository).
#### Adding files from the build context
Any relative or local path that doesn't begin with a `http://`, `https://`, or
`git@` protocol prefix is considered a local file path. The local file path is
relative to the build context. For example, if the build context is the current
directory, `ADD file.txt /` adds the file at `./file.txt` to the root of the
filesystem in the build container.
When adding source files from the build context, their paths are interpreted as
relative to the root of the context. If you specify a relative path leading
outside of the build context, such as `ADD ../something /something`, parent
directory paths are stripped out automatically. The effective source path in
this example becomes `ADD something /something`.
If the source is a directory, the contents of the directory are copied,
including filesystem metadata. The directory itself isn't copied, only its
contents. If it contains subdirectories, these are also copied, and merged with
any existing directories at the destination. Any conflicts are resolved in
favor of the content being added, on a file-by-file basis, except if you're
trying to copy a directory onto an existing file, in which case an error is
raised.
If the source is a file, the file and its metadata are copied to the
destination. File permissions are preserved. If the source is a file and a
directory with the same name exists at the destination, an error is raised.
If you pass a Dockerfile through stdin to the build (`docker build - <
Dockerfile`), there is no build context. In this case, you can only use the
`ADD` instruction to copy remote files. You can also pass a tar archive through
stdin: (`docker build - < archive.tar`), the Dockerfile at the root of the
archive and the rest of the archive will be used as the context of the build.
##### Pattern matching
For local files, each `<src>` may contain wildcards and matching will be done
using Go's [filepath.Match](https://golang.org/pkg/path/filepath#Match) rules.
For example, to add all files and directories in the root of the build context
ending with `.png`:
```dockerfile
ADD test.txt relativeDir/
ADD *.png /dest/
```
Whereas this example uses an absolute path, and adds "test.txt" to `/absoluteDir/`
In the following example, `?` is a single-character wildcard, matching e.g.
`index.js` and `index.ts`.
```dockerfile
ADD test.txt /absoluteDir/
ADD index.?s /dest/
```
When adding files or directories that contain special characters (such as `[`
@ -1203,95 +1257,83 @@ them from being treated as a matching pattern. For example, to add a file
named `arr[0].txt`, use the following;
```dockerfile
ADD arr[[]0].txt /mydir/
ADD arr[[]0].txt /dest/
```
In the case where `<src>` is a remote file URL, the destination will
have permissions of 600. If the remote file being retrieved has an HTTP
`Last-Modified` header, the timestamp from that header will be used
to set the `mtime` on the destination file. However, like any other file
processed during an `ADD`, `mtime` isn't included in the determination
of whether or not the file has changed and the cache should be updated.
#### Adding local tar archives
When using a local tar archive as the source for `ADD`, and the archive is in a
recognized compression format (`gzip`, `bzip2` or `xz`, or uncompressed), the
archive is decompressed and extracted into the specified destination. Only
local tar archives are extracted. If the tar archive is a remote URL, the
archive is not extracted, but downloaded and placed at the destination.
When a directory is extracted, it has the same behavior as `tar -x`.
The result is the union of:
1. Whatever existed at the destination path, and
2. The contents of the source tree, with conflicts resolved in favor of the
content being added, on a file-by-file basis.
> **Note**
>
> If you build by passing a Dockerfile through STDIN (`docker
build - < somefile`), there is no build context, so the Dockerfile
> can only contain a URL based `ADD` instruction. You can also pass a
> compressed archive through STDIN: (`docker build - < archive.tar.gz`),
> the Dockerfile at the root of the archive and the rest of the
> archive will be used as the context of the build.
> Whether a file is identified as a recognized compression format or not is
> done solely based on the contents of the file, not the name of the file. For
> example, if an empty file happens to end with `.tar.gz` this isn't recognized
> as a compressed file and doesn't generate any kind of decompression error
> message, rather the file will simply be copied to the destination.
#### Adding files from a URL
In the case where source is a remote file URL, the destination will have
permissions of 600. If the HTTP response contains a `Last-Modified` header, the
timestamp from that header will be used to set the `mtime` on the destination
file. However, like any other file processed during an `ADD`, `mtime` isn't
included in the determination of whether or not the file has changed and the
cache should be updated.
If the destination ends with a trailing slash, then the filename is inferred
from the URL path. For example, `ADD http://example.com/foobar /` would create
the file `/foobar`. The URL must have a nontrivial path so that an appropriate
filename can be discovered (`http://example.com` doesn't work).
If the destination doesn't end with a trailing slash, the destination path
becomes the filename of the file downloaded from the URL. For example, `ADD
http://example.com/foo /bar` creates the file `/bar`.
If your URL files are protected using authentication, you need to use `RUN wget`,
`RUN curl` or use another tool from within the container as the `ADD` instruction
doesn't support authentication.
> **Note**
>
> The first encountered `ADD` instruction will invalidate the cache for all
> following instructions from the Dockerfile if the contents of `<src>` have
> changed. This includes invalidating the cache for `RUN` instructions.
> See the [Dockerfile Best Practices
> guide Leverage build cache](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#leverage-build-cache)
> for more information.
#### Adding files from a Git repository
`ADD` obeys the following rules:
To use a Git repository as the source for `ADD`, you can reference the
repository's HTTP or SSH address as the source. The repository is cloned to the
specified destination in the image.
- The `<src>` path must be inside the build context;
you can't use `ADD ../something /something`, because the builder can only
access files from the context, and `../something` specifies a parent file or
directory of the build context root.
```dockerfile
ADD https://github.com/user/repo.git /mydir/
```
- If `<src>` is a URL and `<dest>` does end with a trailing slash, then the
filename is inferred from the URL and the file is downloaded to
`<dest>/<filename>`. For instance, `ADD http://example.com/foobar /` would
create the file `/foobar`. The URL must have a nontrivial path so that an
appropriate filename can be discovered in this case (`http://example.com`
doesn't work).
You can use URL fragments to specify a specific branch, tag, commit, or
subdirectory. For example, to add the `docs` directory of the `v0.14.1` tag of
the `buildkit` repository:
- If `<src>` is a directory, the entire contents of the directory are copied,
including filesystem metadata.
```dockerfile
ADD git@github.com:moby/buildkit.git#v0.14.1:docs /buildkit-docs
```
> **Note**
>
> The directory itself isn't copied, only its contents.
For more information about Git URL fragments,
see [URL fragments](https://docs.docker.com/build/building/context/#url-fragments).
- If `<src>` is a local `tar` archive in a recognized compression format
(`identity`, `gzip`, `bzip2` or `xz`) then it's unpacked as a directory. Resources
from remote URLs aren't decompressed. When a directory is copied or
unpacked, it has the same behavior as `tar -x`. The result is the union of:
When adding from a Git repository, the permissions bits for files
are 644. If a file in the repository has the executable bit set, it will have
permissions set to 755. Directories have permissions set to 755.
1. Whatever existed at the destination path and
2. The contents of the source tree, with conflicts resolved in favor
of "2." on a file-by-file basis.
> **Note**
>
> Whether a file is identified as a recognized compression format or not
> is done solely based on the contents of the file, not the name of the file.
> For example, if an empty file happens to end with `.tar.gz` this isn't
> recognized as a compressed file and doesn't generate any kind of
> decompression error message, rather the file will simply be copied to the
> destination.
- If `<src>` is any other kind of file, it's copied individually along with
its metadata. In this case, if `<dest>` ends with a trailing slash `/`, it
will be considered a directory and the contents of `<src>` will be written
at `<dest>/base(<src>)`.
- If multiple `<src>` resources are specified, either directly or due to the
use of a wildcard, then `<dest>` must be a directory, and it must end with
a slash `/`.
- If `<src>` is a file, and `<dest>` doesn't end with a trailing slash,
the contents of `<src>` will be written as filename `<dest>`.
- If `<dest>` doesn't exist, it's created, along with all missing directories
in its path.
### Adding private Git repositories
To add a private repository via SSH, create a Dockerfile with the following form:
When using a Git repository as the source, the repository must be accessible
from the build context. To add a repository via SSH, whether public or private,
you must pass an SSH key for authentication. For example, given the following
Dockerfile:
```dockerfile
# syntax=docker/dockerfile:1
@ -1299,16 +1341,45 @@ FROM alpine
ADD git@git.example.com:foo/bar.git /bar
```
This Dockerfile can be built with `docker build --ssh` or `buildctl build --ssh`, e.g.,
To build this Dockerfile, pass the `--ssh` flag to the `docker build` to mount
the SSH agent socket to the build. For example:
```console
$ docker build --ssh default
$ docker build --ssh default .
```
```console
$ buildctl build --frontend=dockerfile.v0 --local context=. --local dockerfile=. --ssh default
For more information about building with secrets,
see [Build secrets](https://docs.docker.com/build/building/secrets/).
### Destination
If the destination path begins with a forward slash, it's interpreted as an
absolute path, and the source files are copied into the specified destination
relative to the root of the current build stage.
```dockerfile
# create /abs/test.txt
ADD test.txt /abs/
```
Trailing slashes are significant. For example, `ADD test.txt /abs` creates a
file at `/abs`, whereas `ADD test.txt /abs/` creates `/abs/test.txt`.
If the destination path doesn't begin with a leading slash, it's interpreted as
relative to the working directory of the build container.
```dockerfile
WORKDIR /usr/src/app
# create /usr/src/app/rel/test.txt
ADD test.txt rel/
```
If destination doesn't exist, it's created, along with all missing directories
in its path.
If the source is a file, and the destination doesn't end with a trailing slash,
the source file will be written to the destination path as a file.
### ADD --keep-git-dir
```dockerfile
@ -1339,7 +1410,7 @@ The `--checksum` flag lets you verify the checksum of a remote resource:
ADD --checksum=sha256:24454f830cdb571e2c4ad15481119c43b3cafd48dd869a9b2945d1036d1dc68d https://mirrors.edge.kernel.org/pub/linux/kernel/Historic/linux-0.01.tar.gz /
```
The `--checksum` flag only supports HTTP sources currently.
The `--checksum` flag only supports HTTP(S) sources.
### ADD --chown --chmod
@ -1372,100 +1443,130 @@ The available `[OPTIONS]` are:
- [`--parents`](#copy---parents)
- [`--exclude`](#copy---exclude)
The `COPY` instruction copies new files or directories from `<src>`
and adds them to the filesystem of the container at the path `<dest>`.
The `COPY` instruction copies new files or directories from `<src>` and adds
them to the filesystem of the image at the path `<dest>`. Files and directories
can be copied from the build context, build stage, named context, or an image.
Multiple `<src>` resources may be specified but the paths of files and
directories will be interpreted as relative to the source of the context
of the build.
The `ADD` and `COPY` instructions are functionally similar, but serve slightly different purposes.
Learn more about the [differences between `ADD` and `COPY`](https://docs.docker.com/build/building/best-practices/#add-or-copy).
Each `<src>` may contain wildcards and matching will be done using Go's
[filepath.Match](https://golang.org/pkg/path/filepath#Match) rules. For example:
### Source
To add all files in the root of the build context starting with "hom":
You can specify multiple source files or directories with `COPY`. The last
argument must always be the destination. For example, to copy two files,
`file1.txt` and `file2.txt`, from the build context to `/usr/src/things/` in
the build container:
```dockerfile
COPY hom* /mydir/
COPY file1.txt file2.txt /usr/src/things/
```
In the following example, `?` is a single-character wildcard, matching e.g. "home.txt".
If you specify multiple source files, either directly or using a wildcard, then
the destination must be a directory (must end with a slash `/`).
`COPY` accepts a flag `--from=<name>` that lets you specify the source location
to be a build stage, context, or image. The following example copies files from
a stage named `build`:
```dockerfile
COPY hom?.txt /mydir/
FROM golang AS build
WORKDIR /app
RUN --mount=type=bind,target=. go build -o /myapp ./cmd
COPY --from=build /myapp /usr/bin/
```
The `<dest>` is an absolute path, or a path relative to `WORKDIR`, into which
the source will be copied inside the destination container.
For more information about copying from named sources, see the
[`--from` flag](#copy---from).
The example below uses a relative path, and adds "test.txt" to `<WORKDIR>/relativeDir/`:
#### Copying from the build context
When copying source files from the build context, their paths are interpreted as
relative to the root of the context. If you specify a relative path leading
outside of the build context, such as `COPY ../something /something`, parent
directory paths are stripped out automatically. The effective source path in
this example becomes `COPY something /something`.
If the source is a directory, the contents of the directory are copied,
including filesystem metadata. The directory itself isn't copied, only its
contents. If it contains subdirectories, these are also copied, and merged with
any existing directories at the destination. Any conflicts are resolved in
favor of the content being added, on a file-by-file basis, except if you're
trying to copy a directory onto an existing file, in which case an error is
raised.
If the source is a file, the file and its metadata are copied to the
destination. File permissions are preserved. If the source is a file and a
directory with the same name exists at the destination, an error is raised.
If you pass a Dockerfile through stdin to the build (`docker build - <
Dockerfile`), there is no build context. In this case, you can only use the
`COPY` instruction to copy files from other stages, named contexts, or images,
using the [`--from` flag](#copy---from). You can also pass a tar archive
through stdin: (`docker build - < archive.tar`), the Dockerfile at the root of
the archive and the rest of the archive will be used as the context of the
build.
When using a Git repository as the build context, the permissions bits for
copied files are 644. If a file in the repository has the executable bit set,
it will have permissions set to 755. Directories have permissions set to 755.
##### Pattern matching
For local files, each `<src>` may contain wildcards and matching will be done
using Go's [filepath.Match](https://golang.org/pkg/path/filepath#Match) rules.
For example, to add all files and directories in the root of the build context
ending with `.png`:
```dockerfile
COPY test.txt relativeDir/
COPY *.png /dest/
```
Whereas this example uses an absolute path, and adds "test.txt" to `/absoluteDir/`
In the following example, `?` is a single-character wildcard, matching e.g.
`index.js` and `index.ts`.
```dockerfile
COPY test.txt /absoluteDir/
COPY index.?s /dest/
```
When copying files or directories that contain special characters (such as `[`
When adding files or directories that contain special characters (such as `[`
and `]`), you need to escape those paths following the Golang rules to prevent
them from being treated as a matching pattern. For example, to copy a file
them from being treated as a matching pattern. For example, to add a file
named `arr[0].txt`, use the following;
```dockerfile
COPY arr[[]0].txt /mydir/
COPY arr[[]0].txt /dest/
```
> **Note**
>
> If you build using STDIN (`docker build - < somefile`), there is no
> build context, so `COPY` can't be used.
### Destination
Optionally `COPY` accepts a flag `--from=<name>` that can be used to set
the source location to a previous build stage (created with `FROM .. AS <name>`)
that will be used instead of a build context sent by the user. In case a build
stage with a specified name can't be found an image with the same name is
attempted to be used instead.
If the destination path begins with a forward slash, it's interpreted as an
absolute path, and the source files are copied into the specified destination
relative to the root of the current build stage.
`COPY` obeys the following rules:
```dockerfile
# create /abs/test.txt
ADD test.txt /abs/
```
- The `<src>` path is resolved relative to the build context.
If you specify a relative path leading outside of the build context, such as
`COPY ../something /something`, parent directory paths are stripped out automatically.
The effective source path in this example becomes `COPY something /something`
Trailing slashes are significant. For example, `ADD test.txt /abs` creates a
file at `/abs`, whereas `ADD test.txt /abs/` creates `/abs/test.txt`.
- If `<src>` is a directory, the entire contents of the directory are copied,
including filesystem metadata.
If the destination path doesn't begin with a leading slash, it's interpreted as
relative to the working directory of the build container.
> **Note**
>
> The directory itself isn't copied, only its contents.
```dockerfile
WORKDIR /usr/src/app
# create /usr/src/app/rel/test.txt
ADD test.txt rel/
```
- If `<src>` is any other kind of file, it's copied individually along with
its metadata. In this case, if `<dest>` ends with a trailing slash `/`, it
will be considered a directory and the contents of `<src>` will be written
at `<dest>/base(<src>)`.
If destination doesn't exist, it's created, along with all missing directories
in its path.
- If multiple `<src>` resources are specified, either directly or due to the
use of a wildcard, then `<dest>` must be a directory, and it must end with
a slash `/`.
- If `<src>` is a file, and `<dest>` doesn't end with a trailing slash,
the contents of `<src>` will be written as filename `<dest>`.
- If `<dest>` doesn't exist, it's created, along with all missing directories
in its path.
> **Note**
>
> The first encountered `COPY` instruction will invalidate the cache for all
> following instructions from the Dockerfile if the contents of `<src>` have
> changed. This includes invalidating the cache for `RUN` instructions.
> See the [Dockerfile Best Practices
> guide Leverage build cache](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#leverage-build-cache)
> for more information.
If the source is a file, and the destination doesn't end with a trailing slash,
the source file will be written to the destination path as a file.
### COPY --from
@ -1493,8 +1594,9 @@ FROM scratch
COPY --from=build /hello /
```
You can also copy files directly from other images. The following example
copies an `nginx.conf` file from the official Nginx image.
You can also copy files directly from named contexts (specified with
`--build-context <name>=<source>`) or images. The following example copies an
`nginx.conf` file from the official Nginx image.
```dockerfile
COPY --from=nginx:latest /etc/nginx/nginx.conf /nginx.conf

View File

@ -42,10 +42,6 @@ $ docker build --check .
</tr>
<tr>
<td><a href="./consistent-instruction-casing/">ConsistentInstructionCasing</a></td>
<td>Instructions should be in consistent casing (all lower or all upper)</td>
</tr>
<tr>
<td><a href="./file-consistent-command-casing/">FileConsistentCommandCasing</a></td>
<td>All commands within the Dockerfile should use the same casing (either upper or lower)</td>
</tr>
<tr>
@ -84,5 +80,25 @@ $ docker build --check .
<td><a href="./legacy-key-value-format/">LegacyKeyValueFormat</a></td>
<td>Legacy key/value format with whitespace separator should not be used</td>
</tr>
<tr>
<td><a href="./redundant-target-platform/">RedundantTargetPlatform</a></td>
<td>Setting platform to predefined $TARGETPLATFORM in FROM is redundant as this is the default behavior</td>
</tr>
<tr>
<td><a href="./secrets-used-in-arg-or-env/">SecretsUsedInArgOrEnv</a></td>
<td>Sensitive data should not be used in the ARG or ENV commands</td>
</tr>
<tr>
<td><a href="./invalid-default-arg-in-from/">InvalidDefaultArgInFrom</a></td>
<td>Default value for global ARG results in an empty or invalid base image name</td>
</tr>
<tr>
<td><a href="./from-platform-flag-const-disallowed/">FromPlatformFlagConstDisallowed</a></td>
<td>FROM --platform flag should not use a constant value</td>
</tr>
<tr>
<td><a href="./copy-ignored-file/">CopyIgnoredFile</a></td>
<td>Attempting to Copy file that is excluded by .dockerignore</td>
</tr>
</tbody>
</table>

View File

@ -1,6 +1,6 @@
---
title: ConsistentInstructionCasing
description: Instructions should be in consistent casing (all lower or all upper)
description: All commands within the Dockerfile should use the same casing (either upper or lower)
aliases:
- /go/dockerfile/rule/consistent-instruction-casing/
---

View File

@ -0,0 +1,45 @@
---
title: CopyIgnoredFile
description: Attempting to Copy file that is excluded by .dockerignore
aliases:
- /go/dockerfile/rule/copy-ignored-file/
---
## Output
```text
Attempting to Copy file "./tmp/Dockerfile" that is excluded by .dockerignore
```
## Description
When you use the Add or Copy instructions from within a Dockerfile, you should
ensure that the files to be copied into the image do not match a pattern
present in `.dockerignore`.
Files which match the patterns in a `.dockerignore` file are not present in the
context of the image when it is built. Trying to copy or add a file which is
missing from the context will result in a build error.
## Examples
With the given `.dockerignore` file:
```text
*/tmp/*
```
❌ Bad: Attempting to Copy file "./tmp/Dockerfile" that is excluded by .dockerignore
```dockerfile
FROM scratch
COPY ./tmp/helloworld.txt /helloworld.txt
```
✅ Good: Copying a file which is not excluded by .dockerignore
```dockerfile
FROM scratch
COPY ./forever/helloworld.txt /helloworld.txt
```

View File

@ -1,61 +0,0 @@
---
title: FileConsistentCommandCasing
description: All commands within the Dockerfile should use the same casing (either upper or lower)
aliases:
- /go/dockerfile/rule/file-consistent-command-casing/
---
## Output
Example warning:
```text
Command 'foo' should match the case of the command majority (uppercase)
```
## Description
Instructions within a Dockerfile should have consistent casing through out the
entire files. Instructions are not case-sensitive, but the convention is to use
uppercase for instruction keywords to make it easier to distinguish keywords
from arguments.
Whether you prefer instructions to be uppercase or lowercase, you should make
sure you use consistent casing to help improve readability of the Dockerfile.
## Examples
❌ Bad: mixed uppercase and lowercase.
```dockerfile
FROM alpine:latest AS builder
run apk --no-cache add build-base
FROM builder AS build1
copy source1.cpp source.cpp
```
✅ Good: all uppercase.
```dockerfile
FROM alpine:latest AS builder
RUN apk --no-cache add build-base
FROM builder AS build1
COPY source1.cpp source.cpp
```
✅ Good: all lowercase.
```dockerfile
from alpine:latest as builder
run apk --no-cache add build-base
from builder as build1
copy source1.cpp source.cpp
```
## Related errors
- [`FromAsCasing`](./from-as-casing.md)

View File

@ -40,5 +40,5 @@ from debian:latest as deb-builder
## Related errors
- [`FileConsistenCommandCasing`](./file-consistent-command-casing.md)
- [`FileConsistentCommandCasing`](./consistent-instruction-casing.md)

View File

@ -0,0 +1,59 @@
---
title: FromPlatformFlagConstDisallowed
description: FROM --platform flag should not use a constant value
aliases:
- /go/dockerfile/rule/from-platform-flag-const-disallowed/
---
## Output
```text
FROM --platform flag should not use constant value "linux/amd64"
```
## Description
Specifying `--platform` in the Dockerfile `FROM` instruction forces the image to build on only one target platform. This prevents building a multi-platform image from this Dockerfile and you must build on the same platform as specified in `--platform`.
The recommended approach is to:
* Omit `FROM --platform` in the Dockerfile and use the `--platform` argument on the command line.
* Use `$BUILDPLATFORM` or some other combination of variables for the `--platform` argument.
* Stage name should include the platform, OS, or architecture name to indicate that it only contains platform-specific instructions.
## Examples
❌ Bad: using a constant argument for `--platform`
```dockerfile
FROM --platform=linux/amd64 alpine AS base
RUN apk add --no-cache git
```
✅ Good: using the default platform
```dockerfile
FROM alpine AS base
RUN apk add --no-cache git
```
✅ Good: using a meta variable
```dockerfile
FROM --platform=${BUILDPLATFORM} alpine AS base
RUN apk add --no-cache git
```
✅ Good: used in a multi-stage build with a target architecture
```dockerfile
FROM --platform=linux/amd64 alpine AS build_amd64
...
FROM --platform=linux/arm64 alpine AS build_arm64
...
FROM build_${TARGETARCH} AS build
...
```

View File

@ -0,0 +1,47 @@
---
title: InvalidDefaultArgInFrom
description: Default value for global ARG results in an empty or invalid base image name
aliases:
- /go/dockerfile/rule/invalid-default-arg-in-from/
---
## Output
```text
Using the global ARGs with default values should produce a valid build.
```
## Description
An `ARG` used in an image reference should be valid when no build arguments are used. An image build should not require `--build-arg` to be used to produce a valid build.
## Examples
❌ Bad: don't rely on an ARG being set for an image reference to be valid
```dockerfile
ARG TAG
FROM busybox:${TAG}
```
✅ Good: include a default for the ARG
```dockerfile
ARG TAG=latest
FROM busybox:${TAG}
```
✅ Good: ARG can be empty if the image would be valid with it empty
```dockerfile
ARG VARIANT
FROM busybox:stable${VARIANT}
```
✅ Good: Use a default value if the build arg is not present
```dockerfile
ARG TAG
FROM alpine:${TAG:-3.14}
```

View File

@ -36,3 +36,21 @@ FROM alpine
ARG foo=bar
```
❌ Bad: multi-line variable declaration with a space separator.
```dockerfile
ENV DEPS \
curl \
git \
make
```
✅ Good: use an equals sign and wrap the value in quotes.
```dockerfile
ENV DEPS="\
curl \
git \
make"
```

View File

@ -23,16 +23,16 @@ Dockerfile, only the last occurrence is used. An image can only ever have one
```dockerfile
FROM alpine
CMD echo "Hello, Norway!"
CMD echo "Hello, Sweden!"
ENTRYPOINT ["echo", "Hello, Norway!"]
ENTRYPOINT ["echo", "Hello, Sweden!"]
# Only "Hello, Sweden!" will be printed
```
✅ Good: only one `CMD` instruction.
✅ Good: only one `ENTRYPOINT` instruction.
```dockerfile
FROM alpine
CMD echo "Hello, Norway!"; echo "Hello, Sweden!"
ENTRYPOINT ["echo", "Hello, Norway!\nHello, Sweden!"]
```
You can have both a regular, top-level `CMD`
@ -44,7 +44,7 @@ and a separate `CMD` for a `HEALTHCHECK` instruction.
FROM python:alpine
RUN apk add curl
HEALTHCHECK --interval=1s --timeout=3s \
CMD curl -f http://localhost:8080 || exit 1
CMD python -m http.server 8080
CMD ["curl", "-f", "http://localhost:8080"]
CMD ["python", "-m", "http.server", "8080"]
```

View File

@ -0,0 +1,35 @@
---
title: RedundantTargetPlatform
description: Setting platform to predefined $TARGETPLATFORM in FROM is redundant as this is the default behavior
aliases:
- /go/dockerfile/rule/redundant-target-platform/
---
## Output
```text
Setting platform to predefined $TARGETPLATFORM in FROM is redundant as this is the default behavior
```
## Description
A custom platform can be used for a base image. The default platform is the
same platform as the target output so setting the platform to `$TARGETPLATFORM`
is redundant and unnecessary.
## Examples
❌ Bad: this usage of `--platform` is redundant since `$TARGETPLATFORM` is the default.
```dockerfile
FROM --platform=$TARGETPLATFORM alpine AS builder
RUN apk add --no-cache git
```
✅ Good: omit the `--platform` argument.
```dockerfile
FROM alpine AS builder
RUN apk add --no-cache git
```

View File

@ -0,0 +1,36 @@
---
title: SecretsUsedInArgOrEnv
description: Sensitive data should not be used in the ARG or ENV commands
aliases:
- /go/dockerfile/rule/secrets-used-in-arg-or-env/
---
## Output
```text
Potentially sensitive data should not be used in the ARG or ENV commands
```
## Description
While it is common to pass secrets to running processes
through environment variables during local development,
setting secrets in a Dockerfile using `ENV` or `ARG`
is insecure because they persist in the final image.
This rule reports violations where `ENV` and `ARG` keys
indicate that they contain sensitive data.
Instead of `ARG` or `ENV`, you should use secret mounts,
which expose secrets to your builds in a secure manner,
and do not persist in the final image or its metadata.
See [Build secrets](https://docs.docker.com/build/building/secrets/).
## Examples
❌ Bad: `AWS_SECRET_ACCESS_KEY` is a secret value.
```dockerfile
FROM scratch
ARG AWS_SECRET_ACCESS_KEY
```

View File

@ -862,34 +862,42 @@ Reference:
section:
- path: /reference/build-checks/
title: Overview
- path: /reference/build-checks/stage-name-casing/
title: StageNameCasing
- path: /reference/build-checks/from-as-casing/
title: FromAsCasing
- path: /reference/build-checks/no-empty-continuation/
title: NoEmptyContinuation
- path: /reference/build-checks/consistent-instruction-casing/
title: ConsistentInstructionCasing
- path: /reference/build-checks/file-consistent-command-casing/
title: FileConsistentCommandCasing
- path: /reference/build-checks/copy-ignored-file/
title: CopyIgnoredFile
- path: /reference/build-checks/duplicate-stage-name/
title: DuplicateStageName
- path: /reference/build-checks/reserved-stage-name/
title: ReservedStageName
- path: /reference/build-checks/from-as-casing/
title: FromAsCasing
- path: /reference/build-checks/from-platform-flag-const-disallowed/
title: FromPlatformConstDisallowed
- path: /reference/build-checks/invalid-default-arg-in-from/
title: InvalidDefaultArgInFrom
- path: /reference/build-checks/json-args-recommended/
title: JSONArgsRecommended
- path: /reference/build-checks/maintainer-deprecated/
title: MaintainerDeprecated
- path: /reference/build-checks/undefined-arg-in-from/
title: UndefinedArgInFrom
- path: /reference/build-checks/workdir-relative-path/
title: WorkdirRelativePath
- path: /reference/build-checks/undefined-var/
title: UndefinedVar
- path: /reference/build-checks/multiple-instructions-disallowed/
title: MultipleInstructionsDisallowed
- path: /reference/build-checks/legacy-key-value-format/
title: LegacyKeyValueFormat
- path: /reference/build-checks/maintainer-deprecated/
title: MaintainerDeprecated
- path: /reference/build-checks/multiple-instructions-disallowed/
title: MultipleInstructionsDisallowed
- path: /reference/build-checks/no-empty-continuation/
title: NoEmptyContinuation
- path: /reference/build-checks/redundant-target-platform/
title: RedundantTargetPlatform
- path: /reference/build-checks/reserved-stage-name/
title: ReservedStageName
- path: /reference/build-checks/secrets-used-in-arg-or-env/
title: SecretsUsedInArgOrEnv
- path: /reference/build-checks/stage-name-casing/
title: StageNameCasing
- path: /reference/build-checks/undefined-arg-in-from/
title: UndefinedArgInFrom
- path: /reference/build-checks/undefined-var/
title: UndefinedVar
- path: /reference/build-checks/workdir-relative-path/
title: WorkdirRelativePath
- title: Daemon CLI (dockerd)
path: /reference/cli/dockerd/
- sectiontitle: API reference

2
go.mod
View File

@ -18,6 +18,6 @@ replace (
github.com/docker/cli => github.com/docker/cli v27.0.3+incompatible
github.com/docker/compose/v2 => github.com/docker/compose/v2 v2.29.0
github.com/docker/scout-cli => github.com/docker/scout-cli v1.11.0
github.com/moby/buildkit => github.com/moby/buildkit v0.14.0-rc2.0.20240611065153-eed17a45c62b
github.com/moby/buildkit => github.com/moby/buildkit v0.15.1
github.com/moby/moby => github.com/moby/moby v27.0.3+incompatible
)

2
go.sum
View File

@ -272,6 +272,8 @@ github.com/moby/buildkit v0.14.0-rc2.0.20240610193248-7da4d591c4dc h1:D/QzYP+52V
github.com/moby/buildkit v0.14.0-rc2.0.20240610193248-7da4d591c4dc/go.mod h1:1XssG7cAqv5Bz1xcGMxJL123iCv5TYN4Z/qf647gfuk=
github.com/moby/buildkit v0.14.0-rc2.0.20240611065153-eed17a45c62b h1:n06ACmuRYPZLR6DbQvVPDRGvqWK7gGCRJjMEzGTemzs=
github.com/moby/buildkit v0.14.0-rc2.0.20240611065153-eed17a45c62b/go.mod h1:1XssG7cAqv5Bz1xcGMxJL123iCv5TYN4Z/qf647gfuk=
github.com/moby/buildkit v0.15.1 h1:J6wrew7hphKqlq1wuu6yaUb/1Ra7gEzDAovylGztAKM=
github.com/moby/buildkit v0.15.1/go.mod h1:Yis8ZMUJTHX9XhH9zVyK2igqSHV3sxi3UN0uztZocZk=
github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc=
github.com/moby/moby v24.0.2+incompatible h1:yH+5dRHH1x3XRKzl1THA2aGTy6CHYnkt5N924ADMax8=
github.com/moby/moby v24.0.2+incompatible/go.mod h1:fDXVQ6+S340veQPv35CzDahGBmHsiclFwfEygB/TWMc=