vendor: github.com/moby/buildkit v0.17.0

Signed-off-by: David Karlsson <35727626+dvdksn@users.noreply.github.com>
This commit is contained in:
David Karlsson 2024-10-31 10:38:04 +01:00
parent e8e6274e17
commit 16efa7f08b
11 changed files with 262 additions and 77 deletions

View File

@ -1,4 +1,6 @@
# Image Attestation Storage ---
title: Image attestation storage
---
Buildkit supports creating and attaching attestations to build artifacts. These Buildkit supports creating and attaching attestations to build artifacts. These
attestations can provide valuable information from the build process, attestations can provide valuable information from the build process,

View File

@ -1,4 +1,6 @@
# SLSA definitions ---
title: SLSA definitions
---
BuildKit supports the [creation of SLSA Provenance](./slsa-provenance.md) for builds that BuildKit supports the [creation of SLSA Provenance](./slsa-provenance.md) for builds that
it runs. it runs.

View File

@ -62,11 +62,25 @@ insecure-entitlements = [ "network.host", "security.insecure" ]
# Whether run subprocesses in main pid namespace or not, this is useful for # Whether run subprocesses in main pid namespace or not, this is useful for
# running rootless buildkit inside a container. # running rootless buildkit inside a container.
noProcessSandbox = false noProcessSandbox = false
# gc enables/disables garbage collection
gc = true gc = true
# gckeepstorage can be an integer number of bytes (e.g. 512000000), a string # reservedSpace is the minimum amount of disk space guaranteed to be
# with a unit (e.g. "512MB"), or a string percentage of the total disk # retained by this buildkit worker - any usage below this threshold will not
# space (e.g. "10%") # be reclaimed during garbage collection.
gckeepstorage = 9000 # all disk space parameters can be an integer number of bytes (e.g.
# 512000000), a string with a unit (e.g. "512MB"), or a string percentage
# of the total disk space (e.g. "10%")
reservedSpace = "30%"
# maxUsedSpace is the maximum amount of disk space that may be used by
# this buildkit worker - any usage above this threshold will be reclaimed
# during garbage collection.
maxUsedSpace = "60%"
# minFreeSpace is the target amount of free disk space that the garbage
# collector will attempt to leave - however, it will never be bought below
# reservedSpace.
minFreeSpace = "20GB"
# alternate OCI worker binary name(example 'crun'), by default either # alternate OCI worker binary name(example 'crun'), by default either
# buildkit-runc or runc binary is used # buildkit-runc or runc binary is used
binary = "" binary = ""
@ -83,26 +97,51 @@ insecure-entitlements = [ "network.host", "security.insecure" ]
"foo" = "bar" "foo" = "bar"
[[worker.oci.gcpolicy]] [[worker.oci.gcpolicy]]
# keepBytes can be an integer number of bytes (e.g. 512000000), a string # reservedSpace is the minimum amount of disk space guaranteed to be
# with a unit (e.g. "512MB"), or a string percentage of the total disk # retained by this policy - any usage below this threshold will not be
# space (e.g. "10%") # reclaimed during # garbage collection.
keepBytes = "512MB" reservedSpace = "512MB"
# maxUsedSpace is the maximum amount of disk space that may be used by this
# policy - any usage above this threshold will be reclaimed during garbage
# collection.
maxUsedSpace = "1GB"
# minFreeSpace is the target amount of free disk space that the garbage
# collector will attempt to leave - however, it will never be bought below
# reservedSpace.
minFreeSpace = "10GB"
# keepDuration can be an integer number of seconds (e.g. 172800), or a # keepDuration can be an integer number of seconds (e.g. 172800), or a
# string duration (e.g. "48h") # string duration (e.g. "48h")
keepDuration = "48h" keepDuration = "48h"
filters = [ "type==source.local", "type==exec.cachemount", "type==source.git.checkout"] filters = [ "type==source.local", "type==exec.cachemount", "type==source.git.checkout"]
[[worker.oci.gcpolicy]] [[worker.oci.gcpolicy]]
all = true all = true
keepBytes = 1024000000 reservedSpace = 1024000000
[worker.containerd] [worker.containerd]
address = "/run/containerd/containerd.sock" address = "/run/containerd/containerd.sock"
enabled = true enabled = true
platforms = [ "linux/amd64", "linux/arm64" ] platforms = [ "linux/amd64", "linux/arm64" ]
namespace = "buildkit" namespace = "buildkit"
# gc enables/disables garbage collection
gc = true gc = true
# gckeepstorage sets storage limit for default gc profile, in bytes. # reservedSpace is the minimum amount of disk space guaranteed to be
gckeepstorage = 9000 # retained by this buildkit worker - any usage below this threshold will not
# be reclaimed during garbage collection.
# all disk space parameters can be an integer number of bytes (e.g.
# 512000000), a string with a unit (e.g. "512MB"), or a string percentage
# of the total disk space (e.g. "10%")
reservedSpace = "30%"
# maxUsedSpace is the maximum amount of disk space that may be used by
# this buildkit worker - any usage above this threshold will be reclaimed
# during garbage collection.
maxUsedSpace = "60%"
# minFreeSpace is the target amount of free disk space that the garbage
# collector will attempt to leave - however, it will never be bought below
# reservedSpace.
minFreeSpace = "20GB"
# maintain a pool of reusable CNI network namespaces to amortize the overhead # maintain a pool of reusable CNI network namespaces to amortize the overhead
# of allocating and releasing the namespaces # of allocating and releasing the namespaces
cniPoolSize = 16 cniPoolSize = 16
@ -119,12 +158,12 @@ insecure-entitlements = [ "network.host", "security.insecure" ]
options = { BinaryName = "runc" } options = { BinaryName = "runc" }
[[worker.containerd.gcpolicy]] [[worker.containerd.gcpolicy]]
keepBytes = 512000000 reservedSpace = 512000000
keepDuration = 172800 keepDuration = 172800
filters = [ "type==source.local", "type==exec.cachemount", "type==source.git.checkout"] filters = [ "type==source.local", "type==exec.cachemount", "type==source.git.checkout"]
[[worker.containerd.gcpolicy]] [[worker.containerd.gcpolicy]]
all = true all = true
keepBytes = 1024000000 reservedSpace = 1024000000
# registry configures a new Docker register used for cache import or output. # registry configures a new Docker register used for cache import or output.
[registry."docker.io"] [registry."docker.io"]

View File

@ -47,8 +47,8 @@ be UPPERCASE to distinguish them from arguments more easily.
Docker runs instructions in a Dockerfile in order. A Dockerfile **must Docker runs instructions in a Dockerfile in order. A Dockerfile **must
begin with a `FROM` instruction**. This may be after [parser begin with a `FROM` instruction**. This may be after [parser
directives](#parser-directives), [comments](#format), and globally scoped directives](#parser-directives), [comments](#format), and globally scoped
[ARGs](#arg). The `FROM` instruction specifies the [parent [ARGs](#arg). The `FROM` instruction specifies the [base
image](https://docs.docker.com/glossary/#parent-image) from which you are image](https://docs.docker.com/glossary/#base-image) from which you are
building. `FROM` may only be preceded by one or more `ARG` instructions, which building. `FROM` may only be preceded by one or more `ARG` instructions, which
declare arguments that are used in `FROM` lines in the Dockerfile. declare arguments that are used in `FROM` lines in the Dockerfile.
@ -345,6 +345,11 @@ despite warnings. To make the build fail on warnings, set `#check=error=true`.
# check=error=true # check=error=true
``` ```
> [!NOTE]
> When using the `check` directive, with `error=true` option, it is recommended
> to pin the [Dockerfile syntax]((#syntax)) to a specific version. Otherwise, your build may
> start to fail when new checks are added in the future versions.
To combine both the `skip` and `error` options, use a semi-colon to separate To combine both the `skip` and `error` options, use a semi-colon to separate
them: them:
@ -723,7 +728,7 @@ This can be used to:
The supported mount types are: The supported mount types are:
| Type | Description | | Type | Description |
| ---------------------------------------- | --------------------------------------------------------------------------------------------------------- | | ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| [`bind`](#run---mounttypebind) (default) | Bind-mount context directories (read-only). | | [`bind`](#run---mounttypebind) (default) | Bind-mount context directories (read-only). |
| [`cache`](#run---mounttypecache) | Mount a temporary directory to cache directories for compilers and package managers. | | [`cache`](#run---mounttypecache) | Mount a temporary directory to cache directories for compilers and package managers. |
| [`tmpfs`](#run---mounttypetmpfs) | Mount a `tmpfs` in the build container. | | [`tmpfs`](#run---mounttypetmpfs) | Mount a `tmpfs` in the build container. |
@ -736,7 +741,7 @@ This mount type allows binding files or directories to the build container. A
bind mount is read-only by default. bind mount is read-only by default.
| Option | Description | | Option | Description |
| ---------------- | ---------------------------------------------------------------------------------------------- | | ---------------------------------- | ---------------------------------------------------------------------------------------------- |
| `target`, `dst`, `destination`[^1] | Mount path. | | `target`, `dst`, `destination`[^1] | Mount path. |
| `source` | Source path in the `from`. Defaults to the root of the `from`. | | `source` | Source path in the `from`. Defaults to the root of the `from`. |
| `from` | Build stage, context, or image name for the root of the source. Defaults to the build context. | | `from` | Build stage, context, or image name for the root of the source. Defaults to the build context. |
@ -748,7 +753,7 @@ This mount type allows the build container to cache directories for compilers
and package managers. and package managers.
| Option | Description | | Option | Description |
| --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id` | Optional ID to identify separate/different caches. Defaults to value of `target`. | | `id` | Optional ID to identify separate/different caches. Defaults to value of `target`. |
| `target`, `dst`, `destination`[^1] | Mount path. | | `target`, `dst`, `destination`[^1] | Mount path. |
| `ro`,`readonly` | Read-only if set. | | `ro`,`readonly` | Read-only if set. |
@ -797,7 +802,7 @@ case.
This mount type allows mounting `tmpfs` in the build container. This mount type allows mounting `tmpfs` in the build container.
| Option | Description | | Option | Description |
| ------------ | ----------------------------------------------------- | | ---------------------------------- | ----------------------------------------------------- |
| `target`, `dst`, `destination`[^1] | Mount path. | | `target`, `dst`, `destination`[^1] | Mount path. |
| `size` | Specify an upper limit on the size of the filesystem. | | `size` | Specify an upper limit on the size of the filesystem. |
@ -842,7 +847,7 @@ environment variable with the same name.
# syntax=docker/dockerfile:1 # syntax=docker/dockerfile:1
FROM alpine FROM alpine
RUN --mount=type=secret,id=API_KEY,env=API_KEY \ RUN --mount=type=secret,id=API_KEY,env=API_KEY \
some-command --token-from-env API_KEY some-command --token-from-env $API_KEY
``` ```
Assuming that the `API_KEY` environment variable is set in the build Assuming that the `API_KEY` environment variable is set in the build
@ -858,7 +863,7 @@ This mount type allows the build container to access SSH keys via SSH agents,
with support for passphrases. with support for passphrases.
| Option | Description | | Option | Description |
| ---------- | ---------------------------------------------------------------------------------------------- | | ------------------------------ | ---------------------------------------------------------------------------------------------- |
| `id` | ID of SSH agent socket or key. Defaults to "default". | | `id` | ID of SSH agent socket or key. Defaults to "default". |
| `target`, `dst`, `destination` | SSH agent socket path. Defaults to `/run/buildkit/ssh_agent.${N}`. | | `target`, `dst`, `destination` | SSH agent socket path. Defaults to `/run/buildkit/ssh_agent.${N}`. |
| `required` | If set to `true`, the instruction errors out when the key is unavailable. Defaults to `false`. | | `required` | If set to `true`, the instruction errors out when the key is unavailable. Defaults to `false`. |
@ -1012,7 +1017,7 @@ both the `CMD` and `ENTRYPOINT` instructions should be specified in the
## LABEL ## LABEL
```dockerfile ```dockerfile
LABEL <key>=<value> <key>=<value> <key>=<value> ... LABEL <key>=<value> [<key>=<value>...]
``` ```
The `LABEL` instruction adds metadata to an image. A `LABEL` is a The `LABEL` instruction adds metadata to an image. A `LABEL` is a
@ -1047,9 +1052,9 @@ LABEL multi.label1="value1" \
> using string interpolation (e.g. `LABEL example="foo-$ENV_VAR"`), single > using string interpolation (e.g. `LABEL example="foo-$ENV_VAR"`), single
> quotes will take the string as is without unpacking the variable's value. > quotes will take the string as is without unpacking the variable's value.
Labels included in base or parent images (images in the `FROM` line) are Labels included in base images (images in the `FROM` line) are inherited by
inherited by your image. If a label already exists but with a different value, your image. If a label already exists but with a different value, the
the most-recently-applied value overrides any previously-set value. most-recently-applied value overrides any previously-set value.
To view an image's labels, use the `docker image inspect` command. You can use To view an image's labels, use the `docker image inspect` command. You can use
the `--format` option to show just the labels; the `--format` option to show just the labels;
@ -1139,7 +1144,7 @@ port. For detailed information, see the
## ENV ## ENV
```dockerfile ```dockerfile
ENV <key>=<value> ... ENV <key>=<value> [<key>=<value>...]
``` ```
The `ENV` instruction sets the environment variable `<key>` to the value The `ENV` instruction sets the environment variable `<key>` to the value
@ -1232,7 +1237,7 @@ The available `[OPTIONS]` are:
| [`--chown`](#add---chown---chmod) | | | [`--chown`](#add---chown---chmod) | |
| [`--chmod`](#add---chown---chmod) | 1.2 | | [`--chmod`](#add---chown---chmod) | 1.2 |
| [`--link`](#add---link) | 1.4 | | [`--link`](#add---link) | 1.4 |
| [`--exclude`](#add---exclude) | 1.7 | | [`--exclude`](#add---exclude) | 1.7-labs |
The `ADD` instruction copies new files or directories from `<src>` and adds 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 them to the filesystem of the image at the path `<dest>`. Files and directories
@ -1517,8 +1522,8 @@ The available `[OPTIONS]` are:
| [`--chown`](#copy---chown---chmod) | | | [`--chown`](#copy---chown---chmod) | |
| [`--chmod`](#copy---chown---chmod) | 1.2 | | [`--chmod`](#copy---chown---chmod) | 1.2 |
| [`--link`](#copy---link) | 1.4 | | [`--link`](#copy---link) | 1.4 |
| [`--parents`](#copy---parents) | 1.7 | | [`--parents`](#copy---parents) | 1.7-labs |
| [`--exclude`](#copy---exclude) | 1.7 | | [`--exclude`](#copy---exclude) | 1.7-labs |
The `COPY` instruction copies new files or directories from `<src>` and adds 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 them to the filesystem of the image at the path `<dest>`. Files and directories
@ -1815,7 +1820,7 @@ COPY [--parents[=<boolean>]] <src> ... <dest>
The `--parents` flag preserves parent directories for `src` entries. This flag defaults to `false`. The `--parents` flag preserves parent directories for `src` entries. This flag defaults to `false`.
```dockerfile ```dockerfile
# syntax=docker/dockerfile:1.7-labs # syntax=docker/dockerfile:1-labs
FROM scratch FROM scratch
COPY ./x/a.txt ./y/a.txt /no_parents/ COPY ./x/a.txt ./y/a.txt /no_parents/
@ -1835,7 +1840,7 @@ directories after it will be preserved. This may be especially useful copies bet
with `--from` where the source paths need to be absolute. with `--from` where the source paths need to be absolute.
```dockerfile ```dockerfile
# syntax=docker/dockerfile:1.7-labs # syntax=docker/dockerfile:1-labs
FROM scratch FROM scratch
COPY --parents ./x/./y/*.txt /parents/ COPY --parents ./x/./y/*.txt /parents/
@ -1877,6 +1882,9 @@ supporting wildcards and matching using Go's
For example, to add all files starting with "hom", excluding files with a `.txt` extension: For example, to add all files starting with "hom", excluding files with a `.txt` extension:
```dockerfile ```dockerfile
# syntax=docker/dockerfile:1-labs
FROM scratch
COPY --exclude=*.txt hom* /mydir/ COPY --exclude=*.txt hom* /mydir/
``` ```
@ -1886,6 +1894,9 @@ even if the files paths match the pattern specified in `<src>`.
To add all files starting with "hom", excluding files with either `.txt` or `.md` extensions: To add all files starting with "hom", excluding files with either `.txt` or `.md` extensions:
```dockerfile ```dockerfile
# syntax=docker/dockerfile:1-labs
FROM scratch
COPY --exclude=*.txt --exclude=*.md hom* /mydir/ COPY --exclude=*.txt --exclude=*.md hom* /mydir/
``` ```
@ -2305,7 +2316,7 @@ Therefore, to avoid unintended operations in unknown directories, it's best prac
## ARG ## ARG
```dockerfile ```dockerfile
ARG <name>[=<default value>] ARG <name>[=<default value>] [<name>[=<default value>]...]
``` ```
The `ARG` instruction defines a variable that users can pass at build-time to The `ARG` instruction defines a variable that users can pass at build-time to
@ -2349,9 +2360,8 @@ at build-time, the builder uses the default.
### Scope ### Scope
An `ARG` variable definition comes into effect from the line on which it is An `ARG` variable comes into effect from the line on which it is declared in
defined in the Dockerfile not from the argument's use on the command-line or the Dockerfile. For example, consider this Dockerfile:
elsewhere. For example, consider this Dockerfile:
```dockerfile ```dockerfile
FROM busybox FROM busybox
@ -2367,24 +2377,22 @@ A user builds this file by calling:
$ docker build --build-arg username=what_user . $ docker build --build-arg username=what_user .
``` ```
The `USER` at line 2 evaluates to `some_user` as the `username` variable is defined on the - The `USER` instruction on line 2 evaluates to the `some_user` fallback,
subsequent line 3. The `USER` at line 4 evaluates to `what_user`, as the `username` argument is because the `username` variable is not yet declared.
defined and the `what_user` value was passed on the command line. Prior to its definition by an - The `username` variable is declared on line 3, and available for reference in
`ARG` instruction, any use of a variable results in an empty string. Dockerfile instruction from that point onwards.
- The `USER` instruction on line 4 evaluates to `what_user`, since at that
point the `username` argument has a value of `what_user` which was passed on
the command line. Prior to its definition by an `ARG` instruction, any use of
a variable results in an empty string.
An `ARG` instruction goes out of scope at the end of the build An `ARG` variable declared within a build stage is automatically inherited by
stage where it was defined. To use an argument in multiple stages, each stage must other stages based on that stage. Unrelated build stages do not have access to
include the `ARG` instruction. the variable. To use an argument in multiple distinct stages, each stage must
include the `ARG` instruction, or they must both be based on a shared base
stage in the same Dockerfile where the variable is declared.
```dockerfile For more information, refer to [variable scoping](https://docs.docker.com/build/building/variables/#scoping).
FROM busybox
ARG SETTINGS
RUN ./run/setup $SETTINGS
FROM busybox
ARG SETTINGS
RUN ./run/other $SETTINGS
```
### Using ARG variables ### Using ARG variables
@ -2622,8 +2630,6 @@ another build. The trigger will be executed in the context of the
downstream build, as if it had been inserted immediately after the downstream build, as if it had been inserted immediately after the
`FROM` instruction in the downstream Dockerfile. `FROM` instruction in the downstream Dockerfile.
Any build instruction can be registered as a trigger.
This is useful if you are building an image which will be used as a base This is useful if you are building an image which will be used as a base
to build other images, for example an application build environment or a to build other images, for example an application build environment or a
daemon which may be customized with user-specific configuration. daemon which may be customized with user-specific configuration.
@ -2666,11 +2672,26 @@ ONBUILD ADD . /app/src
ONBUILD RUN /usr/local/bin/python-build --dir /app/src ONBUILD RUN /usr/local/bin/python-build --dir /app/src
``` ```
### Copy or mount from stage, image, or context
As of Dockerfile syntax 1.11, you can use `ONBUILD` with instructions that copy
or mount files from other stages, images, or build contexts. For example:
```dockerfile
# syntax=docker/dockerfile:1.11
FROM alpine AS baseimage
ONBUILD COPY --from=build /usr/bin/app /app
ONBUILD RUN --mount=from=config,target=/opt/appconfig ...
```
If the source of `from` is a build stage, the stage must be defined in the
Dockerfile where `ONBUILD` gets triggered. If it's a named context, that
context must be passed to the downstream build.
### ONBUILD limitations ### ONBUILD limitations
- Chaining `ONBUILD` instructions using `ONBUILD ONBUILD` isn't allowed. - Chaining `ONBUILD` instructions using `ONBUILD ONBUILD` isn't allowed.
- The `ONBUILD` instruction may not trigger `FROM` or `MAINTAINER` instructions. - The `ONBUILD` instruction may not trigger `FROM` or `MAINTAINER` instructions.
- `ONBUILD COPY --from` is [not supported](https://github.com/moby/buildkit/issues/816).
## STOPSIGNAL ## STOPSIGNAL
@ -3002,10 +3023,9 @@ hello world
For examples of Dockerfiles, refer to: For examples of Dockerfiles, refer to:
- The ["build images" section](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/) - The [building best practices page](https://docs.docker.com/build/building/best-practices/)
- The ["get started" tutorial](https://docs.docker.com/get-started/) - The ["get started" tutorials](https://docs.docker.com/get-started/)
- The [language-specific getting started guides](https://docs.docker.com/language/) - The [language-specific getting started guides](https://docs.docker.com/guides/language/)
- The [build guide](https://docs.docker.com/build/guide/)
[^1]: Value required [^1]: Value required
[^2]: For Docker-integrated [BuildKit](https://docs.docker.com/build/buildkit/#getting-started) and `docker buildx build` [^2]: For Docker-integrated [BuildKit](https://docs.docker.com/build/buildkit/#getting-started) and `docker buildx build`

View File

@ -103,5 +103,9 @@ To learn more about how to use build checks, see
<td><a href="./copy-ignored-file/">CopyIgnoredFile (experimental)</a></td> <td><a href="./copy-ignored-file/">CopyIgnoredFile (experimental)</a></td>
<td>Attempting to Copy file that is excluded by .dockerignore</td> <td>Attempting to Copy file that is excluded by .dockerignore</td>
</tr> </tr>
<tr>
<td><a href="./invalid-definition-description/">InvalidDefinitionDescription (experimental)</a></td>
<td>Comment for build stage or argument should follow the format: `# <arg/stage name> <description>`. If this is not intended to be a description comment, add an empty line or comment between the instruction and the comment.</td>
</tr>
</tbody> </tbody>
</table> </table>

View File

@ -0,0 +1,70 @@
---
title: InvalidDefinitionDescription
description: Comment for build stage or argument should follow the format: `# <arg/stage name> <description>`. If this is not intended to be a description comment, add an empty line or comment between the instruction and the comment.
aliases:
- /go/dockerfile/rule/invalid-definition-description/
---
> [!NOTE]
> This check is experimental and is not enabled by default. To enable it, see
> [Experimental checks](https://docs.docker.com/go/build-checks-experimental/).
## Output
```text
Comment for build stage or argument should follow the format: `# <arg/stage name> <description>`. If this is not intended to be a description comment, add an empty line or comment between the instruction and the comment.
```
## Description
The [`--call=outline`](https://docs.docker.com/reference/cli/docker/buildx/build/#call-outline)
and [`--call=targets`](https://docs.docker.com/reference/cli/docker/buildx/build/#call-outline)
flags for the `docker build` command print descriptions for build targets and arguments.
The descriptions are generated from [Dockerfile comments](https://docs.docker.com/reference/cli/docker/buildx/build/#descriptions)
that immediately precede the `FROM` or `ARG` instruction
and that begin with the name of the build stage or argument.
For example:
```dockerfile
# build-cli builds the CLI binary
FROM alpine AS build-cli
# VERSION controls the version of the program
ARG VERSION=1
```
In cases where preceding comments are not meant to be descriptions,
add an empty line or comment between the instruction and the preceding comment.
## Examples
❌ Bad: A non-descriptive comment on the line preceding the `FROM` command.
```dockerfile
# a non-descriptive comment
FROM scratch AS base
# another non-descriptive comment
ARG VERSION=1
```
✅ Good: An empty line separating non-descriptive comments.
```dockerfile
# a non-descriptive comment
FROM scratch AS base
# another non-descriptive comment
ARG VERSION=1
```
✅ Good: Comments describing `ARG` keys and stages immediately proceeding the command.
```dockerfile
# base is a stage for compiling source
FROM scratch AS base
# VERSION This is the version number.
ARG VERSION=1
```

View File

@ -50,10 +50,41 @@ Note that running programs as PID 1 means the program now has the special
responsibilities and behaviors associated with PID 1 in Linux, such as reaping responsibilities and behaviors associated with PID 1 in Linux, such as reaping
child processes. child processes.
Alternatively, if you want to ignore this lint rule because you do want your ### Workarounds
executable to be invoked via a shell, you can use the
[`SHELL`](https://docs.docker.com/reference/dockerfile.md#shell) Dockerfile There might still be cases when you want to run your containers under a shell.
instruction to explicitly specify a shell to use. When using exec form, shell features such as variable expansion, piping (`|`)
and command chaining (`&&`, `||`, `;`), are not available. To use such
features, you need to use shell form.
Here are some ways you can achieve that. Note that this still means that
executables run as child-processes of a shell.
#### Create a wrapper script
You can create an entrypoint script that wraps your startup commands, and
execute that script with a JSON-formatted `ENTRYPOINT` command.
✅ Good: the `ENTRYPOINT` uses JSON format.
```dockerfile
FROM alpine
RUN apk add bash
COPY --chmod=755 <<EOT /entrypoint.sh
#!/usr/bin/env bash
set -e
my-background-process &
my-program start
EOT
ENTRYPOINT ["/entrypoint.sh"]
```
#### Explicitly specify the shell
You can use the [`SHELL`](https://docs.docker.com/reference/dockerfile/#shell)
Dockerfile instruction to explicitly specify a shell to use. This will suppress
the warning since setting the `SHELL` instruction indicates that using shell
form is a conscious decision.
✅ Good: shell is explicitly defined. ✅ Good: shell is explicitly defined.

View File

@ -13,24 +13,25 @@ Usage of undefined variable '$foo'
## Description ## Description
Before you reference an environment variable or a build argument in a `RUN` This check ensures that environment variables and build arguments are correctly
instruction, you should ensure that the variable is declared in the Dockerfile, declared before being used. While undeclared variables might not cause an
using the `ARG` or `ENV` instructions. immediate build failure, they can lead to unexpected behavior or errors later
in the build process.
Attempting to access an environment variable without explicitly declaring it This check does not evaluate undefined variables for `RUN`, `CMD`, and
doesn't necessarily result in a build error, but it may yield an unexpected `ENTRYPOINT` instructions where you use the [shell form](https://docs.docker.com/reference/dockerfile/#shell-form).
result or an error later on in the build process. That's because when you use shell form, variables are resolved by the command
shell.
This check also attempts to detect if you're accessing a variable with a typo. It also detects common mistakes like typos in variable names. For example, in
For example, given the following Dockerfile: the following Dockerfile:
```dockerfile ```dockerfile
FROM alpine FROM alpine
ENV PATH=$PAHT:/app/bin ENV PATH=$PAHT:/app/bin
``` ```
The check detects that `$PAHT` is undefined, and that it's probably a The check identifies that `$PAHT` is undefined and likely a typo for `$PATH`:
misspelling of `PATH`.
```text ```text
Usage of undefined variable '$PAHT' (did you mean $PATH?) Usage of undefined variable '$PAHT' (did you mean $PATH?)
@ -53,3 +54,17 @@ ARG foo
COPY $foo . COPY $foo .
``` ```
❌ Bad: `$foo` is undefined.
```dockerfile
FROM alpine AS base
ARG VERSION=$foo
```
✅ Good: the base image defines `$PYTHON_VERSION`
```dockerfile
FROM python AS base
ARG VERSION=$PYTHON_VERSION
```

View File

@ -1,5 +1,5 @@
# github.com/moby/moby v27.3.1+incompatible # github.com/moby/moby v27.3.1+incompatible
# github.com/moby/buildkit v0.16.0 # github.com/moby/buildkit v0.17.0
# github.com/docker/buildx v0.17.1 # github.com/docker/buildx v0.17.1
# github.com/docker/cli v27.3.2-0.20241008150905-cb3048fbebb1+incompatible # github.com/docker/cli v27.3.2-0.20241008150905-cb3048fbebb1+incompatible
# github.com/docker/compose/v2 v2.30.1 # github.com/docker/compose/v2 v2.30.1

4
go.mod
View File

@ -7,7 +7,7 @@ require (
github.com/docker/cli v27.3.2-0.20241008150905-cb3048fbebb1+incompatible // indirect github.com/docker/cli v27.3.2-0.20241008150905-cb3048fbebb1+incompatible // indirect
github.com/docker/compose/v2 v2.30.1 // indirect github.com/docker/compose/v2 v2.30.1 // indirect
github.com/docker/scout-cli v1.13.0 // indirect github.com/docker/scout-cli v1.13.0 // indirect
github.com/moby/buildkit v0.16.0 // indirect github.com/moby/buildkit v0.17.0 // indirect
github.com/moby/moby v27.3.1+incompatible // indirect github.com/moby/moby v27.3.1+incompatible // indirect
) )
@ -16,6 +16,6 @@ replace (
github.com/docker/cli => github.com/docker/cli v27.3.1+incompatible github.com/docker/cli => github.com/docker/cli v27.3.1+incompatible
github.com/docker/compose/v2 => github.com/docker/compose/v2 v2.30.1 github.com/docker/compose/v2 => github.com/docker/compose/v2 v2.30.1
github.com/docker/scout-cli => github.com/docker/scout-cli v1.13.0 github.com/docker/scout-cli => github.com/docker/scout-cli v1.13.0
github.com/moby/buildkit => github.com/moby/buildkit v0.16.0 github.com/moby/buildkit => github.com/moby/buildkit v0.17.0
github.com/moby/moby => github.com/moby/moby v27.3.1+incompatible github.com/moby/moby => github.com/moby/moby v27.3.1+incompatible
) )

2
go.sum
View File

@ -300,6 +300,8 @@ github.com/moby/buildkit v0.15.1 h1:J6wrew7hphKqlq1wuu6yaUb/1Ra7gEzDAovylGztAKM=
github.com/moby/buildkit v0.15.1/go.mod h1:Yis8ZMUJTHX9XhH9zVyK2igqSHV3sxi3UN0uztZocZk= github.com/moby/buildkit v0.15.1/go.mod h1:Yis8ZMUJTHX9XhH9zVyK2igqSHV3sxi3UN0uztZocZk=
github.com/moby/buildkit v0.16.0 h1:wOVBj1o5YNVad/txPQNXUXdelm7Hs/i0PUFjzbK0VKE= github.com/moby/buildkit v0.16.0 h1:wOVBj1o5YNVad/txPQNXUXdelm7Hs/i0PUFjzbK0VKE=
github.com/moby/buildkit v0.16.0/go.mod h1:Xqx/5GlrqE1yIRORk0NSCVDFpQAU1WjlT6KHYZdisIQ= github.com/moby/buildkit v0.16.0/go.mod h1:Xqx/5GlrqE1yIRORk0NSCVDFpQAU1WjlT6KHYZdisIQ=
github.com/moby/buildkit v0.17.0 h1:ZA/4AxwBbve1f3ZaNNJQiCBtTV62R6YweWNwq4A+sTc=
github.com/moby/buildkit v0.17.0/go.mod h1:ru8NFyDHD8HbuKaLXJIjK9nr3x6FZR+IWjtF07S+wdM=
github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc= 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 h1:yH+5dRHH1x3XRKzl1THA2aGTy6CHYnkt5N924ADMax8=
github.com/moby/moby v24.0.2+incompatible/go.mod h1:fDXVQ6+S340veQPv35CzDahGBmHsiclFwfEygB/TWMc= github.com/moby/moby v24.0.2+incompatible/go.mod h1:fDXVQ6+S340veQPv35CzDahGBmHsiclFwfEygB/TWMc=