Skip to content

Commit

Permalink
build: user guide on using build checks
Browse files Browse the repository at this point in the history
Signed-off-by: David Karlsson <35727626+dvdksn@users.noreply.github.com>
  • Loading branch information
dvdksn committed Jun 13, 2024
1 parent ac4d311 commit 1bdffcb
Show file tree
Hide file tree
Showing 2 changed files with 205 additions and 0 deletions.
203 changes: 203 additions & 0 deletions content/build/checks.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
---
title: Checking your build configuration
description: Learn how to use build checks to validate your build configuration.
keywords: build, buildx, buildkit, checks, validate, configuration, lint
---

{{< introduced buildx 0.15.0 >}}

Build checks are a feature introduced in Dockerfile 1.8. It lets you validate
your build configuration and conduct a series of checks prior to executing your
build. Think of it as an advanced form of linting for your Dockerfile and build
options, or a dry-run mode for builds.

You can find the list of checks available, and a description of each, in the
[Build checks reference](/reference/build-checks/).

## How build checks work

Typically, when you run a build, Docker executes the build steps in your
Dockerfile and build options as specified. With build checks, rather than
executing the build steps, Docker checks the Dockerfile and options you provide
and reports any issues it detects.

Build checks are useful for:

- Validating your Dockerfile and build options before running a build.
- Ensuring that your Dockerfile and build options are up-to-date with the
latest best practices.
- Identifying potential issues or anti-patterns in your Dockerfile and build
options.

## Build with checks

Build checks are supported in Buildx version 0.15.0 and later. Invoking a build
runs the checks by default, and displays any violations in the build output.
For example, the following command both builds the image and runs the checks:

```console
$ docker build .
[+] Building 3.5s (11/11) FINISHED
...

1 warning found (use --debug to expand):
- Lint Rule 'JSONArgsRecommended': JSON arguments recommended for CMD to prevent unintended behavior related to OS signals (line 7)

```

In this example, the build ran successfully, but a
[JSONArgsRecommended](/reference/build-checks/json-args-recommended/) warning
was reported, because `CMD` instructions should use JSON array syntax.

### More verbose output

Check warnings for a regular `docker build` display a consice message

Check failure on line 54 in content/build/checks.md

View workflow job for this annotation

GitHub Actions / vale

[vale] reported by reviewdog 🐶 [Vale.Spelling] Did you really mean 'consice'? Raw Output: {"message": "[Vale.Spelling] Did you really mean 'consice'?", "location": {"path": "content/build/checks.md", "range": {"start": {"line": 54, "column": 55}}}, "severity": "ERROR"}
containing the rule name, the message, and the line number of where in the
Dockerfile the issue originated. If you want to see more detailed information
about the checks, you can use the `--debug` flag. For example:

```console
$ docker build --debug .
[+] Building 3.5s (11/11) FINISHED
...

JSONArgsRecommended - https://docs.docker.com/go/dockerfile/rule/json-args-recommended/
JSON arguments recommended for ENTRYPOINT/CMD to prevent unintended behavior related to OS signals
Dockerfile:4
--------------------
2 |
3 | FROM alpine
4 | >>> CMD echo "Hello, world!"
5 |
--------------------

```

With the `--debug` flag, the output includes a link to the documentation for
the check, and a snippet of the Dockerfile where the issue was found.

## Check a build without building

To run build checks without actually building, you can use the `docker build`
command as you typically would, but with the addition of the `--check` flag.
Here's an example:

```console
$ docker build --check .
```

Instead of executing the build steps, this command only runs the checks and
report any issues it finds. If there are any issues, they will be reported in
the output. For example:

```text {title="Output with --check"}
[+] Building 1.5s (5/5) FINISHED
=> [internal] connecting to local controller
=> [internal] load build definition from Dockerfile
=> => transferring dockerfile: 253B
=> [internal] load metadata for docker.io/library/node:22
=> [auth] library/node:pull token for registry-1.docker.io
=> [internal] load .dockerignore
=> => transferring context: 50B
JSONArgsRecommended - https://docs.docker.com/go/dockerfile/rule/json-args-recommended/
JSON arguments recommended for ENTRYPOINT/CMD to prevent unintended behavior related to OS signals
Dockerfile:7
--------------------
5 |
6 | COPY index.js .
7 | >>> CMD node index.js
8 |
--------------------
```

This output with `--check` shows the [verbose message](#more-verbose-output)
for the check.

<!-- TODO(dvdksn): There's a bug with exit codes atm
## Error on check violations
Check violations are reported as warnings by default, but you can configure
Docker to error on check violations (exit with a non-zero status code) using a
`check=error=true` directive in your Dockerfile, as follows:
```dockerfile {title=Dockerfile,linenos=true,hl_lines=2}
# syntax=docker/dockerfile:1
# check=error=true
FROM alpine
CMD echo "Hello, world!"
```
Without the `# check=error=true` directive, this build would complete with an
exit code of 0. However, with the directive, build check violation results in
non-zero exit code:
```console
$ docker build --check .
[+] Building 1.5s (5/5) FINISHED
...
JSONArgsRecommended - https://docs.docker.com/go/dockerfile/rule/json-args-recommended/
JSON arguments recommended for ENTRYPOINT/CMD to prevent unintended behavior related to OS signals
Dockerfile:5
--------------------
3 |
4 | FROM alpine
5 | >>> CMD echo "Hello, world!"
6 |
--------------------
$ echo $?
1
```
You can also set the error directive on the CLI by passing the
`BUILDKIT_DOCKERFILE_CHECK` build argument:
```console
$ docker build --check --build-arg "BUILDKIT_DOCKERFILE_CHECK=error=true" .
```
-->

## Skip checks

By default, all checks are run when you build an image. If you want to skip
specific checks, you can use the `check=skip` directive in your Dockerfile.
The `skip` parameter takes a CSV strings of the check IDs you want to skip.
For example:

```dockerfile {title=Dockerfile}
# syntax=docker/dockerfile:1
# check=skip=JSONArgsRecommended,StageNameCasing

FROM alpine AS BASE_STAGE
CMD echo "Hello, world!"
```

Building this Dockerfile results in no check violations.

You can also skip checks by passing the `BUILDKIT_DOCKERFILE_CHECK` build
argument with a CSV string of check IDs you want to skip. For example:

```console
$ docker build --check --build-arg "BUILDKIT_DOCKERFILE_CHECK=skip=JSONArgsRecommended,StageNameCasing" .
```

<!-- TODO(dvdksn): error parameter doesn't work yet
## Combine error and skip parameters for check directives
To both skip specific checks and error on check violations, pass both the
`skip` and `error` parameters separated by a semi-colon (`;`) to the `check`
directive in your Dockerfile or in a build argument. For example:
```dockerfile {title=Dockerfile}
# syntax=docker/dockerfile:1
# check=skip=JSONArgsRecommended,StageNameCasing;error=true
```
```console {title="Build argument"}
$ docker build --check --build-arg "BUILDKIT_DOCKERFILE_CHECK=skip=JSONArgsRecommended,StageNameCasing;error=true" .
``` -->
2 changes: 2 additions & 0 deletions data/toc.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1882,6 +1882,8 @@ Manuals:
title: OpenTelemetry support
- path: /build/building/base-images/
title: Create your own base image
- path: /build/checks/
title: Build checks {{< badge color=violet text=New >}}
- sectiontitle: Builders
section:
- path: /build/builders/
Expand Down

0 comments on commit 1bdffcb

Please sign in to comment.