From 97d2765d98b0031779bf9a1f2252bf1d3299b2d9 Mon Sep 17 00:00:00 2001 From: David Karlsson <35727626+dvdksn@users.noreply.github.com> Date: Tue, 5 Dec 2023 08:59:45 +0100 Subject: [PATCH 1/4] build: annotations Signed-off-by: David Karlsson <35727626+dvdksn@users.noreply.github.com> --- content/build/building/annotations.md | 192 ++++++++++++++++++ .../build/ci/github-actions/annotations.md | 165 +++++++++++++++ data/toc.yaml | 4 + 3 files changed, 361 insertions(+) create mode 100644 content/build/building/annotations.md create mode 100644 content/build/ci/github-actions/annotations.md diff --git a/content/build/building/annotations.md b/content/build/building/annotations.md new file mode 100644 index 0000000000..8bcd22a6aa --- /dev/null +++ b/content/build/building/annotations.md @@ -0,0 +1,192 @@ +--- +title: Annotations +description: Annotations specify additional metadata about OCI images +keywords: build, buildkit, annotations, metadata +--- + +Annotations provide descriptive metadata for images. Use annotations to record +arbitrary information and attach it to your image, which helps consumers and +tools understand the origin, contents, and how to use the image. + +Annotations are similar to, and in some sense overlap with, [labels]. Both +serve the same purpose: attach metadata to a resource. As a general principle, +you can think of the difference between annotations and labels as follows: + +- Annotations describe OCI image components, such as [manifests], [indexes], + and [descriptors]. +- Labels describe Docker resources, such as images, containers, networks, and + volumes. + +The OCI image [specification] defines the format of annotations, as well as a set +of pre-defined annotation keys. Adhering to the specified standards ensures +that metadata about images can be surfaced automatically and consistently, by +tools like Docker Scout. + +Annotations are not to be confused with [attestations]: + +- Attestations contain information about how an image was built and what it contains. + An attestation is attached as a separate manifest on the image index. + Attestations are not standardized by the Open Container Initiative. +- Annotations contain arbitrary metadata about an image. + Annotations attach to the image [config] as labels, + or on the image index or manifest as properties. + +## Add annotations + +You can add annotations to an image at build-time, or when creating the image +manifest or index. + +> **Note** +> +> The Docker Engine image store doesn't support loading images with +> annotations. To build with annotations, make sure to push the image directly +> to a registry, using the `--push` CLI flag or the +> [registry exporter](../exporters/image-registry.md). + +To specify annotations on the command line, use the `--annotation` flag for the +`docker build` command: + +```console +$ docker build --push --annotation "foo=bar" . +``` + +If you're using [Bake](../bake/_index.md), you can use the `annotations` +attribute to specify annotations for a given target: + +```hcl +target "default" { + output = ["type=registry"] + annotations = ["foo=bar"] +} +``` + +For examples on how to add annotations to images built with GitHub Actions, see +[Add image annotations with GitHub Actions](../ci/github-actions/annotations.md) + +You can also add annotations to an image created using `docker buildx +imagetools create`. This command only supports adding annotations to an index +or manifest descriptors, see +[CLI reference](../../engine/reference/commandline/buildx_imagetools_create.md#annotations). + +## Inspect annotations + +To view annotations on an **image index**, use the `docker buildx imagetools +inspect` command. This shows you any annotations for the index and descriptors +(references to manifests) that the index contains. The following example shows +an `org.opencontainers.image.documentation` annotation on a descriptor, and an +`org.opencontainers.image.authors` annotation on the index. + +```console {hl_lines=["10-12","19-21"]} +$ docker buildx imagetools inspect --raw +{ + "schemaVersion": 2, + "mediaType": "application/vnd.oci.image.index.v1+json", + "manifests": [ + { + "mediaType": "application/vnd.oci.image.manifest.v1+json", + "digest": "sha256:d20246ef744b1d05a1dd69d0b3fa907db007c07f79fe3e68c17223439be9fefb", + "size": 911, + "annotations": { + "org.opencontainers.image.documentation": "https://foo.example/docs", + }, + "platform": { + "architecture": "amd64", + "os": "linux" + } + }, + ], + "annotations": { + "org.opencontainers.image.authors": "dvdksn" + } +} +``` + +To inspect annotations on a manifest, use the `docker buildx imagetools +inspect` command and specify `@`, where `` is the digest +of the manifest: + +```console {hl_lines="22-25"} +$ docker buildx imagetools inspect @sha256:d20246ef744b1d05a1dd69d0b3fa907db007c07f79fe3e68c17223439be9fefb --raw +{ + "schemaVersion": 2, + "mediaType": "application/vnd.oci.image.manifest.v1+json", + "config": { + "mediaType": "application/vnd.oci.image.config.v1+json", + "digest": "sha256:4368b6959a78b412efa083c5506c4887e251f1484ccc9f0af5c406d8f76ece1d", + "size": 850 + }, + "layers": [ + { + "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip", + "digest": "sha256:2c03dbb20264f09924f9eab176da44e5421e74a78b09531d3c63448a7baa7c59", + "size": 3333033 + }, + { + "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip", + "digest": "sha256:4923ad480d60a548e9b334ca492fa547a3ce8879676685b6718b085de5aaf142", + "size": 61887305 + } + ], + "annotations": { + "index,manifest:org.opencontainers.image.vendor": "foocorp", + "org.opencontainers.image.source": "https://git.example/foo.git", + } +} +``` + +## Specify annotation level + +By default, annotations are added to the image manifest. You can specify which +level(s) to attach the manifest to, by prefixing the annotation string with a +special type declaration: + +- `manifest`: annotates manifests. +- `index`: annotates the root index. +- `manifest-descriptor`: annotates manifest descriptors in the index. +- `index-descriptor`: annotates the index descriptor in the image layout. + +For example, to build an image with the annotation `foo=bar` attached to the +image index: + +```console +$ docker build --tag --push --annotation "index:foo=bar" . +``` + +It's possible to specify types, separated by a comma, to add the annotation to +more than one level. The following example creates an image with the annotation +`foo=bar` on both the image index and the image manifest: + +```console +$ docker build --tag --push --annotation "index,manifest:foo=bar" . +``` + +You can also specify a platform qualifier in the type prefix, to annotate only +components matching specific OS and architectures. The following example adds +the `foo=bar` annotation only to the `linux/amd64` manifest: + +```console +$ docker build --tag --push --annotation "manifest[linux/amd64]:foo=bar" . +``` + +## Related information + +Related articles: + +- [Add image annotations with GitHub Actions](../ci/github-actions/annotations.md) +- [Annotations OCI specification][specification] + +Reference information: + +- [`docker buildx build --annotation`](../../engine/reference/commandline/buildx_build.md#annotation) +- [Bake file reference: `annotations`](../bake/reference.md#targetannotations) +- [`docker buildx imagetools create --annotation`](../../engine/reference/commandline/buildx_imagetools_create.md#annotation) + + + +[specification]: https://github.com/opencontainers/image-spec/blob/main/annotations.md +[attestations]: ../attestations/_index.md +[config]: https://github.com/opencontainers/image-spec/blob/main/config.md +[descriptors]: https://github.com/opencontainers/image-spec/blob/main/descriptor.md +[indexes]: https://github.com/opencontainers/image-spec/blob/main/image-index.md +[labels]: ../../config/labels-custom-metadata.md +[manifests]: https://github.com/opencontainers/image-spec/blob/main/manifest.md diff --git a/content/build/ci/github-actions/annotations.md b/content/build/ci/github-actions/annotations.md new file mode 100644 index 0000000000..0c7f4dee3a --- /dev/null +++ b/content/build/ci/github-actions/annotations.md @@ -0,0 +1,165 @@ +--- +title: Add image annotations with GitHub Actions +description: Add OCI annotations to image components using GitHub Actions +keywords: ci, github actions, gha, buildkit, buildx, annotations, oci +--- + +Annotations let you specify arbitrary metadata for OCI image components, such +as manifests, indexes, and descriptors. + +To add annotations when building images with GitHub Actions, use the +[metadata-action] to automatically create OCI-compliant annotations. The +metadata action creates an `annotations` output that you can reference, both +with [build-push-action] and [bake-action]. + +[metadata-action]: https://github.com/docker/metadata-action#overwrite-labels-and-annotations +[build-push-action]: https://github.com/docker/build-push-action/ +[bake-action]: https://github.com/docker/bake-action/ + +{{< tabs >}} +{{< tab name="build-push-action" >}} + +```yaml {hl_lines=37} +name: ci + +on: + push: + branches: + - "main" + +env: + IMAGE_NAME: user/app + +jobs: + docker: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Extract metadata + id: meta + uses: docker/metadata-action@v4 + with: + images: ${{ env.IMAGE_NAME }} + + - name: Build and push + uses: docker/build-push-action@v5 + with: + tags: ${{ steps.meta.outputs.tags }} + annotations: ${{ steps.meta.outputs.annotations }} + push: true +``` + +{{< /tab >}} +{{< tab name="bake-action" >}} + +```yaml {hl_lines=39} +name: ci + +on: + push: + branches: + - "main" + +env: + IMAGE_NAME: user/app + +jobs: + docker: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Extract metadata + id: meta + uses: docker/metadata-action@v4 + with: + images: ${{ env.IMAGE_NAME }} + + - name: Build + uses: docker/bake-action@v3 + with: + files: | + ./docker-bake.hcl + ${{ steps.meta.outputs.bake-file-tags }} + ${{ steps.meta.outputs.bake-file-annotations }} + push: true +``` + +{{< /tab >}} +{{< /tabs >}} + +## Configure annotation level + +By default, annotations are placed on image manifests. To configure the +[annotation level](../../building/annotations.md#specify-annotation-level), set +the `DOCKER_METADATA_ANNOTATIONS_LEVELS` environment variable on the +`metadata-action` step to a comma-separated list of all the levels that you +want to annotate. For example, setting `DOCKER_METADATA_ANNOTATIONS_LEVELS` to +`index` results in annotations on the image index instead of the manifests. + +The following example creates annotations on both the image index and +manifests. + +```yaml {hl_lines=33} +name: ci + +on: + push: + branches: + - "main" + +env: + IMAGE_NAME: user/app + +jobs: + docker: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Extract metadata + id: meta + uses: docker/metadata-action@v4 + with: + images: ${{ env.IMAGE_NAME }} + env: + DOCKER_METADATA_ANNOTATIONS_LEVELS: manifest,index + + - name: Build and push + uses: docker/build-push-action@v5 + with: + tags: ${{ steps.meta.outputs.tags }} + annotations: ${{ steps.meta.outputs.annotations }} + push: true +``` diff --git a/data/toc.yaml b/data/toc.yaml index a4f88e25d8..f4adfbae2b 100644 --- a/data/toc.yaml +++ b/data/toc.yaml @@ -1790,6 +1790,8 @@ Manuals: title: Environment variables - path: /build/building/secrets/ title: Build secrets + - path: /build/building/annotations/ + title: Annotations - path: /build/building/opentelemetry/ title: OpenTelemetry support - path: /build/building/base-images/ @@ -1922,6 +1924,8 @@ Manuals: title: Update Docker Hub repo description - path: /build/ci/github-actions/attestations/ title: SBOM and provenance attestations + - path: /build/ci/github-actions/annotations/ + title: Annotations - path: /build/release-notes/ title: Release notes - sectiontitle: Docker Compose From cda0db80b5f9c594c4d57b315b6ab95925e9174f Mon Sep 17 00:00:00 2001 From: David Karlsson <35727626+dvdksn@users.noreply.github.com> Date: Thu, 14 Dec 2023 10:19:56 +0100 Subject: [PATCH 2/4] vendor: github.com/docker/buildx b68ee824c67342b19c4208dbfef40a3498e17a7b Signed-off-by: David Karlsson <35727626+dvdksn@users.noreply.github.com> --- .../docker/buildx/docs/bake-reference.md | 23 +++++++++++++++---- _vendor/modules.txt | 2 +- go.mod | 2 +- go.sum | 2 ++ 4 files changed, 23 insertions(+), 6 deletions(-) diff --git a/_vendor/github.com/docker/buildx/docs/bake-reference.md b/_vendor/github.com/docker/buildx/docs/bake-reference.md index 2c113f8a2c..50cf90f9d0 100644 --- a/_vendor/github.com/docker/buildx/docs/bake-reference.md +++ b/_vendor/github.com/docker/buildx/docs/bake-reference.md @@ -274,13 +274,13 @@ target "db" { ### `target.annotations` -The `annotations` attribute is a shortcut to allow you to easily set a list of -annotations on the target. +The `annotations` attribute lets you add annotations to images built with bake. +The key takes a list of annotations, in the format of `KEY=VALUE`. ```hcl target "default" { output = ["type=image,name=foo"] - annotations = ["key=value"] + annotations = ["org.opencontainers.image.authors=dvdksn"] } ``` @@ -288,10 +288,25 @@ is the same as ```hcl target "default" { - output = ["type=image,name=foo,annotation.key=value"] + output = ["type=image,name=foo,annotation.org.opencontainers.image.authors=dvdksn"] } ``` +By default, the annotation is added to image manifests. You can configure the +level of the annotations by adding a prefix to the annotation, containing a +comma-separated list of all the levels that you want to annotate. The following +example adds annotations to both the image index and manifests. + +```hcl +target "default" { + output = ["type=image,name=foo"] + annotations = ["index,manifest:org.opencontainers.image.authors=dvdksn"] +} +``` + +Read about the supported levels in +[Specifying annotation levels](https://docs.docker.com/build/building/annotations/#specifying-annotation-levels). + ### `target.attest` The `attest` attribute lets you apply [build attestations][attestations] to the target. diff --git a/_vendor/modules.txt b/_vendor/modules.txt index 919841cd6d..28b1be1ea1 100644 --- a/_vendor/modules.txt +++ b/_vendor/modules.txt @@ -1,6 +1,6 @@ # github.com/moby/moby v24.0.5+incompatible # github.com/moby/buildkit v0.13.0-beta1.0.20231113205014-1efcd30d9dd6 -# github.com/docker/buildx v0.12.0 +# github.com/docker/buildx v0.12.1-0.20231214091505-b68ee824c673 # github.com/docker/scout-cli v1.2.0 # github.com/docker/cli v24.0.8-0.20231213094340-0f82fd88610a+incompatible # github.com/compose-spec/compose-spec v0.0.0-20231121152139-478928e7c9f8 diff --git a/go.mod b/go.mod index 67f96a98b4..c8e4b23d48 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ toolchain go1.21.1 require ( github.com/compose-spec/compose-spec v0.0.0-20231121152139-478928e7c9f8 // indirect - github.com/docker/buildx v0.12.0 // indirect + github.com/docker/buildx v0.12.1-0.20231214091505-b68ee824c673 // indirect github.com/docker/cli v24.0.8-0.20231213094340-0f82fd88610a+incompatible // indirect github.com/docker/compose/v2 v2.23.3 // indirect github.com/docker/scout-cli v1.2.0 // indirect diff --git a/go.sum b/go.sum index 4c294c5257..cbd5c8c7af 100644 --- a/go.sum +++ b/go.sum @@ -52,6 +52,8 @@ github.com/docker/buildx v0.11.2 h1:R3p9F0gnI4FwvQ0p40UwdX1T4ugap4UWxY3TFHoP4Ws= github.com/docker/buildx v0.11.2/go.mod h1:CWAABt10iIuGpleypA3103mplDfcGu0A2AvT03xfpTc= github.com/docker/buildx v0.12.0 h1:pI4jr4SeH9oHa0SmMvH/lz+Rdqkg+dRa9H/1VXbYgws= github.com/docker/buildx v0.12.0/go.mod h1:SBLnQH9q+77aVvpvS5LLIly9+nHVlwscl5GEegGMD5g= +github.com/docker/buildx v0.12.1-0.20231214091505-b68ee824c673 h1:mZ2+TyEERNA4GY2xO3kIa7ZhfmUNwveIMxGYWV126dA= +github.com/docker/buildx v0.12.1-0.20231214091505-b68ee824c673/go.mod h1:SBLnQH9q+77aVvpvS5LLIly9+nHVlwscl5GEegGMD5g= github.com/docker/cli v24.0.2+incompatible h1:QdqR7znue1mtkXIJ+ruQMGQhpw2JzMJLRXp6zpzF6tM= github.com/docker/cli v24.0.2+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/cli v24.0.4+incompatible h1:Y3bYF9ekNTm2VFz5U/0BlMdJy73D+Y1iAAZ8l63Ydzw= From 901d7da3fe7d905ad2f33f2becf5deaf68fd948a Mon Sep 17 00:00:00 2001 From: David Karlsson <35727626+dvdksn@users.noreply.github.com> Date: Thu, 14 Dec 2023 10:22:53 +0100 Subject: [PATCH 3/4] build: regenerate buildx cli reference SHA: b68ee824c67342b19c4208dbfef40a3498e17a7b Signed-off-by: David Karlsson <35727626+dvdksn@users.noreply.github.com> --- data/buildx/docker_buildx_build.yaml | 47 +++++++++++++++++++ .../docker_buildx_imagetools_create.yaml | 33 ++++++++++++- 2 files changed, 78 insertions(+), 2 deletions(-) diff --git a/data/buildx/docker_buildx_build.yaml b/data/buildx/docker_buildx_build.yaml index 19918ff662..b9e032dcf7 100644 --- a/data/buildx/docker_buildx_build.yaml +++ b/data/buildx/docker_buildx_build.yaml @@ -39,6 +39,7 @@ options: value_type: stringArray default_value: '[]' description: Add annotation to the image + details_url: '#annotation' deprecated: false hidden: false experimental: false @@ -526,6 +527,52 @@ inherited_options: kubernetes: false swarm: false examples: |- + ### Create annotations (--annotation) {#annotation} + + ```text + --annotation="key=value" + --annotation="[type:]key=value" + ``` + + Add OCI annotations to the image index, manifest, or descriptor. + The following example adds the `foo=bar` annotation to the image manifests: + + ```console + $ docker buildx build -t TAG --annotation "foo=bar" --push . + ``` + + You can optionally add a type prefix to specify the level of the annotation. By + default, the image manifest is annotated. The following example adds the + `foo=bar` annotation the image index instead of the manifests: + + ```console + $ docker buildx build -t TAG --annotation "index:foo=bar" --push . + ``` + + You can specify multiple types, separated by a comma (,) to add the annotation + to multiple image components. The following example adds the `foo=bar` + annotation to image index, descriptors, manifests: + + ```console + $ docker buildx build -t TAG --annotation "index,manifest,manifest-descriptor:foo=bar" --push . + ``` + + You can also specify a platform qualifier in square brackets (`[os/arch]`) in + the type prefix, to apply the annotation to a subset of manifests with the + matching platform. The following example adds the `foo=bar` annotation only to + the manifest with the `linux/amd64` platform: + + ```console + $ docker buildx build -t TAG --annotation "manifest[linux/amd64]:foo=bar" --push . + ``` + + Wildcards are not supported in the platform qualifier; you can't specify a type + prefix like `manifest[linux/*]` to add annotations only to manifests which has + `linux` as the OS platform. + + For more information about annotations, see + [Annotations](/build/building/annotations/). + ### Create attestations (--attest) {#attest} ```text diff --git a/data/buildx/docker_buildx_imagetools_create.yaml b/data/buildx/docker_buildx_imagetools_create.yaml index 4a5104282e..67ec9d5a21 100644 --- a/data/buildx/docker_buildx_imagetools_create.yaml +++ b/data/buildx/docker_buildx_imagetools_create.yaml @@ -13,6 +13,7 @@ options: value_type: stringArray default_value: '[]' description: Add annotation to the image + details_url: '#annotation' deprecated: false hidden: false experimental: false @@ -88,6 +89,34 @@ inherited_options: kubernetes: false swarm: false examples: |- + ### Add annotations to an image (--annotation) {#annotation} + + The `--annotation` flag lets you add annotations the image index, manifest, + and descriptors when creating a new image. + + The following command creates a `foo/bar:latest` image with the + `org.opencontainers.image.authors` annotation on the image index. + + ```console + $ docker buildx imagetools create \ + --annotation "index:org.opencontainers.image.authors=dvdksn" \ + --tag foo/bar:latest \ + foo/bar:alpha foo/bar:beta foo/bar:gamma + ``` + + > **Note** + > + > The `imagetools create` command supports adding annotations to the image + > index and descriptor, using the following type prefixes: + > + > - `index:` + > - `manifest-descriptor:` + > + > It doesn't support annotating manifests or OCI layouts. + + For more information about annotations, see + [Annotations](/build/building/annotations/). + ### Append new sources to an existing manifest list (--append) {#append} Use the `--append` flag to append the new sources to an existing manifest list @@ -103,7 +132,7 @@ examples: |- ### Read source descriptor from a file (-f, --file) {#file} - ``` + ```text -f FILE or --file FILE ``` @@ -124,7 +153,7 @@ examples: |- ### Set reference for new image (-t, --tag) {#tag} - ``` + ```text -t IMAGE or --tag IMAGE ``` From 37b84b1a71d1f541b4910517b2567562d272c124 Mon Sep 17 00:00:00 2001 From: David Karlsson <35727626+dvdksn@users.noreply.github.com> Date: Thu, 14 Dec 2023 10:44:12 +0100 Subject: [PATCH 4/4] vendor: github.com/moby/buildkit a960fe501f00 Signed-off-by: David Karlsson <35727626+dvdksn@users.noreply.github.com> --- .../moby/buildkit/docs/buildkitd.toml.md | 1 + .../frontend/dockerfile/docs/reference.md | 854 ++++++++++-------- _vendor/modules.txt | 4 +- go.mod | 7 +- go.sum | 2 + 5 files changed, 476 insertions(+), 392 deletions(-) diff --git a/_vendor/github.com/moby/buildkit/docs/buildkitd.toml.md b/_vendor/github.com/moby/buildkit/docs/buildkitd.toml.md index 4650852ebf..79d7ed1a77 100644 --- a/_vendor/github.com/moby/buildkit/docs/buildkitd.toml.md +++ b/_vendor/github.com/moby/buildkit/docs/buildkitd.toml.md @@ -109,6 +109,7 @@ insecure-entitlements = [ "network.host", "security.insecure" ] # configure the containerd runtime [worker.containerd.runtime] name = "io.containerd.runc.v2" + path = "/path/to/containerd/runc/shim" options = { BinaryName = "runc" } [[worker.containerd.gcpolicy]] diff --git a/_vendor/github.com/moby/buildkit/frontend/dockerfile/docs/reference.md b/_vendor/github.com/moby/buildkit/frontend/dockerfile/docs/reference.md index 2084db5aed..b474e1716d 100644 --- a/_vendor/github.com/moby/buildkit/frontend/dockerfile/docs/reference.md +++ b/_vendor/github.com/moby/buildkit/frontend/dockerfile/docs/reference.md @@ -1,13 +1,38 @@ # Dockerfile reference Docker can build images automatically by reading the instructions from a -`Dockerfile`. A `Dockerfile` is a text document that contains all the commands a +Dockerfile. A Dockerfile is a text document that contains all the commands a user could call on the command line to assemble an image. This page describes -the commands you can use in a `Dockerfile`. +the commands you can use in a Dockerfile. + +## Overview + +The Dockerfile supports the following instructions: + +| Instruction | Description | +| :------------------------------------- | :---------------------------------------------------------- | +| [`ADD`](#add) | Add local or remote files and directories. | +| [`ARG`](#arg) | Use build-time variables. | +| [`CMD`](#cmd) | Specify default commands. | +| [`COPY`](#copy) | Copy files and directories. | +| [`ENTRYPOINT`](#entrypoint) | Specify default executable. | +| [`ENV`](#env) | Set environment variables. | +| [`EXPOSE`](#expose) | Describe which ports your application is listening on. | +| [`FROM`](#from) | Create a new build stage from a base image. | +| [`HEALTHCHECK`](#healthcheck) | Check a container's health on startup. | +| [`LABEL`](#label) | Add metadata to an image. | +| [`MAINTAINER`](#maintainer-deprecated) | Specify the author of an image. | +| [`ONBUILD`](#onbuild) | Specify instructions for when the image is used in a build. | +| [`RUN`](#run) | Execute build commands. | +| [`SHELL`](#shell) | Set the default shell of an image. | +| [`STOPSIGNAL`](#stopsignal) | Specify the system call signal for exiting a container. | +| [`USER`](#user) | Set user and group ID. | +| [`VOLUME`](#volume) | Create volume mounts. | +| [`WORKDIR`](#workdir) | Change working directory. | ## Format -Here is the format of the `Dockerfile`: +Here is the format of the Dockerfile: ```dockerfile # Comment @@ -17,15 +42,15 @@ INSTRUCTION arguments The instruction is not case-sensitive. However, convention is for them to 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 directives](#parser-directives), [comments](#format), and globally scoped -[ARGs](#arg). The `FROM` instruction specifies the [*Parent -Image*](https://docs.docker.com/glossary/#parent-image) from which you are +[ARGs](#arg). The `FROM` instruction specifies the [parent +image](https://docs.docker.com/glossary/#parent-image) from which you are 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. -Docker treats lines that *begin* with `#` as a comment, unless the line is +BuildKit treats lines that begin with `#` as a comment, unless the line is a valid [parser directive](#parser-directives). A `#` marker anywhere else in a line is treated as an argument. This allows statements like: @@ -34,9 +59,9 @@ else in a line is treated as an argument. This allows statements like: RUN echo 'we are running some # of cool things' ``` -Comment lines are removed before the Dockerfile instructions are executed, which -means that the comment in the following example is not handled by the shell -executing the `echo` command, and both examples below are equivalent: +Comment lines are removed before the Dockerfile instructions are executed. +The comment in the following example is removed before the shell executes +the `echo` command. ```dockerfile RUN echo hello \ @@ -44,12 +69,14 @@ RUN echo hello \ world ``` +The following examples is equivalent. + ```dockerfile RUN echo hello \ world ``` -Line continuation characters are not supported in comments. +Comments don't support line continuation characters. > **Note on whitespace** > @@ -63,15 +90,15 @@ Line continuation characters are not supported in comments. > RUN echo hello > RUN echo world > ``` -> +> > ```dockerfile > # this is a comment-line > RUN echo hello > RUN echo world > ``` -> -> Note however, that whitespace in instruction _arguments_, such as the commands -> following `RUN`, are preserved, so the following example prints ` hello world` +> +> Whitespace in instruction arguments, however, isn't ignored. +> The following example prints ` hello world` > with leading whitespace as specified: > > ```dockerfile @@ -83,21 +110,20 @@ Line continuation characters are not supported in comments. ## Parser directives Parser directives are optional, and affect the way in which subsequent lines -in a `Dockerfile` are handled. Parser directives do not add layers to the build, -and will not be shown as a build step. Parser directives are written as a +in a Dockerfile are handled. Parser directives don't add layers to the build, +and don't show up as build steps. Parser directives are written as a special type of comment in the form `# directive=value`. A single directive may only be used once. -Once a comment, empty line or builder instruction has been processed, Docker +Once a comment, empty line or builder instruction has been processed, BuildKit no longer looks for parser directives. Instead it treats anything formatted -as a parser directive as a comment and does not attempt to validate if it might -be a parser directive. Therefore, all parser directives must be at the very -top of a `Dockerfile`. +as a parser directive as a comment and doesn't attempt to validate if it might +be a parser directive. Therefore, all parser directives must be at the +top of a Dockerfile. -Parser directives are not case-sensitive. However, convention is for them to -be lowercase. Convention is also to include a blank line following any -parser directives. Line continuation characters are not supported in parser -directives. +Parser directives aren't case-sensitive, but they're lowercase by convention. +It's also conventional to include a blank line following any parser directives. +Line continuation characters aren't supported in parser directives. Due to these rules, the following examples are all invalid: @@ -117,14 +143,14 @@ Invalid due to appearing twice: FROM ImageName ``` -Treated as a comment due to appearing after a builder instruction: +Treated as a comment because it appears after a builder instruction: ```dockerfile FROM ImageName # directive=value ``` -Treated as a comment due to appearing after a comment which is not a parser +Treated as a comment because it appears after a comment that isn't a parser directive: ```dockerfile @@ -133,13 +159,13 @@ directive: FROM ImageName ``` -The unknown directive is treated as a comment due to not being recognized. In -addition, the known directive is treated as a comment due to appearing after -a comment which is not a parser directive. +The following `unknowndirective` is treated as a comment because it isn't +recognized. The known `syntax` directive is treated as a comment because it +appears after a comment that isn't a parser directive. ```dockerfile # unknowndirective=value -# knowndirective=value +# syntax=value ``` Non line-breaking whitespace is permitted in a parser directive. Hence, the @@ -171,34 +197,34 @@ page for more information. ### escape ```dockerfile -# escape=\ (backslash) +# escape=\ ``` Or ```dockerfile -# escape=` (backtick) +# escape=` ``` The `escape` directive sets the character used to escape characters in a -`Dockerfile`. If not specified, the default escape character is `\`. +Dockerfile. If not specified, the default escape character is `\`. The escape character is used both to escape characters in a line, and to -escape a newline. This allows a `Dockerfile` instruction to +escape a newline. This allows a Dockerfile instruction to span multiple lines. Note that regardless of whether the `escape` parser -directive is included in a `Dockerfile`, *escaping is not performed in -a `RUN` command, except at the end of a line.* +directive is included in a Dockerfile, escaping is not performed in +a `RUN` command, except at the end of a line. Setting the escape character to `` ` `` is especially useful on `Windows`, where `\` is the directory path separator. `` ` `` is consistent with [Windows PowerShell](https://technet.microsoft.com/en-us/library/hh847755.aspx). Consider the following example which would fail in a non-obvious way on -`Windows`. The second `\` at the end of the second line would be interpreted as an +Windows. The second `\` at the end of the second line would be interpreted as an escape for the newline, instead of a target of the escape from the first `\`. Similarly, the `\` at the end of the third line would, assuming it was actually handled as an instruction, cause it be treated as a line continuation. The result -of this dockerfile is that second and third lines are considered a single +of this Dockerfile is that second and third lines are considered a single instruction: ```dockerfile @@ -222,11 +248,11 @@ PS E:\myproject> One solution to the above would be to use `/` as the target of both the `COPY` instruction, and `dir`. However, this syntax is, at best, confusing as it is not -natural for paths on `Windows`, and at worst, error prone as not all commands on -`Windows` support `/` as the path separator. +natural for paths on Windows, and at worst, error prone as not all commands on +Windows support `/` as the path separator. -By adding the `escape` parser directive, the following `Dockerfile` succeeds as -expected with the use of natural platform semantics for file paths on `Windows`: +By adding the `escape` parser directive, the following Dockerfile succeeds as +expected with the use of natural platform semantics for file paths on Windows: ```dockerfile # escape=` @@ -272,10 +298,10 @@ PS E:\myproject> Environment variables (declared with [the `ENV` statement](#env)) can also be used in certain instructions as variables to be interpreted by the -`Dockerfile`. Escapes are also handled for including variable-like syntax +Dockerfile. Escapes are also handled for including variable-like syntax into a statement literally. -Environment variables are notated in the `Dockerfile` either with +Environment variables are notated in the Dockerfile either with `$variable_name` or `${variable_name}`. They are treated equivalently and the brace syntax is typically used to address issues with variable names with no whitespace, like `${foo}_bar`. @@ -288,10 +314,46 @@ modifiers as specified below: - `${variable:+word}` indicates that if `variable` is set then `word` will be the result, otherwise the result is the empty string. +The following variable replacements are supported in a pre-release version of +Dockerfile syntax, when using the `# syntax=docker/dockerfile-upstream:master` syntax +directive in your Dockerfile: + +- `${variable#pattern}` removes the shortest match of `pattern` from `variable`, + seeking from the start of the string. + + ```bash + str=foobarbaz echo ${str#f*b} # arbaz + ``` + +- `${variable##pattern}` removes the longest match of `pattern` from `variable`, + seeking from the start of the string. + + ```bash + str=foobarbaz echo ${str##f*b} # az + ``` + +- `${variable%pattern}` removes the shortest match of `pattern` from `variable`, + seeking backwards from the end of the string. + + ```bash + string=foobarbaz echo ${string%b*} # foobar + ``` + +- `${variable%%pattern}` removes the longest match of `pattern` from `variable`, + seeking backwards from the end of the string. + + ```bash + string=foobarbaz echo ${string%%b*} # foo + ``` + In all cases, `word` can be any string, including additional environment variables. -Escaping is possible by adding a `\` before the variable: `\$foo` or `\${foo}`, +`pattern` is a glob pattern where `?` matches any single character +and `*` any number of characters (including zero). To match literal `?` and `*`, +use a backslash escape: `\?` and `\*`. + +You can escape whole variable names by adding a `\` before the variable: `\$foo` or `\${foo}`, for example, will translate to `$foo` and `${foo}` literals respectively. Example (parsed representation is displayed after the `#`): @@ -305,7 +367,7 @@ COPY \$FOO /quux # COPY $FOO /quux ``` Environment variables are supported by the following list of instructions in -the `Dockerfile`: +the Dockerfile: - `ADD` - `COPY` @@ -319,8 +381,15 @@ the `Dockerfile`: - `WORKDIR` - `ONBUILD` (when combined with one of the supported instructions above) -Environment variable substitution will use the same value for each variable -throughout the entire instruction. In other words, in this example: +You can also use environment variables with `RUN`, `CMD`, and `ENTRYPOINT` +instructions, but in those cases the variable substitution is handled by the +command shell, not the builder. Note that instructions using the exec form +don't invoke a command shell automatically. See [Variable +substitution](#variable-substitution). + +Environment variable substitution use the same value for each variable +throughout the entire instruction. Changing the value of a variable only takes +effect in subsequent instructions. Consider the following example: ```dockerfile ENV abc=hello @@ -328,15 +397,116 @@ ENV abc=bye def=$abc ENV ghi=$abc ``` -will result in `def` having a value of `hello`, not `bye`. However, -`ghi` will have a value of `bye` because it is not part of the same instruction -that set `abc` to `bye`. +- The value of `def` becomes `hello` +- The value of `ghi` becomes `bye` ## .dockerignore file You can use `.dockerignore` file to exclude files and directories from the build context. For more information, see -[.dockerignore file](https://docs.docker.com/build/building/context#dockerignore-files/). +[.dockerignore file](https://docs.docker.com/build/building/context/#dockerignore-files). + +## Shell and exec form + +The `RUN`, `CMD`, and `ENTRYPOINT` instructions all have two possible forms: + +- `INSTRUCTION ["executable","param1","param2"]` (exec form) +- `INSTRUCTION command param1 param2` (shell form) + +The exec form makes it possible to avoid shell string munging, and to invoke +commands using a specific command shell, or any other executable. It uses a +JSON array syntax, where each element in the array is a command, flag, or +argument. + +The shell form is more relaxed, and emphasizes ease of use, flexibility, and +readability. The shell form automatically uses a command shell, whereas the +exec form does not. + +### Exec form + +The exec form is parsed as a JSON array, which means that +you must use double-quotes (") around words, not single-quotes ('). + +```dockerfile +ENTRYPOINT ["/bin/bash", "-c", "echo", "hello"] +``` + +The exec form is best used to specify an `ENTRYPOINT` instruction, combined +with `CMD` for setting default arguments that can be overridden at runtime. For +more information, see [ENTRYPOINT](#entrypoint). + +#### Variable substitution + +Using the exec form doesn't automatically invoke a command shell. This means +that normal shell processing, such as variable substitution, doesn't happen. +For example, `RUN [ "echo", "$HOME" ]` won't handle variable substitution for +`$HOME`. + +If you want shell processing then either use the shell form or execute a shell +directly with the exec form, for example: `RUN [ "sh", "-c", "echo $HOME" ]`. +When using the exec form and executing a shell directly, as in the case for the +shell form, it's the shell that's doing the environment variable substitution, +not the builder. + +#### Backslashes + +In exec form, you must escape backslashes. This is particularly relevant on +Windows where the backslash is the path separator. The following line would +otherwise be treated as shell form due to not being valid JSON, and fail in an +unexpected way: + +```dockerfile +RUN ["c:\windows\system32\tasklist.exe"] +``` + +The correct syntax for this example is: + +```dockerfile +RUN ["c:\\windows\\system32\\tasklist.exe"] +``` + +### Shell form + +Unlike the exec form, instructions using the shell form always use a command +shell. The shell form doesn't use the JSON array format, instead it's a regular +string. The shell form string lets you escape newlines using the [escape +character](#escape) (backslash by default) to continue a single instruction +onto the next line. This makes it easier to use with longer commands, because +it lets you split them up into multiple lines. For example, consider these two +lines: + +```dockerfile +RUN source $HOME/.bashrc && \ +echo $HOME +``` + +They're equivalent to the following line: + +```dockerfile +RUN source $HOME/.bashrc && echo $HOME +``` + +You can also use heredocs with the shell form to break up a command: + +```dockerfile +RUN <] [@] [AS ] ``` The `FROM` instruction initializes a new build stage and sets the -[*Base Image*](https://docs.docker.com/glossary/#base-image) for subsequent instructions. As such, a -valid `Dockerfile` must start with a `FROM` instruction. The image can be -any valid image – it is especially easy to start by **pulling an image** from -the [*Public Repositories*](https://docs.docker.com/docker-hub/repos/). +[base image](https://docs.docker.com/glossary/#base-image) for subsequent +instructions. As such, a valid Dockerfile must start with a `FROM` instruction. +The image can be any valid image. -- `ARG` is the only instruction that may precede `FROM` in the `Dockerfile`. +- `ARG` is the only instruction that may precede `FROM` in the Dockerfile. See [Understand how ARG and FROM interact](#understand-how-arg-and-from-interact). -- `FROM` can appear multiple times within a single `Dockerfile` to +- `FROM` can appear multiple times within a single Dockerfile to create multiple images or use one build stage as a dependency for another. Simply make a note of the last image ID output by the commit before each new `FROM` instruction. Each `FROM` instruction clears any state created by previous @@ -374,7 +543,7 @@ the [*Public Repositories*](https://docs.docker.com/docker-hub/repos/). `COPY --from=` instructions to refer to the image built in this stage. - The `tag` or `digest` values are optional. If you omit either of them, the builder assumes a `latest` tag by default. The builder returns an error if it - cannot find the `tag` value. + can't find the `tag` value. The optional `--platform` flag can be used to specify the platform of the image in case `FROM` references a multi-platform image. For example, `linux/amd64`, @@ -412,77 +581,32 @@ RUN echo $VERSION > image_version ## RUN -RUN has 2 forms: - -- `RUN ` (*shell* form, the command is run in a shell, which by -default is `/bin/sh -c` on Linux or `cmd /S /C` on Windows) -- `RUN ["executable", "param1", "param2"]` (*exec* form) - -The `RUN` instruction will execute any commands in a new layer on top of the -current image and commit the results. The resulting committed image will be -used for the next step in the `Dockerfile`. - -Layering `RUN` instructions and generating commits conforms to the core -concepts of Docker where commits are cheap and containers can be created from -any point in an image's history, much like source control. - -The *exec* form makes it possible to avoid shell string munging, and to `RUN` -commands using a base image that does not contain the specified shell executable. - -The default shell for the *shell* form can be changed using the `SHELL` -command. - -In the *shell* form you can use a `\` (backslash) to continue a single -RUN instruction onto the next line. For example, consider these two lines: +The `RUN` instruction will execute any commands to create a new layer on top of +the current image. The added layer is used in the next step in the Dockerfile. ```dockerfile -RUN /bin/bash -c 'source $HOME/.bashrc && \ -echo $HOME' +RUN apt-get update +RUN apt-get install -y curl ``` -Together they are equivalent to this single line: +You can specify `CMD` instructions using +[shell or exec forms](#shell-and-exec-form): + +- `RUN ["executable","param1","param2"]` (exec form) +- `RUN command param1 param2` (shell form) + +The shell form is most commonly used, and lets you more easily break up longer +instructions into multiple lines, either using newline [escapes](#escape), or +with [heredocs](#here-documents): ```dockerfile -RUN /bin/bash -c 'source $HOME/.bashrc && echo $HOME' +RUN < **Note** -> -> The *exec* form is parsed as a JSON array, which means that -> you must use double-quotes (") around words not single-quotes ('). - -Unlike the *shell* form, the *exec* form does not invoke a command shell. -This means that normal shell processing does not happen. For example, -`RUN [ "echo", "$HOME" ]` will not do variable substitution on `$HOME`. -If you want shell processing then either use the *shell* form or execute -a shell directly, for example: `RUN [ "sh", "-c", "echo $HOME" ]`. -When using the exec form and executing a shell directly, as in the case for -the shell form, it is the shell that is doing the environment variable -expansion, not docker. - -> **Note** -> -> In the *JSON* form, it is necessary to escape backslashes. This is -> particularly relevant on Windows where the backslash is the path separator. -> The following line would otherwise be treated as *shell* form due to not -> being valid JSON, and fail in an unexpected way: -> -> ```dockerfile -> RUN ["c:\windows\system32\tasklist.exe"] -> ``` -> -> The correct syntax for this example is: -> -> ```dockerfile -> RUN ["c:\\windows\\system32\\tasklist.exe"] -> ``` +### Cache invalidation for RUN instructions The cache for `RUN` instructions isn't invalidated automatically during the next build. The cache for an instruction like @@ -490,7 +614,7 @@ the next build. The cache for an instruction like cache for `RUN` instructions can be invalidated by using the `--no-cache` flag, for example `docker build --no-cache`. -See the [`Dockerfile` Best Practices +See the [Dockerfile Best Practices guide](https://docs.docker.com/engine/userguide/eng-image/dockerfile_best-practices/) for more information. The cache for `RUN` instructions can be invalidated by [`ADD`](#add) and [`COPY`](#copy) instructions. @@ -513,9 +637,9 @@ Syntax: `--mount=[type=][,option=[,option=]...]` ### Mount types | Type | Description | -|------------------------------------------|-----------------------------------------------------------------------------------------------------------| +| ---------------------------------------- | --------------------------------------------------------------------------------------------------------- | | [`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. | | [`secret`](#run---mounttypesecret) | Allow the build container to access secure files such as private keys without baking them into the image. | | [`ssh`](#run---mounttypessh) | Allow the build container to access SSH keys via SSH agents, with support for passphrases. | @@ -524,29 +648,29 @@ Syntax: `--mount=[type=][,option=[,option=]...]` This mount type allows binding files or directories to the build container. A bind mount is read-only by default. -| Option | Description | -|----------------------|--------------------------------------------------------------------------------------| -| `target`[^1] | Mount path. | -| `source` | Source path in the `from`. Defaults to the root of the `from`. | -| `from` | Build stage or image name for the root of the source. Defaults to the build context. | -| `rw`,`readwrite` | Allow writes on the mount. Written data will be discarded. | +| Option | Description | +| ---------------- | ------------------------------------------------------------------------------------ | +| `target`[^1] | Mount path. | +| `source` | Source path in the `from`. Defaults to the root of the `from`. | +| `from` | Build stage or image name for the root of the source. Defaults to the build context. | +| `rw`,`readwrite` | Allow writes on the mount. Written data will be discarded. | ### RUN --mount=type=cache This mount type allows the build container to cache directories for compilers and package managers. -| Option | Description | -|---------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `id` | Optional ID to identify separate/different caches. Defaults to value of `target`. | -| `target`[^1] | Mount path. | -| `ro`,`readonly` | Read-only if set. | -| `sharing` | One of `shared`, `private`, or `locked`. Defaults to `shared`. A `shared` cache mount can be used concurrently by multiple writers. `private` creates a new mount if there are multiple writers. `locked` pauses the second writer until the first one releases the mount. | -| `from` | Build stage to use as a base of the cache mount. Defaults to empty directory. | -| `source` | Subpath in the `from` to mount. Defaults to the root of the `from`. | -| `mode` | File mode for new cache directory in octal. Default `0755`. | -| `uid` | User ID for new cache directory. Default `0`. | -| `gid` | Group ID for new cache directory. Default `0`. | +| Option | Description | +| --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `id` | Optional ID to identify separate/different caches. Defaults to value of `target`. | +| `target`[^1] | Mount path. | +| `ro`,`readonly` | Read-only if set. | +| `sharing` | One of `shared`, `private`, or `locked`. Defaults to `shared`. A `shared` cache mount can be used concurrently by multiple writers. `private` creates a new mount if there are multiple writers. `locked` pauses the second writer until the first one releases the mount. | +| `from` | Build stage to use as a base of the cache mount. Defaults to empty directory. | +| `source` | Subpath in the `from` to mount. Defaults to the root of the `from`. | +| `mode` | File mode for new cache directory in octal. Default `0755`. | +| `uid` | User ID for new cache directory. Default `0`. | +| `gid` | Group ID for new cache directory. Default `0`. | Contents of the cache directories persists between builder invocations without invalidating the instruction cache. Cache mounts should only be used for better @@ -583,26 +707,26 @@ case. ### RUN --mount=type=tmpfs -This mount type allows mounting tmpfs in the build container. +This mount type allows mounting `tmpfs` in the build container. -| Option | Description | -|---------------------|-------------------------------------------------------| -| `target`[^1] | Mount path. | -| `size` | Specify an upper limit on the size of the filesystem. | +| Option | Description | +| ------------ | ----------------------------------------------------- | +| `target`[^1] | Mount path. | +| `size` | Specify an upper limit on the size of the filesystem. | ### RUN --mount=type=secret This mount type allows the build container to access secure files such as private keys without baking them into the image. -| Option | Description | -|---------------------|---------------------------------------------------------------------------------------------------| -| `id` | ID of the secret. Defaults to basename of the target path. | -| `target` | Mount path. Defaults to `/run/secrets/` + `id`. | -| `required` | If set to `true`, the instruction errors out when the secret is unavailable. Defaults to `false`. | -| `mode` | File mode for secret file in octal. Default `0400`. | -| `uid` | User ID for secret file. Default `0`. | -| `gid` | Group ID for secret file. Default `0`. | +| Option | Description | +| ---------- | ------------------------------------------------------------------------------------------------- | +| `id` | ID of the secret. Defaults to basename of the target path. | +| `target` | Mount path. Defaults to `/run/secrets/` + `id`. | +| `required` | If set to `true`, the instruction errors out when the secret is unavailable. Defaults to `false`. | +| `mode` | File mode for secret file in octal. Default `0400`. | +| `uid` | User ID for secret file. Default `0`. | +| `gid` | Group ID for secret file. Default `0`. | #### Example: access to S3 @@ -623,14 +747,14 @@ $ docker buildx build --secret id=aws,src=$HOME/.aws/credentials . This mount type allows the build container to access SSH keys via SSH agents, with support for passphrases. -| Option | Description | -|---------------------|------------------------------------------------------------------------------------------------| -| `id` | ID of SSH agent socket or key. Defaults to "default". | -| `target` | 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`. | -| `mode` | File mode for socket in octal. Default `0600`. | -| `uid` | User ID for socket. Default `0`. | -| `gid` | Group ID for socket. Default `0`. | +| Option | Description | +| ---------- | ---------------------------------------------------------------------------------------------- | +| `id` | ID of SSH agent socket or key. Defaults to "default". | +| `target` | 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`. | +| `mode` | File mode for socket in octal. Default `0600`. | +| `uid` | User ID for socket. Default `0`. | +| `gid` | Group ID for socket. Default `0`. | #### Example: access to Gitlab @@ -669,7 +793,7 @@ Syntax: `--network=` ### Network types | Type | Description | -|----------------------------------------------|----------------------------------------| +| -------------------------------------------- | -------------------------------------- | | [`default`](#run---networkdefault) (default) | Run in the default network. | | [`none`](#run---networknone) | Run with no network access. | | [`host`](#run---networkhost) | Run in the host's network environment. | @@ -703,7 +827,7 @@ The command is run in the host's network environment (similar to > **Warning** > -> The use of `--network=host` is protected by the `network.host` entitlement, +> The use of `--network=host` is protected by the `network.host` entitlement, > which needs to be enabled when starting the buildkitd daemon with > `--allow-insecure-entitlement network.host` flag or in [buildkitd config](https://github.com/moby/buildkit/blob/master/docs/buildkitd.toml.md), > and for a build request with [`--allow network.host` flag](https://docs.docker.com/engine/reference/commandline/buildx_build/#allow). @@ -736,6 +860,7 @@ This is equivalent to running `docker run --privileged`. FROM ubuntu RUN --security=insecure cat /proc/self/status | grep CapEff ``` + ```text #84 0.093 CapEff: 0000003fffffffff ``` @@ -746,70 +871,37 @@ Default sandbox mode can be activated via `--security=sandbox`, but that is no-o ## CMD -The `CMD` instruction has three forms: +The `CMD` instruction sets the command to be executed when running a container +from an image. -- `CMD ["executable","param1","param2"]` (*exec* form, this is the preferred form) -- `CMD ["param1","param2"]` (as *default parameters to ENTRYPOINT*) -- `CMD command param1 param2` (*shell* form) +You can specify `CMD` instructions using +[shell or exec forms](#shell-and-exec-form): -There can only be one `CMD` instruction in a `Dockerfile`. If you list more than one `CMD` -then only the last `CMD` will take effect. +- `CMD ["executable","param1","param2"]` (exec form) +- `CMD ["param1","param2"]` (exec form, as default parameters to `ENTRYPOINT`) +- `CMD command param1 param2` (shell form) -**The main purpose of a `CMD` is to provide defaults for an executing -container.** These defaults can include an executable, or they can omit -the executable, in which case you must specify an `ENTRYPOINT` -instruction as well. +There can only be one `CMD` instruction in a Dockerfile. If you list more than +one `CMD`, only the last one takes effect. -If `CMD` is used to provide default arguments for the `ENTRYPOINT` instruction, -both the `CMD` and `ENTRYPOINT` instructions should be specified with the JSON -array format. - -> **Note** -> -> The *exec* form is parsed as a JSON array, which means that you must use -> double-quotes (") around words not single-quotes ('). - -Unlike the *shell* form, the *exec* form does not invoke a command shell. -This means that normal shell processing does not happen. For example, -`CMD [ "echo", "$HOME" ]` will not do variable substitution on `$HOME`. -If you want shell processing then either use the *shell* form or execute -a shell directly, for example: `CMD [ "sh", "-c", "echo $HOME" ]`. -When using the exec form and executing a shell directly, as in the case for -the shell form, it is the shell that is doing the environment variable -expansion, not docker. - -When used in the shell or exec formats, the `CMD` instruction sets the command -to be executed when running the image. - -If you use the *shell* form of the `CMD`, then the `` will execute in -`/bin/sh -c`: - -```dockerfile -FROM ubuntu -CMD echo "This is a test." | wc - -``` - -If you want to **run your** `` **without a shell** then you must -express the command as a JSON array and give the full path to the executable. -**This array form is the preferred format of `CMD`.** Any additional parameters -must be individually expressed as strings in the array: - -```dockerfile -FROM ubuntu -CMD ["/usr/bin/wc","--help"] -``` +The purpose of a `CMD` is to provide defaults for an executing container. These +defaults can include an executable, or they can omit the executable, in which +case you must specify an `ENTRYPOINT` instruction as well. If you would like your container to run the same executable every time, then you should consider using `ENTRYPOINT` in combination with `CMD`. See -[*ENTRYPOINT*](#entrypoint). +[`ENTRYPOINT`](#entrypoint). If the user specifies arguments to `docker run` +then they will override the default specified in `CMD`, but still use the +default `ENTRYPOINT`. -If the user specifies arguments to `docker run` then they will override the -default specified in `CMD`. +If `CMD` is used to provide default arguments for the `ENTRYPOINT` instruction, +both the `CMD` and `ENTRYPOINT` instructions should be specified in the +[exec form](#exec-form). > **Note** > -> Do not confuse `RUN` with `CMD`. `RUN` actually runs a command and commits -> the result; `CMD` does not execute anything at build time, but specifies +> Don't confuse `RUN` with `CMD`. `RUN` actually runs a command and commits +> the result; `CMD` doesn't execute anything at build time, but specifies > the intended command for the image. ## LABEL @@ -846,7 +938,7 @@ LABEL multi.label1="value1" \ ``` > **Note** -> +> > Be sure to use double quotes and not single quotes. Particularly when you are > using string interpolation (e.g. `LABEL example="foo-$ENV_VAR"`), single > quotes will take the string as is without unpacking the variable's value. @@ -857,12 +949,10 @@ the most-recently-applied value overrides any previously-set value. To view an image's labels, use the `docker image inspect` command. You can use the `--format` option to show just the labels; - -{% raw %} + ```console $ docker image inspect --format='{{json .Config.Labels}}' myimage ``` -{% endraw %} ```json { @@ -882,7 +972,7 @@ $ docker image inspect --format='{{json .Config.Labels}}' myimage MAINTAINER ``` -The `MAINTAINER` instruction sets the *Author* field of the generated images. +The `MAINTAINER` instruction sets the _Author_ field of the generated images. The `LABEL` instruction is a much more flexible version of this and you should use it instead, as it enables setting any metadata you require, and can be viewed easily, for example with `docker inspect`. To set a label corresponding to the @@ -902,11 +992,11 @@ EXPOSE [/...] The `EXPOSE` instruction informs Docker that the container listens on the specified network ports at runtime. You can specify whether the port listens on -TCP or UDP, and the default is TCP if the protocol is not specified. +TCP or UDP, and the default is TCP if you don't specify a protocol. -The `EXPOSE` instruction does not actually publish the port. It functions as a +The `EXPOSE` instruction doesn't actually publish the port. It functions as a type of documentation between the person who builds the image and the person who -runs the container, about which ports are intended to be published. To actually +runs the container, about which ports are intended to be published. To publish the port when running the container, use the `-p` flag on `docker run` to publish and map one or more ports, or the `-P` flag to publish all exposed ports and map them to high-order ports. @@ -926,7 +1016,7 @@ EXPOSE 80/udp In this case, if you use `-P` with `docker run`, the port will be exposed once for TCP and once for UDP. Remember that `-P` uses an ephemeral high-ordered host -port on the host, so the port will not be the same for TCP and UDP. +port on the host, so TCP and UDP doesn't use the same port. Regardless of the `EXPOSE` settings, you can override them at runtime by using the `-p` flag. For example @@ -990,7 +1080,7 @@ image, consider setting a value for a single command instead: ```dockerfile RUN DEBIAN_FRONTEND=noninteractive apt-get update && apt-get install -y ... ``` - + Or using [`ARG`](#arg), which is not persisted in the final image: ```dockerfile @@ -1006,7 +1096,7 @@ RUN apt-get update && apt-get install -y ... > ```dockerfile > ENV MY_VAR my-value > ``` -> +> > This syntax does not allow for multiple environment-variables to be set in a > single `ENV` instruction, and can be confusing. For example, the following > sets a single environment variable (`ONE`) with value `"TWO= THREE=world"`: @@ -1014,7 +1104,7 @@ RUN apt-get update && apt-get install -y ... > ```dockerfile > ENV ONE TWO= THREE=world > ``` -> +> > The alternative syntax is supported for backward compatibility, but discouraged > for the reasons outlined above, and may be removed in a future release. @@ -1032,7 +1122,7 @@ The latter form is required for paths containing whitespace. > **Note** > > The `--chown` and `--chmod` features are only supported on Dockerfiles used to build Linux containers, -> and will not work on Windows containers. Since user and group ownership concepts do +> and doesn't work on Windows containers. Since user and group ownership concepts do > not translate between Linux and Windows, the use of `/etc/passwd` and `/etc/group` for > translating user and group names to IDs restricts this feature to only be viable > for Linux OS-based containers. @@ -1089,7 +1179,6 @@ named `arr[0].txt`, use the following; ADD arr[[]0].txt /mydir/ ``` - All new files and directories are created with a UID and GID of 0, unless the optional `--chown` flag specifies a given username, groupname, or UID/GID combination to request specific ownership of the content added. The @@ -1109,84 +1198,83 @@ ADD --chown=10:11 files* /somedir/ ADD --chown=myuser:mygroup --chmod=655 files* /somedir/ ``` -If the container root filesystem does not contain either `/etc/passwd` or +If the container root filesystem doesn't contain either `/etc/passwd` or `/etc/group` files and either user or group names are used in the `--chown` flag, the build will fail on the `ADD` operation. Using numeric IDs requires -no lookup and will not depend on container root filesystem content. +no lookup and doesn't depend on container root filesystem content. In the case where `` 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` will not be included in the determination +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. > **Note** > -> If you build by passing a `Dockerfile` through STDIN (`docker -> build - < somefile`), there is no build context, so the `Dockerfile` +> 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 +> the Dockerfile at the root of the archive and the rest of the > archive will be used as the context of the build. 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 -does not support authentication. +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 `` 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) +> 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. - `ADD` obeys the following rules: -- The `` path must be inside the *context* of the build; - you cannot `ADD ../something /something`, because the first step of a - `docker build` is to send the context directory (and subdirectories) to the - docker daemon. +- The `` path must be inside the build context; + you can't use `COPY ../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. -- If `` is a URL and `` does not end with a trailing slash, then a - file is downloaded from the URL and copied to ``. +- If `` is a directory, the entire contents of the directory are copied, + including filesystem metadata. - If `` is a URL and `` does end with a trailing slash, then the filename is inferred from the URL and the file is downloaded to `/`. 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` - will not work). + doesn't work). - If `` is a directory, the entire contents of the directory are copied, including filesystem metadata. -> **Note** -> -> The directory itself is not copied, just its contents. + > **Note** + > + > The directory itself isn't copied, only its contents. -- If `` is a *local* tar archive in a recognized compression format - (identity, gzip, bzip2 or xz) then it is unpacked as a directory. Resources - from *remote* URLs are **not** decompressed. When a directory is copied or - unpacked, it has the same behavior as `tar -x`, the result is the union of: +- If `` 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: - 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. + 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 will not - > be recognized as a compressed file and **will not** generate any kind of + > 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 `` is any other kind of file, it is copied individually along with +- If `` is any other kind of file, it's copied individually along with its metadata. In this case, if `` ends with a trailing slash `/`, it will be considered a directory and the contents of `` will be written at `/base()`. @@ -1195,10 +1283,10 @@ guide – Leverage build cache](https://docs.docker.com/develop/develop-images/d use of a wildcard, then `` must be a directory, and it must end with a slash `/`. -- If `` does not end with a trailing slash, it will be considered a +- If `` doesn't end with a trailing slash, it will be considered a regular file and the contents of `` will be written at ``. -- If `` doesn't exist, it is created along with all missing directories +- If `` doesn't exist, it's created, along with all missing directories in its path. ### Verifying a remote file checksum `ADD --checksum= ` @@ -1211,10 +1299,11 @@ ADD --checksum=sha256:24454f830cdb571e2c4ad15481119c43b3cafd48dd869a9b2945d1036d The `--checksum` flag only supports HTTP sources currently. -### Adding a git repository `ADD ` +### Adding a Git repository `ADD ` -This form allows adding a git repository to an image directly, without using the `git` command inside the image: -``` +This form allows adding a Git repository to an image directly, without using the `git` command inside the image: + +```dockerfile ADD [--keep-git-dir=] ``` @@ -1264,7 +1353,7 @@ This latter form is required for paths containing whitespace > **Note** > > The `--chown` and `--chmod` features are only supported on Dockerfiles used to build Linux containers, -> and will not work on Windows containers. Since user and group ownership concepts do +> and doesn't work on Windows containers. Since user and group ownership concepts do > not translate between Linux and Windows, the use of `/etc/passwd` and `/etc/group` for > translating user and group names to IDs restricts this feature to only be viable for > Linux OS-based containers. @@ -1334,7 +1423,7 @@ COPY --chown=10:11 files* /somedir/ COPY --chown=myuser:mygroup --chmod=644 files* /somedir/ ``` -If the container root filesystem does not contain either `/etc/passwd` or +If the container root filesystem doesn't contain either `/etc/passwd` or `/etc/group` files and either user or group names are used in the `--chown` flag, the build will fail on the `COPY` operation. Using numeric IDs requires no lookup and does not depend on container root filesystem content. @@ -1352,19 +1441,19 @@ attempted to be used instead. `COPY` obeys the following rules: -- The `` path must be inside the *context* of the build; - you cannot `COPY ../something /something`, because the first step of a - `docker build` is to send the context directory (and subdirectories) to the - docker daemon. +- The `` path must be inside the build context; + you can't use `COPY ../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. - If `` is a directory, the entire contents of the directory are copied, including filesystem metadata. -> **Note** -> -> The directory itself is not copied, just its contents. + > **Note** + > + > The directory itself isn't copied, only its contents. -- If `` is any other kind of file, it is copied individually along with +- If `` is any other kind of file, it's copied individually along with its metadata. In this case, if `` ends with a trailing slash `/`, it will be considered a directory and the contents of `` will be written at `/base()`. @@ -1373,19 +1462,19 @@ attempted to be used instead. use of a wildcard, then `` must be a directory, and it must end with a slash `/`. -- If `` does not end with a trailing slash, it will be considered a +- If `` doesn't end with a trailing slash, it will be considered a regular file and the contents of `` will be written at ``. -- If `` doesn't exist, it is created along with all missing directories +- If `` 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 `` 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) +> 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. ## COPY --link @@ -1457,7 +1546,6 @@ path, using `--link` is always recommended. The performance of `--link` is equivalent or better than the default behavior and, it creates much better conditions for cache reuse. - ## COPY --parents > **Note** @@ -1499,49 +1587,50 @@ with the `--parents` flag, the Buildkit is capable of packing multiple ## ENTRYPOINT -ENTRYPOINT has two forms: - -The *exec* form, which is the preferred form: - -```dockerfile -ENTRYPOINT ["executable", "param1", "param2"] -``` - -The *shell* form: - -```dockerfile -ENTRYPOINT command param1 param2 -``` - An `ENTRYPOINT` allows you to configure a container that will run as an executable. -For example, the following starts nginx with its default content, listening -on port 80: +`ENTRYPOINT` has two possible forms: + +- The exec form, which is the preferred form: + + ```dockerfile + ENTRYPOINT ["executable", "param1", "param2"] + ``` + +- The shell form: + + ```dockerfile + ENTRYPOINT command param1 param2 + ``` + +For more information about the different forms, see [Shell and exec form](#shell-and-exec-form). + +The following command starts a container from the `nginx` with its default +content, listening on port 80: ```console $ docker run -i -t --rm -p 80:80 nginx ``` Command line arguments to `docker run ` will be appended after all -elements in an *exec* form `ENTRYPOINT`, and will override all elements specified +elements in an exec form `ENTRYPOINT`, and will override all elements specified using `CMD`. -This allows arguments to be passed to the entry point, i.e., `docker run -d` -will pass the `-d` argument to the entry point. -You can override the `ENTRYPOINT` instruction using the `docker run --entrypoint` -flag. -The *shell* form prevents any `CMD` or `run` command line arguments from being -used, but has the disadvantage that your `ENTRYPOINT` will be started as a -subcommand of `/bin/sh -c`, which does not pass signals. -This means that the executable will not be the container's `PID 1` - and -will _not_ receive Unix signals - so your executable will not receive a -`SIGTERM` from `docker stop `. +This allows arguments to be passed to the entry point, i.e., `docker run + -d` will pass the `-d` argument to the entry point. You can override +the `ENTRYPOINT` instruction using the `docker run --entrypoint` flag. -Only the last `ENTRYPOINT` instruction in the `Dockerfile` will have an effect. +The shell form of `ENTRYPOINT` prevents any `CMD` command line arguments from +being used. It also starts your `ENTRYPOINT` as a subcommand of `/bin/sh -c`, +which does not pass signals. This means that the executable will not be the +container's `PID 1`, and will not receive Unix signals. In this case, your +executable doesn't receive a `SIGTERM` from `docker stop `. + +Only the last `ENTRYPOINT` instruction in the Dockerfile will have an effect. ### Exec form ENTRYPOINT example -You can use the *exec* form of `ENTRYPOINT` to set fairly stable default commands +You can use the exec form of `ENTRYPOINT` to set fairly stable default commands and arguments and then use either form of `CMD` to set additional defaults that are more likely to be changed. @@ -1578,7 +1667,7 @@ root 7 0.0 0.1 15572 2164 ? R+ 08:25 0:00 ps aux And you can gracefully request `top` to shut down using `docker stop test`. -The following `Dockerfile` shows using the `ENTRYPOINT` to run Apache in the +The following Dockerfile shows using the `ENTRYPOINT` to run Apache in the foreground (i.e., as `PID 1`): ```dockerfile @@ -1669,21 +1758,7 @@ sys 0m 0.03s > **Note** > > You can override the `ENTRYPOINT` setting using `--entrypoint`, -> but this can only set the binary to *exec* (no `sh -c` will be used). - -> **Note** -> -> The *exec* form is parsed as a JSON array, which means that -> you must use double-quotes (") around words not single-quotes ('). - -Unlike the *shell* form, the *exec* form does not invoke a command shell. -This means that normal shell processing does not happen. For example, -`ENTRYPOINT [ "echo", "$HOME" ]` will not do variable substitution on `$HOME`. -If you want shell processing then either use the *shell* form or execute -a shell directly, for example: `ENTRYPOINT [ "sh", "-c", "echo $HOME" ]`. -When using the exec form and executing a shell directly, as in the case for -the shell form, it is the shell that is doing the environment variable -expansion, not docker. +> but this can only set the binary to exec (no `sh -c` will be used). ### Shell form ENTRYPOINT example @@ -1776,15 +1851,15 @@ There are few rules that describe their co-operation. 2. `ENTRYPOINT` should be defined when using the container as an executable. 3. `CMD` should be used as a way of defining default arguments for an `ENTRYPOINT` command -or for executing an ad-hoc command in a container. + or for executing an ad-hoc command in a container. 4. `CMD` will be overridden when running the container with alternative arguments. The table below shows what command is executed for different `ENTRYPOINT` / `CMD` combinations: | | No ENTRYPOINT | ENTRYPOINT exec_entry p1_entry | ENTRYPOINT ["exec_entry", "p1_entry"] | -|:-------------------------------|:---------------------------|:-------------------------------|:-----------------------------------------------| -| **No CMD** | *error, not allowed* | /bin/sh -c exec_entry p1_entry | exec_entry p1_entry | +| :----------------------------- | :------------------------- | :----------------------------- | :--------------------------------------------- | +| **No CMD** | error, not allowed | /bin/sh -c exec_entry p1_entry | exec_entry p1_entry | | **CMD ["exec_cmd", "p1_cmd"]** | exec_cmd p1_cmd | /bin/sh -c exec_entry p1_entry | exec_entry p1_entry exec_cmd p1_cmd | | **CMD exec_cmd p1_cmd** | /bin/sh -c exec_cmd p1_cmd | /bin/sh -c exec_entry p1_entry | exec_entry p1_entry /bin/sh -c exec_cmd p1_cmd | @@ -1806,7 +1881,7 @@ containers. The value can be a JSON array, `VOLUME ["/var/log/"]`, or a plain string with multiple arguments, such as `VOLUME /var/log` or `VOLUME /var/log /var/db`. For more information/examples and mounting instructions via the Docker client, refer to -[*Share Directories via Volumes*](https://docs.docker.com/storage/volumes/) +[_Share Directories via Volumes_](https://docs.docker.com/storage/volumes/) documentation. The `docker run` command initializes the newly created volume with any data @@ -1821,12 +1896,12 @@ VOLUME /myvol ``` This Dockerfile results in an image that causes `docker run` to -create a new mount point at `/myvol` and copy the `greeting` file +create a new mount point at `/myvol` and copy the `greeting` file into the newly created volume. ### Notes about specifying volumes -Keep the following things in mind about volumes in the `Dockerfile`. +Keep the following things in mind about volumes in the Dockerfile. - **Volumes on Windows-based containers**: When using Windows-based containers, the destination of a volume inside the container must be one of: @@ -1845,7 +1920,7 @@ Keep the following things in mind about volumes in the `Dockerfile`. portability, since a given host directory can't be guaranteed to be available on all hosts. For this reason, you can't mount a host directory from within the Dockerfile. The `VOLUME` instruction does not support specifying a `host-dir` - parameter. You must specify the mountpoint when you create or run the container. + parameter. You must specify the mountpoint when you create or run the container. ## USER @@ -1874,6 +1949,7 @@ runtime, runs the relevant `ENTRYPOINT` and `CMD` commands. > > On Windows, the user must be created first if it's not a built-in account. > This can be done with the `net user` command called as part of a Dockerfile. +{ .warning } ```dockerfile FROM microsoft/windowsservercore @@ -1890,11 +1966,11 @@ WORKDIR /path/to/workdir ``` The `WORKDIR` instruction sets the working directory for any `RUN`, `CMD`, -`ENTRYPOINT`, `COPY` and `ADD` instructions that follow it in the `Dockerfile`. +`ENTRYPOINT`, `COPY` and `ADD` instructions that follow it in the Dockerfile. If the `WORKDIR` doesn't exist, it will be created even if it's not used in any -subsequent `Dockerfile` instruction. +subsequent Dockerfile instruction. -The `WORKDIR` instruction can be used multiple times in a `Dockerfile`. If a +The `WORKDIR` instruction can be used multiple times in a Dockerfile. If a relative path is provided, it will be relative to the path of the previous `WORKDIR` instruction. For example: @@ -1905,10 +1981,10 @@ WORKDIR c RUN pwd ``` -The output of the final `pwd` command in this `Dockerfile` would be `/a/b/c`. +The output of the final `pwd` command in this Dockerfile would be `/a/b/c`. The `WORKDIR` instruction can resolve environment variables previously set using -`ENV`. You can only use environment variables explicitly set in the `Dockerfile`. +`ENV`. You can only use environment variables explicitly set in the Dockerfile. For example: ```dockerfile @@ -1917,13 +1993,13 @@ WORKDIR $DIRPATH/$DIRNAME RUN pwd ``` -The output of the final `pwd` command in this `Dockerfile` would be +The output of the final `pwd` command in this Dockerfile would be `/path/$DIRNAME` -If not specified, the default working directory is `/`. In practice, if you aren't building a Dockerfile from scratch (`FROM scratch`), +If not specified, the default working directory is `/`. In practice, if you aren't building a Dockerfile from scratch (`FROM scratch`), the `WORKDIR` may likely be set by the base image you're using. -Therefore, to avoid unintended operations in unknown directories, it is best practice to set your `WORKDIR` explicitly. +Therefore, to avoid unintended operations in unknown directories, it's best practice to set your `WORKDIR` explicitly. ## ARG @@ -1950,12 +2026,12 @@ ARG buildno # ... ``` -> **Warning:** +> **Warning** > > It is not recommended to use build-time variables for passing secrets like > GitHub keys, user credentials etc. Build-time variable values are visible to > any user of the image with the `docker history` command. -> +> > Refer to the [`RUN --mount=type=secret`](#run---mounttypesecret) section to > learn about secure ways to use secrets when building images. { .warning } @@ -1977,8 +2053,8 @@ at build-time, the builder uses the default. ### Scope An `ARG` variable definition comes into effect from the line on which it is -defined in the `Dockerfile` not from the argument's use on the command-line or -elsewhere. For example, consider this Dockerfile: +defined in the Dockerfile not from the argument's use on the command-line or +elsewhere. For example, consider this Dockerfile: ```dockerfile FROM busybox @@ -2120,7 +2196,7 @@ When building this Dockerfile, the `HTTP_PROXY` is preserved in the This feature is only available when using the [BuildKit](https://docs.docker.com/build/buildkit/) backend. -Docker predefines a set of `ARG` variables with information on the platform of +BuildKit supports a predefined set of `ARG` variables with information on the platform of the node performing the build (build platform) and on the platform of the resulting image (target platform). The target platform can be specified with the `--platform` flag on `docker build`. @@ -2150,19 +2226,19 @@ RUN echo "I'm building for $TARGETPLATFORM" ### BuildKit built-in build args -| Arg | Type | Description | -|---------------------------------------|--------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `BUILDKIT_CACHE_MOUNT_NS` | String | Set optional cache ID namespace. | -| `BUILDKIT_CONTEXT_KEEP_GIT_DIR` | Bool | Trigger git context to keep the `.git` directory. | -| `BUILDKIT_INLINE_CACHE`[^2] | Bool | Inline cache metadata to image config or not. | -| `BUILDKIT_MULTI_PLATFORM` | Bool | Opt into deterministic output regardless of multi-platform output or not. | -| `BUILDKIT_SANDBOX_HOSTNAME` | String | Set the hostname (default `buildkitsandbox`) | -| `BUILDKIT_SYNTAX` | String | Set frontend image | -| `SOURCE_DATE_EPOCH` | Int | Set the UNIX timestamp for created image and layers. More info from [reproducible builds](https://reproducible-builds.org/docs/source-date-epoch/). Supported since Dockerfile 1.5, BuildKit 0.11 | +| Arg | Type | Description | +| ------------------------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `BUILDKIT_CACHE_MOUNT_NS` | String | Set optional cache ID namespace. | +| `BUILDKIT_CONTEXT_KEEP_GIT_DIR` | Bool | Trigger Git context to keep the `.git` directory. | +| `BUILDKIT_INLINE_CACHE`[^2] | Bool | Inline cache metadata to image config or not. | +| `BUILDKIT_MULTI_PLATFORM` | Bool | Opt into deterministic output regardless of multi-platform output or not. | +| `BUILDKIT_SANDBOX_HOSTNAME` | String | Set the hostname (default `buildkitsandbox`) | +| `BUILDKIT_SYNTAX` | String | Set frontend image | +| `SOURCE_DATE_EPOCH` | Int | Set the Unix timestamp for created image and layers. More info from [reproducible builds](https://reproducible-builds.org/docs/source-date-epoch/). Supported since Dockerfile 1.5, BuildKit 0.11 | #### Example: keep `.git` dir -When using a Git context, `.git` dir is not kept on git checkouts. It can be +When using a Git context, `.git` dir is not kept on checkouts. It can be useful to keep it around if you want to retrieve git information during your build: @@ -2187,7 +2263,7 @@ build, then a "cache miss" occurs upon its first usage, not its definition. In particular, all `RUN` instructions following an `ARG` instruction use the `ARG` variable implicitly (as an environment variable), thus can cause a cache miss. All predefined `ARG` variables are exempt from caching unless there is a -matching `ARG` statement in the `Dockerfile`. +matching `ARG` statement in the Dockerfile. For example, consider these two Dockerfile: @@ -2204,10 +2280,10 @@ RUN echo hello ``` If you specify `--build-arg CONT_IMG_VER=` on the command line, in both -cases, the specification on line 2 does not cause a cache miss; line 3 does -cause a cache miss.`ARG CONT_IMG_VER` causes the RUN line to be identified +cases, the specification on line 2 doesn't cause a cache miss; line 3 does +cause a cache miss. `ARG CONT_IMG_VER` causes the `RUN` line to be identified as the same as running `CONT_IMG_VER= echo hello`, so if the `` -changes, we get a cache miss. +changes, you get a cache miss. Consider another example under the same command line: @@ -2233,7 +2309,7 @@ ENV CONT_IMG_VER=hello RUN echo $CONT_IMG_VER ``` -Line 3 does not cause a cache miss because the value of `CONT_IMG_VER` is a +Line 3 doesn't cause a cache miss because the value of `CONT_IMG_VER` is a constant (`hello`). As a result, the environment variables and values used on the `RUN` (line 4) doesn't change between builds. @@ -2243,11 +2319,11 @@ the `RUN` (line 4) doesn't change between builds. ONBUILD ``` -The `ONBUILD` instruction adds to the image a *trigger* instruction to +The `ONBUILD` instruction adds to the image a trigger instruction to be executed at a later time, when the image is used as the base for another build. The trigger will be executed in the context of 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. @@ -2257,12 +2333,12 @@ daemon which may be customized with user-specific configuration. For example, if your image is a reusable Python application builder, it will require application source code to be added in a particular -directory, and it might require a build script to be called *after* +directory, and it might require a build script to be called after that. You can't just call `ADD` and `RUN` now, because you don't yet have access to the application source code, and it will be different for each application build. You could simply provide application developers -with a boilerplate `Dockerfile` to copy-paste into their application, but -that is inefficient, error-prone and difficult to update because it +with a boilerplate Dockerfile to copy-paste into their application, but +that's inefficient, error-prone and difficult to update because it mixes with application-specific code. The solution is to use `ONBUILD` to register advance instructions to @@ -2272,7 +2348,7 @@ Here's how it works: 1. When it encounters an `ONBUILD` instruction, the builder adds a trigger to the metadata of the image being built. The instruction - does not otherwise affect the current build. + doesn't otherwise affect the current build. 2. At the end of the build, a list of all triggers is stored in the image manifest, under the key `OnBuild`. They can be inspected with the `docker inspect` command. @@ -2284,7 +2360,7 @@ Here's how it works: build to fail. If all triggers succeed, the `FROM` instruction completes and the build continues as usual. 4. Triggers are cleared from the final image after being executed. In - other words they are not inherited by "grand-children" builds. + other words they aren't inherited by "grand-children" builds. For example you might add something like this: @@ -2296,10 +2372,12 @@ ONBUILD RUN /usr/local/bin/python-build --dir /app/src > **Warning** > > Chaining `ONBUILD` instructions using `ONBUILD ONBUILD` isn't allowed. +{ .warning } > **Warning** > > The `ONBUILD` instruction may not trigger `FROM` or `MAINTAINER` instructions. +{ .warning } ## STOPSIGNAL @@ -2324,11 +2402,11 @@ The `HEALTHCHECK` instruction has two forms: - `HEALTHCHECK NONE` (disable any healthcheck inherited from the base image) The `HEALTHCHECK` instruction tells Docker how to test a container to check that -it is still working. This can detect cases such as a web server that is stuck in +it's still working. This can detect cases such as a web server stuck in an infinite loop and unable to handle new connections, even though the server process is still running. -When a container has a healthcheck specified, it has a _health status_ in +When a container has a healthcheck specified, it has a health status in addition to its normal status. This status is initially `starting`. Whenever a health check passes, it becomes `healthy` (whatever state it was previously in). After a certain number of consecutive failures, it becomes `unhealthy`. @@ -2362,15 +2440,15 @@ There can only be one `HEALTHCHECK` instruction in a Dockerfile. If you list more than one then only the last `HEALTHCHECK` will take effect. The command after the `CMD` keyword can be either a shell command (e.g. `HEALTHCHECK -CMD /bin/check-running`) or an _exec_ array (as with other Dockerfile commands; +CMD /bin/check-running`) or an exec array (as with other Dockerfile commands; see e.g. `ENTRYPOINT` for details). The command's exit status indicates the health status of the container. The possible values are: - 0: success - the container is healthy and ready for use -- 1: unhealthy - the container is not working correctly -- 2: reserved - do not use this exit code +- 1: unhealthy - the container isn't working correctly +- 2: reserved - don't use this exit code For example, to check every five minutes or so that a web-server is able to serve the site's main page within three seconds: @@ -2388,16 +2466,15 @@ are stored currently). When the health status of a container changes, a `health_status` event is generated with the new status. - ## SHELL ```dockerfile SHELL ["executable", "parameters"] ``` -The `SHELL` instruction allows the default shell used for the *shell* form of +The `SHELL` instruction allows the default shell used for the shell form of commands to be overridden. The default shell on Linux is `["/bin/sh", "-c"]`, and on -Windows is `["cmd", "/S", "/C"]`. The `SHELL` instruction *must* be written in JSON +Windows is `["cmd", "/S", "/C"]`. The `SHELL` instruction must be written in JSON form in a Dockerfile. The `SHELL` instruction is particularly useful on Windows where there are @@ -2426,7 +2503,7 @@ RUN echo hello ``` The following instructions can be affected by the `SHELL` instruction when the -*shell* form of them is used in a Dockerfile: `RUN`, `CMD` and `ENTRYPOINT`. +shell form of them is used in a Dockerfile: `RUN`, `CMD` and `ENTRYPOINT`. The following example is a common pattern found on Windows which can be streamlined by using the `SHELL` instruction: @@ -2435,26 +2512,26 @@ streamlined by using the `SHELL` instruction: RUN powershell -command Execute-MyCmdlet -param1 "c:\foo.txt" ``` -The command invoked by docker will be: +The command invoked by the builder will be: ```powershell cmd /S /C powershell -command Execute-MyCmdlet -param1 "c:\foo.txt" ``` -This is inefficient for two reasons. First, there is an un-necessary cmd.exe command -processor (aka shell) being invoked. Second, each `RUN` instruction in the *shell* -form requires an extra `powershell -command` prefixing the command. +This is inefficient for two reasons. First, there is an unnecessary `cmd.exe` +command processor (aka shell) being invoked. Second, each `RUN` instruction in +the shell form requires an extra `powershell -command` prefixing the command. To make this more efficient, one of two mechanisms can be employed. One is to -use the JSON form of the RUN command such as: +use the JSON form of the `RUN` command such as: ```dockerfile RUN ["powershell", "-command", "Execute-MyCmdlet", "-param1 \"c:\\foo.txt\""] ``` -While the JSON form is unambiguous and does not use the un-necessary cmd.exe, +While the JSON form is unambiguous and does not use the unnecessary `cmd.exe`, it does require more verbosity through double-quoting and escaping. The alternate -mechanism is to use the `SHELL` instruction and the *shell* form, +mechanism is to use the `SHELL` instruction and the shell form, making a more natural syntax for Windows users, especially when combined with the `escape` parser directive: @@ -2602,6 +2679,7 @@ For examples of Dockerfiles, refer to: - The ["build images" section](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/) - The ["get started" tutorial](https://docs.docker.com/get-started/) - The [language-specific getting started guides](https://docs.docker.com/language/) +- The [build guide](https://docs.docker.com/build/guide/) [^1]: Value required [^2]: For Docker-integrated [BuildKit](https://docs.docker.com/build/buildkit/#getting-started) and `docker buildx build` diff --git a/_vendor/modules.txt b/_vendor/modules.txt index 28b1be1ea1..275bd8562a 100644 --- a/_vendor/modules.txt +++ b/_vendor/modules.txt @@ -1,7 +1,7 @@ # github.com/moby/moby v24.0.5+incompatible -# github.com/moby/buildkit v0.13.0-beta1.0.20231113205014-1efcd30d9dd6 +# github.com/moby/buildkit v0.13.0-beta1.0.20231214000015-a960fe501f00 # github.com/docker/buildx v0.12.1-0.20231214091505-b68ee824c673 # github.com/docker/scout-cli v1.2.0 -# github.com/docker/cli v24.0.8-0.20231213094340-0f82fd88610a+incompatible +# github.com/docker/cli v25.0.0-beta.1+incompatible # github.com/compose-spec/compose-spec v0.0.0-20231121152139-478928e7c9f8 # github.com/docker/compose/v2 v2.23.3 diff --git a/go.mod b/go.mod index c8e4b23d48..fce6dc2a9c 100644 --- a/go.mod +++ b/go.mod @@ -7,9 +7,12 @@ toolchain go1.21.1 require ( github.com/compose-spec/compose-spec v0.0.0-20231121152139-478928e7c9f8 // indirect github.com/docker/buildx v0.12.1-0.20231214091505-b68ee824c673 // indirect - github.com/docker/cli v24.0.8-0.20231213094340-0f82fd88610a+incompatible // indirect + github.com/docker/cli v25.0.0-beta.1+incompatible // indirect github.com/docker/compose/v2 v2.23.3 // indirect github.com/docker/scout-cli v1.2.0 // indirect - github.com/moby/buildkit v0.13.0-beta1.0.20231113205014-1efcd30d9dd6 // indirect + github.com/moby/buildkit v0.13.0-beta1.0.20231214000015-a960fe501f00 // indirect github.com/moby/moby v24.0.5+incompatible // indirect ) + +// buildkit depends on cli v25 beta1, pin to v24 +replace github.com/docker/cli => github.com/docker/cli v24.0.8-0.20231213094340-0f82fd88610a+incompatible diff --git a/go.sum b/go.sum index cbd5c8c7af..d1d2a7e487 100644 --- a/go.sum +++ b/go.sum @@ -153,6 +153,8 @@ github.com/moby/buildkit v0.13.0-beta1.0.20231011101155-c444964c2e8f h1:CEiXZq08 github.com/moby/buildkit v0.13.0-beta1.0.20231011101155-c444964c2e8f/go.mod h1:oSHnUZH7sNtAFLyeN1syf46SuzMThKsCQaioNEqJVUk= github.com/moby/buildkit v0.13.0-beta1.0.20231113205014-1efcd30d9dd6 h1:gfbjHMadWpzz9Jbbo4l73lrkNrP2YvNsKIIg8e5Ra4s= github.com/moby/buildkit v0.13.0-beta1.0.20231113205014-1efcd30d9dd6/go.mod h1:VE6gCOYRW2hbxnxtt7udKkYMF73YdvkgIrGhkB0EiDA= +github.com/moby/buildkit v0.13.0-beta1.0.20231214000015-a960fe501f00 h1:Ymp+x/hsr6M6R+6j4XVyGaRrhAt1MnGXoN+ZkQ+TuuA= +github.com/moby/buildkit v0.13.0-beta1.0.20231214000015-a960fe501f00/go.mod h1:6MddWPSL5jxy+W8eMMHWDOfZzzRRKWXPZqajw72YHBc= 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=