diff --git a/content/build/bake/_index.md b/content/build/bake/_index.md index b4d3ef63537..fae941e7a92 100644 --- a/content/build/bake/_index.md +++ b/content/build/bake/_index.md @@ -1,5 +1,5 @@ --- -title: High-level builds with Bake +title: Buildx Bake keywords: build, buildx, bake, buildkit, hcl, json, compose aliases: - /build/customize/bake/ @@ -11,27 +11,51 @@ aliases: > [feedback from users](https://github.com/docker/buildx/issues). { .experimental } -Buildx provides support for high-level build orchestration that goes beyond -invoking a single build command. Bake lets you build all the images in your -application together. You can define all of the build jobs for your projects in -a file that can then be easily invoked by anyone. - -You can think of Bake as a task runner for Docker builds. -[BuildKit](https://github.com/moby/buildkit) efficiently handles multiple -concurrent build requests and de-duplicating work. You can invoke your builds -using general-purpose task runners, like `make`. However, such tools generally -invoke builds in a sequence. Therefore they aren't leveraging the full -potential of BuildKit parallelization. Bake solves this problem. - -The `docker buildx bake` command supports building images from a configuration -file in HCL, JSON or YAML format. The YAML format extends the Compose -Specification, and it's similar to `docker compose build`, except it builds all -of your services concurrently as part of a single request. - -## Next steps - -- [Bake file reference](./reference.md) -- [Configuring builds](./configuring-build.md) -- [User defined HCL functions](./advanced.md) -- [Defining additional build contexts and linking targets](./build-contexts.md) -- [Building from Compose file](./compose-file.md) +Bake is a feature of Docker Buildx that lets you define your build configuraton +using a declarative file, as opposed to specifying a complex CLI expression. It +also lets you run multiple builds concurrently with a single invocation. + +A Bake file can be written in HCL, JSON, or YAML formats, where the YAML format +is an extension of a Docker Compose file. Here's an example Bake file in HCL +format: + +```hcl +group "default" { + targets = ["frontend", "backend"] +} + +target "frontend" { + context = "./frontend" + dockerfile = "frontend.Dockerfile" + args = { + NODE_VERSION = "22" + } + tags = ["myapp/frontend:latest"] +} + +target "backend" { + context = "./backend" + dockerfile = "backend.Dockerfile" + args = { + GO_VERSION = "{{% param "example_go_version" %}}" + } + tags = ["myapp/backend:latest"] +} +``` + +The `group` block defines a group of targets that can be built concurrently. +Each `target` block defines a build target with its own configuration, such as +the build context, Dockerfile, and tags. + +To invoke a build using the above Bake file, you can run: + +```console +$ docker buildx bake +``` + +This executes the `default` group, which builds the `frontend` and `backend` +targets concurrently. + +## Get started + +To learn how to get started with Bake, head over to the [Bake introduction](./introduction.md). diff --git a/content/build/bake/advanced.md b/content/build/bake/advanced.md deleted file mode 100644 index 09ba09befce..00000000000 --- a/content/build/bake/advanced.md +++ /dev/null @@ -1,348 +0,0 @@ ---- -title: Advanced Bake patterns and functions -description: Learn about advanced Bake features, like user-defined functions -keywords: build, buildx, bake, buildkit, hcl -aliases: - - /build/customize/bake/hcl-funcs/ - - /build/bake/hcl-funcs/ ---- - -HCL functions are great for when you need to manipulate values in more complex ways than just concatenating or appending values. - -The following sections contain some examples on custom functions and other -advanced use cases: - -- [Interpolate environment variables](#interpolate-environment-variables) -- [Built-in functions](#built-in-functions) -- [User-defined functions](#user-defined-functions) -- [Ternary operators](#ternary-operators) -- [Variables in functions](#variables-in-functions) -- [Typed variables](#typed-variables) - -## Interpolate environment variables - -As shown in the [Bake file reference](reference.md#variable) page, Bake -supports variable blocks which are assigned to matching environment variables -or default values. - -The following example shows how you can interpolate a `TAG` environment -variable to populate a variable in the Bake configuration. - -{{< tabs >}} -{{< tab name="HCL" >}} - -```hcl -# docker-bake.hcl -variable "TAG" { - default = "latest" -} - -group "default" { - targets = ["webapp"] -} - -target "webapp" { - tags = ["docker.io/username/webapp:${TAG}"] -} -``` - -{{< /tab >}} -{{< tab name="JSON" >}} - -```json -{ - "variable": { - "TAG": { - "default": "latest" - } - }, - "group": { - "default": { - "targets": ["webapp"] - } - }, - "target": { - "webapp": { - "tags": ["docker.io/username/webapp:${TAG}"] - } - } -} -``` - -{{< /tab >}} -{{< /tabs >}} - -```console -$ docker buildx bake --print webapp -``` - -```json -{ - "group": { - "default": { - "targets": ["webapp"] - } - }, - "target": { - "webapp": { - "context": ".", - "dockerfile": "Dockerfile", - "tags": ["docker.io/username/webapp:latest"] - } - } -} -``` - -```console -$ TAG=$(git rev-parse --short HEAD) docker buildx bake --print webapp -``` - -```json -{ - "group": { - "default": { - "targets": ["webapp"] - } - }, - "target": { - "webapp": { - "context": ".", - "dockerfile": "Dockerfile", - "tags": ["docker.io/username/webapp:985e9e9"] - } - } -} -``` - -## Built-in functions - -You can use [`go-cty` standard library functions](https://github.com/zclconf/go-cty/tree/main/cty/function/stdlib). -The following example shows the `add` function. - -```hcl -# docker-bake.hcl -variable "TAG" { - default = "latest" -} - -group "default" { - targets = ["webapp"] -} - -target "webapp" { - args = { - buildno = "${add(123, 1)}" - } -} -``` - -```console -$ docker buildx bake --print webapp -``` - -```json -{ - "group": { - "default": { - "targets": ["webapp"] - } - }, - "target": { - "webapp": { - "context": ".", - "dockerfile": "Dockerfile", - "args": { - "buildno": "124" - } - } - } -} -``` - -## User-defined functions - -You can create [user-defined functions](https://github.com/hashicorp/hcl/tree/main/ext/userfunc) -that do just what you want, if the built-in standard library functions don't -meet your needs. - -The following example defines an `increment` function. - -```hcl -# docker-bake.hcl -function "increment" { - params = [number] - result = number + 1 -} - -group "default" { - targets = ["webapp"] -} - -target "webapp" { - args = { - buildno = "${increment(123)}" - } -} -``` - -```console -$ docker buildx bake --print webapp -``` - -```json -{ - "group": { - "default": { - "targets": ["webapp"] - } - }, - "target": { - "webapp": { - "context": ".", - "dockerfile": "Dockerfile", - "args": { - "buildno": "124" - } - } - } -} -``` - -## Ternary operators - -You can use ternary operators to conditionally register a value. - -The following example adds a tag only when a variable is not empty, using the -`notequal` function. - -```hcl -# docker-bake.hcl -variable "TAG" {default="" } - -group "default" { - targets = [ - "webapp", - ] -} - -target "webapp" { - context="." - dockerfile="Dockerfile" - tags = [ - "my-image:latest", - notequal("",TAG) ? "my-image:${TAG}": "", - ] -} -``` - -```console -$ docker buildx bake --print webapp -``` - -```json -{ - "group": { - "default": { - "targets": ["webapp"] - } - }, - "target": { - "webapp": { - "context": ".", - "dockerfile": "Dockerfile", - "tags": ["my-image:latest"] - } - } -} -``` - -## Variables in functions - -You can make references to variables and standard library functions inside your -functions. - -You can't reference user-defined functions from other functions. - -```hcl -# docker-bake.hcl -variable "REPO" { - default = "user/repo" -} - -function "tag" { - params = [tag] - result = ["${REPO}:${tag}"] -} - -target "webapp" { - tags = tag("v1") -} -``` - -```console -$ docker buildx bake --print webapp -``` - -```json -{ - "group": { - "default": { - "targets": ["webapp"] - } - }, - "target": { - "webapp": { - "context": ".", - "dockerfile": "Dockerfile", - "tags": ["user/repo:v1"] - } - } -} -``` - -## Typed variables - -Non-string variables are supported. Values passed as environment variables are -coerced into suitable types first. - -```hcl -# docker-bake.hcl -variable "FOO" { - default = 3 -} - -variable "IS_FOO" { - default = true -} - -target "app" { - args = { - v1 = FOO > 5 ? "higher" : "lower" - v2 = IS_FOO ? "yes" : "no" - } -} -``` - -```console -$ docker buildx bake --print app -``` - -```json -{ - "group": { - "default": { - "targets": ["app"] - } - }, - "target": { - "app": { - "context": ".", - "dockerfile": "Dockerfile", - "args": { - "v1": "lower", - "v2": "yes" - } - } - } -} -``` diff --git a/content/build/bake/compose-file.md b/content/build/bake/compose-file.md index 4386a2503ce..a139df08517 100644 --- a/content/build/bake/compose-file.md +++ b/content/build/bake/compose-file.md @@ -6,10 +6,8 @@ aliases: - /build/customize/bake/compose-file/ --- -## Specification - -Bake uses the [compose-spec](../../compose/compose-file/index.md) to -parse a compose file and translate each service to a [target](reference.md#target). +Bake supports the [Compose file format](../../compose/compose-file/_index.md) +to parse a Compose file and translate each service to a [target](reference.md#target). ```yaml # docker-compose.yml diff --git a/content/build/bake/configuring-build.md b/content/build/bake/configuring-build.md deleted file mode 100644 index e4a0447ec6f..00000000000 --- a/content/build/bake/configuring-build.md +++ /dev/null @@ -1,261 +0,0 @@ ---- -title: Configure builds with Bake -description: Learn how to create a flexible build configuration with Bake -keywords: build, buildx, bake, buildkit, hcl, json -aliases: - - /build/customize/bake/configuring-build/ ---- - -Bake supports loading build definitions from files, but sometimes you need even -more flexibility to configure these definitions. - -For this use case, you can define variables inside the bake files that can be -set by the user with environment variables or by [attribute definitions](#global-scope-attributes) -in other bake files. If you wish to change a specific value for a single -invocation you can use the `--set` flag [from the command line](#from-command-line). - -## Global scope attributes - -You can define global scope attributes in HCL/JSON and use them for code reuse -and setting values for variables. This means you can do a "data-only" HCL file -with the values you want to set/override and use it in the list of regular -output files. - -```hcl -# docker-bake.hcl -variable "FOO" { - default = "abc" -} - -target "app" { - args = { - v1 = "pre-${FOO}" - } -} -``` - -You can use this file directly: - -```console -$ docker buildx bake --print app -``` - -```json -{ - "group": { - "default": { - "targets": ["app"] - } - }, - "target": { - "app": { - "context": ".", - "dockerfile": "Dockerfile", - "args": { - "v1": "pre-abc" - } - } - } -} -``` - -Or create an override configuration file: - -```hcl -# env.hcl -WHOAMI="myuser" -FOO="def-${WHOAMI}" -``` - -And invoke bake together with both of the files: - -```console -$ docker buildx bake -f docker-bake.hcl -f env.hcl --print app -``` - -```json -{ - "group": { - "default": { - "targets": ["app"] - } - }, - "target": { - "app": { - "context": ".", - "dockerfile": "Dockerfile", - "args": { - "v1": "pre-def-myuser" - } - } - } -} -``` - -## Resource interpolation - -You can also refer to attributes defined as part of other targets, to help -reduce duplication between targets. - -```hcl -# docker-bake.hcl -target "foo" { - dockerfile = "${target.foo.name}.Dockerfile" - tags = [target.foo.name] -} -target "bar" { - dockerfile = "${target.foo.name}.Dockerfile" - tags = [target.bar.name] -} -``` - -You can use this file directly: - -```console -$ docker buildx bake --print foo bar -``` - -```json -{ - "group": { - "default": { - "targets": ["foo", "bar"] - } - }, - "target": { - "foo": { - "context": ".", - "dockerfile": "foo.Dockerfile", - "tags": ["foo"] - }, - "bar": { - "context": ".", - "dockerfile": "foo.Dockerfile", - "tags": ["bar"] - } - } -} -``` - -## From command line - -You can also override target configurations from the command line with the -[`--set` flag](../../reference/cli/docker/buildx/bake.md#set): - -```hcl -# docker-bake.hcl -target "app" { - args = { - mybuildarg = "foo" - } -} -``` - -```console -$ docker buildx bake --set app.args.mybuildarg=bar --set app.platform=linux/arm64 app --print -``` - -```json -{ - "group": { - "default": { - "targets": ["app"] - } - }, - "target": { - "app": { - "context": ".", - "dockerfile": "Dockerfile", - "args": { - "mybuildarg": "bar" - }, - "platforms": ["linux/arm64"] - } - } -} -``` - -Pattern matching syntax defined in [https://golang.org/pkg/path/#Match](https://golang.org/pkg/path/#Match) -is also supported: - -```console -$ docker buildx bake --set foo*.args.mybuildarg=value # overrides build arg for all targets starting with "foo" -$ docker buildx bake --set *.platform=linux/arm64 # overrides platform for all targets -$ docker buildx bake --set foo*.no-cache # bypass caching only for targets starting with "foo" -``` - -Complete list of overridable fields: - -- `args` -- `cache-from` -- `cache-to` -- `context` -- `dockerfile` -- `labels` -- `no-cache` -- `output` -- `platform` -- `pull` -- `secrets` -- `ssh` -- `tags` -- `target` - -## Using variables in variables across files - -When multiple files are specified, one file can use variables defined in -another file. - -```hcl -# docker-bake1.hcl -variable "FOO" { - default = upper("${BASE}def") -} - -variable "BAR" { - default = "-${FOO}-" -} - -target "app" { - args = { - v1 = "pre-${BAR}" - } -} -``` - -```hcl -# docker-bake2.hcl -variable "BASE" { - default = "abc" -} - -target "app" { - args = { - v2 = "${FOO}-post" - } -} -``` - -```console -$ docker buildx bake -f docker-bake1.hcl -f docker-bake2.hcl --print app -``` - -```json -{ - "group": { - "default": { - "targets": ["app"] - } - }, - "target": { - "app": { - "context": ".", - "dockerfile": "Dockerfile", - "args": { - "v1": "pre--ABCDEF-", - "v2": "ABCDEF-post" - } - } - } -} -``` diff --git a/content/build/bake/build-contexts.md b/content/build/bake/contexts.md similarity index 92% rename from content/build/bake/build-contexts.md rename to content/build/bake/contexts.md index 75d8a3eede3..8b2744cd289 100644 --- a/content/build/bake/build-contexts.md +++ b/content/build/bake/contexts.md @@ -1,11 +1,12 @@ --- -title: Defining additional build contexts and linking targets +title: Using Bake with additional contexts description: | Additional contexts are useful when you want to pin image versions, or reference the output of other targets keywords: build, buildx, bake, buildkit, hcl aliases: - /build/customize/bake/build-contexts/ + - /build/bake/build-contexts/ --- In addition to the main `context` key that defines the build context, each @@ -60,9 +61,9 @@ target "app" { } ``` -## Using a result of one target as a base image in another target +## Using a target as a build context -To use a result of one target as a build context of another, specity the target +To use a result of one target as a build context of another, specify the target name with `target:` prefix. ```dockerfile diff --git a/content/build/bake/expressions.md b/content/build/bake/expressions.md new file mode 100644 index 00000000000..b486d5b36a4 --- /dev/null +++ b/content/build/bake/expressions.md @@ -0,0 +1,144 @@ +--- +title: Expression evaluation in Bake +description: Learn about advanced Bake features, like user-defined functions +keywords: build, buildx, bake, buildkit, hcl, expressions, evaluation, math, arithmetic, conditionals +aliases: + - /build/bake/advanced/ +--- + +Bake files in the HCL format support expression evaluation, which lets you +perform arithmetic operations, conditionally set values, and more. + +## Arithmetic operations + +You can perform arithmetic operations in expressions. The following example +shows how to multiply two numbers. + +```hcl {title=docker-bake.hcl} +sum = 7*6 + +target "default" { + args = { + answer = sum + } +} +``` + +Printing the Bake file with the `--print` flag shows the evaluated value for +the `answer` build argument. + +```console +$ docker buildx bake --print app +``` + +```json +{ + "target": { + "default": { + "context": ".", + "dockerfile": "Dockerfile", + "args": { + "answer": "42" + } + } + } +} +``` + +## Ternary operators + +You can use ternary operators to conditionally register a value. + +The following example adds a tag only when a variable is not empty, using the +built-in `notequal` [function](./funcs.md). + +```hcl {title=docker-bake.hcl} +variable "TAG" {} + +target "default" { + context="." + dockerfile="Dockerfile" + tags = [ + "my-image:latest", + notequal("",TAG) ? "my-image:${TAG}": "", + ] +} +``` + +In this case, `TAG` is an empty string, so the resulting build configuration +only contains the hard-coded `my-image:latest` tag. + +```console +$ docker buildx bake --print +``` + +```json +{ + "group": { + "default": { + "targets": ["default"] + } + }, + "target": { + "webapp": { + "context": ".", + "dockerfile": "Dockerfile", + "tags": ["my-image:latest"] + } + } +} +``` + +## Expressions with variables + +You can use expressions with [variables](./variables.md) to conditionally set +values, or to perform arithmetic operations. + +The following example uses expressions to set values based on the value of +variables. The `v1` build argument is set to "higher" if the variable `FOO` is +greater than 5, otherwise it is set to "lower". The `v2` build argument is set +to "yes" if the `IS_FOO` variable is true, otherwise it is set to "no". + +```hcl {title=docker-bake.hcl} +variable "FOO" { + default = 3 +} + +variable "IS_FOO" { + default = true +} + +target "app" { + args = { + v1 = FOO > 5 ? "higher" : "lower" + v2 = IS_FOO ? "yes" : "no" + } +} +``` + +Printing the Bake file with the `--print` flag shows the evaluated values for +the `v1` and `v2` build arguments. + +```console +$ docker buildx bake --print app +``` + +```json +{ + "group": { + "default": { + "targets": ["app"] + } + }, + "target": { + "app": { + "context": ".", + "dockerfile": "Dockerfile", + "args": { + "v1": "lower", + "v2": "yes" + } + } + } +} +``` diff --git a/content/build/bake/funcs.md b/content/build/bake/funcs.md new file mode 100644 index 00000000000..737db986719 --- /dev/null +++ b/content/build/bake/funcs.md @@ -0,0 +1,152 @@ +--- +title: HCL functions +description: Learn about built-in and user-defined HCL functions with Bake +keywords: build, buildx, bake, buildkit, hcl, functions, user-defined, built-in, custom, gocty +aliases: + - /build/customize/bake/hcl-funcs/ + - /build/bake/hcl-funcs/ +--- + +HCL functions are great for when you need to manipulate values in your build +configuration in more complex ways than just concatenation or interpolation. + +## Standard library + +Bake ships with built-in support for the [`go-cty` standard library functions](https://github.com/zclconf/go-cty/tree/main/cty/function/stdlib). +The following example shows the `add` function. + +```hcl {title=docker-bake.hcl} +variable "TAG" { + default = "latest" +} + +group "default" { + targets = ["webapp"] +} + +target "webapp" { + args = { + buildno = "${add(123, 1)}" + } +} +``` + +```console +$ docker buildx bake --print webapp +``` + +```json +{ + "group": { + "default": { + "targets": ["webapp"] + } + }, + "target": { + "webapp": { + "context": ".", + "dockerfile": "Dockerfile", + "args": { + "buildno": "124" + } + } + } +} +``` + +## User-defined functions + +You can create [user-defined functions](https://github.com/hashicorp/hcl/tree/main/ext/userfunc) +that do just what you want, if the built-in standard library functions don't +meet your needs. + +The following example defines an `increment` function. + +```hcl {title=docker-bake.hcl} +function "increment" { + params = [number] + result = number + 1 +} + +group "default" { + targets = ["webapp"] +} + +target "webapp" { + args = { + buildno = "${increment(123)}" + } +} +``` + +```console +$ docker buildx bake --print webapp +``` + +```json +{ + "group": { + "default": { + "targets": ["webapp"] + } + }, + "target": { + "webapp": { + "context": ".", + "dockerfile": "Dockerfile", + "args": { + "buildno": "124" + } + } + } +} +``` + +## Variables in functions + +You can make references to [variables](./variables) and standard library +functions inside your functions. + +You can't reference user-defined functions from other functions. + +The following example uses a global variable (`REPO`) in a custom function. + +```hcl {title=docker-bake.hcl} +# docker-bake.hcl +variable "REPO" { + default = "user/repo" +} + +function "tag" { + params = [tag] + result = ["${REPO}:${tag}"] +} + +target "webapp" { + tags = tag("v1") +} +``` + +Printing the Bake file with the `--print` flag shows that the `tag` function +uses the value of `REPO` to set the prefix of the tag. + +```console +$ docker buildx bake --print webapp +``` + +```json +{ + "group": { + "default": { + "targets": ["webapp"] + } + }, + "target": { + "webapp": { + "context": ".", + "dockerfile": "Dockerfile", + "tags": ["user/repo:v1"] + } + } +} +``` diff --git a/content/build/bake/inheritance.md b/content/build/bake/inheritance.md new file mode 100644 index 00000000000..c3556408fb9 --- /dev/null +++ b/content/build/bake/inheritance.md @@ -0,0 +1,165 @@ +--- +title: Inheritance in Bake +description: Learn how to inherit attributes from other targets in Bake +keywords: buildx, buildkit, bake, inheritance, targets, attributes +--- + +Targets can inherit attributes from other targets, using the `inherits` +attribute. For example, imagine that you have a target that builds a Docker +image for a development environment: + +```hcl +target "app-dev" { + args = { + GO_VERSION = "{{% param example_go_version %}}" + } + tags = ["docker.io/username/myapp:dev"] + labels = { + "org.opencontainers.image.source" = "https://github.com/username/myapp" + "org.opencontainers.image.author" = "moby.whale@example.com" + } +} +``` + +You can create a new target that uses the same build configuration, but with +slightly different attributes for a production build. In this example, the +`app-release` target inherits the `app-dev` target, but overrides the `tags` +attribute and adds a new `platforms` attribute: + +```hcl +target "app-release" { + inherits = ["app-dev"] + tags = ["docker.io/username/myapp:latest"] + platforms = ["linux/amd64", "linux/arm64"] +} +``` + +## Common reusable targets + +One common inheritance pattern is to define a common target that contains +shared attributes for all or many of the build targets in the project. For +example, the following `_common` target defines a common set of build +arguments: + +```hcl +target "_common" { + args = { + GO_VERSION = "{{% param example_go_version %}}" + BUILDKIT_CONTEXT_KEEP_GIT_DIR = 1 + } +} +``` + +You can then inherit the `_common` target in other targets to apply the shared +attributes: + +```hcl +target "lint" { + inherits = ["_common"] + dockerfile = "./dockerfiles/lint.Dockerfile" + output = ["type=cacheonly"] +} + +target "docs" { + inherits = ["_common"] + dockerfile = "./dockerfiles/docs.Dockerfile" + output = ["./docs/reference"] +} + +target "test" { + inherits = ["_common"] + target = "test-output" + output = ["./test"] +} + +target "binaries" { + inherits = ["_common"] + target = "binaries" + output = ["./build"] + platforms = ["local"] +} +``` + +## Overriding inherited attributes + +When a target inherits another target, it can override any of the inherited +attributes. For example, the following target overrides the `args` attribute +from the inherited target: + +```hcl +target "app-dev" { + inherits = ["_common"] + args = { + GO_VERSION = "1.17" + } + tags = ["docker.io/username/myapp:dev"] +} +``` + +The `GO_VERSION` argument in `app-release` is set to `1.17`, overriding the +`GO_VERSION` argument from the `app-dev` target. + +For more information about overriding attributes, see the [Overriding +configurations](./overrides.md) page. + +## Inherit from multiple targets + +The `inherits` attribute is a list, meaning you can reuse attributes from +multiple other targets. In the following example, the app-release target reuses +attributes from both the `app-dev` and `_common` targets. + +```hcl +target "_common" { + args = { + GO_VERSION = "{{% param example_go_version %}}" + BUILDKIT_CONTEXT_KEEP_GIT_DIR = 1 + } +} + +target "app-dev" { + inherits = ["_common"] + args = { + BUILDKIT_CONTEXT_KEEP_GIT_DIR = 0 + } + tags = ["docker.io/username/myapp:dev"] + labels = { + "org.opencontainers.image.source" = "https://github.com/username/myapp" + "org.opencontainers.image.author" = "moby.whale@example.com" + } +} + +target "app-release" { + inherits = ["app-dev", "_common"] + tags = ["docker.io/username/myapp:latest"] + platforms = ["linux/amd64", "linux/arm64"] +} +``` + +When inheriting attributes from multiple targets and there's a conflict, the +target that appears last in the inherits list takes precedence. The previous +example defines the `BUILDKIT_CONTEXT_KEEP_GIT_DIR` in the `_common` target and +overrides it in the `app-dev` target. + +The `app-release` target inherits both `app-dev` target and the `_common` target. +The `BUILDKIT_CONTEXT_KEEP_GIT_DIR` argument is set to 0 in the `app-dev` target +and 1 in the `_common` target. The `BUILDKIT_CONTEXT_KEEP_GIT_DIR` argument in +the `app-release` target is set to 1, not 0, because the `_common` target appears +last in the inherits list. + +## Reusing single attributes from targets + +If you only want to inherit a single attribute from a target, you can reference +an attribute from another target using dot notation. For example, in the +following Bake file, the `bar` target reuses the `tags` attribute from the +`foo` target: + +```hcl {title=docker-bake.hcl} +target "foo" { + dockerfile = "foo.Dockerfile" + tags = ["myapp:latest"] +} +target "bar" { + dockerfile = "bar.Dockerfile" + tags = target.foo.tags +} +``` diff --git a/content/build/bake/introduction.md b/content/build/bake/introduction.md new file mode 100644 index 00000000000..872c9da5b44 --- /dev/null +++ b/content/build/bake/introduction.md @@ -0,0 +1,91 @@ +--- +title: Introduction to Bake +description: Get started with using Bake to build your project +keywords: bake, quickstart, build, project, introduction, getting started +--- + +Bake is an abstraction for the `docker build` command that lets you more easily +manage your build configuration (CLI flags, environment variables, etc.) in a +consistent way for everyone on your team. + +Bake is a command built into the Buildx CLI, so as long as you have Buildx +installed, you also have access to bake, via the `docker buildx bake` command. + +## Building a project with Bake + +Here's a simple example of a `docker build` command: + +```console +$ docker build -f Dockerfile -t myapp:latest . +``` + +This command builds the Dockerfile in the current directory and tags the +resulting image as `myapp:latest`. + +To express the same build configuration using Bake: + +```hcl {title=docker-bake.hcl} +target "myapp" { + context = "." + dockerfile = "Dockerfile" + tags = ["myapp:latest"] +} +``` + +Bake provides a structured way to manage your build configuration, and it saves +you from having to remember all the CLI flags for `docker build` every time. +With this file, building the image is as simple as running: + +```console +$ docker buildx bake myapp +``` + +For simple builds, the difference between `docker build` and `docker buildx +bake` is minimal. However, as your build configuration grows more complex, Bake +provides a more structured way to manage that complexity, that would be +difficult to manage with CLI flags for the `docker build`. It also provides a +way to share build configurations across your team, so that everyone is +building images in a consistent way, with the same configuration. + +## The Bake file format + +You can write Bake files in HCL, YAML (Docker Compose files), or JSON. In +general, HCL is the most expressive and flexible format, which is why you'll +see it used in most of the examples in this documentation, and in projects that +use Bake. + +The properties that can be set for a target closely resemble the CLI flags for +`docker build`. For instance, consider the following `docker build` command: + +```console +$ docker build \ + -f Dockerfile \ + -t myapp:latest \ + --build-arg foo=bar \ + --no-cache \ + --platform linux/amd64,linux/arm64 \ + . +``` + +The Bake equivalent would be: + +```hcl +target "myapp" { + context = "." + dockerfile = "Dockerfile" + tags = ["myapp:latest"] + args = { + foo = "bar" + } + no-cache = true + platforms = ["linux/amd64", "linux/arm64"] +} +``` + +## Next steps + +To learn more about using Bake, see the following topics: + +- Learn how to define and use [targets](./targets.md) in Bake +- To see all the properties that can be set for a target, refer to the + [Bake file reference](/build/bake/reference/). diff --git a/content/build/bake/matrices.md b/content/build/bake/matrices.md new file mode 100644 index 00000000000..f859550cd51 --- /dev/null +++ b/content/build/bake/matrices.md @@ -0,0 +1,120 @@ +--- +title: Matrix targets +description: Learn how to define and use matrix targets in Bake to fork a single target into multiple different variants +keywords: build, buildx, bake, buildkit, matrix, hcl, json +--- + +A matrix strategy lets you fork a single target into multiple different +variants, based on parameters that you specify. This works in a similar way to +[Matrix strategies for GitHub Actions](https://docs.github.com/en/actions/using-jobs/using-a-matrix-for-your-jobs). +You can use this to reduce duplication in your Bake definition. + +The matrix attribute is a map of parameter names to lists of values. Bake +builds each possible combination of values as a separate target. + +Each generated target must have a unique name. To specify how target names +should resolve, use the name attribute. + +The following example resolves the app target to `app-foo` and `app-bar`. It +also uses the matrix value to define the [target build stage](/build/bake/reference/#targettarget). + +```hcl +target "app" { + name = "app-${tgt}" + matrix = { + tgt = ["foo", "bar"] + } + target = tgt +} +``` + +```console +$ docker buildx bake --print app +[+] Building 0.0s (0/0) +{ + "group": { + "app": { + "targets": [ + "app-foo", + "app-bar" + ] + }, + "default": { + "targets": [ + "app" + ] + } + }, + "target": { + "app-bar": { + "context": ".", + "dockerfile": "Dockerfile", + "target": "bar" + }, + "app-foo": { + "context": ".", + "dockerfile": "Dockerfile", + "target": "foo" + } + } +} +``` + +## Multiple axes + +You can specify multiple keys in your matrix to fork a target on multiple axes. +When using multiple matrix keys, Bake builds every possible variant. + +The following example builds four targets: + +- `app-foo-1-0` +- `app-foo-2-0` +- `app-bar-1-0` +- `app-bar-2-0` + +```hcl +target "app" { + name = "app-${tgt}-${replace(version, ".", "-")}" + matrix = { + tgt = ["foo", "bar"] + version = ["1.0", "2.0"] + } + target = tgt + args = { + VERSION = version + } +} +``` + +## Multiple values per matrix target + +If you want to differentiate the matrix on more than just a single value, you +can use maps as matrix values. Bake creates a target for each map, and you can +access the nested values using dot notation. + +The following example builds two targets: + +- `app-foo-1-0` +- `app-bar-2-0` + +```hcl +target "app" { + name = "app-${item.tgt}-${replace(item.version, ".", "-")}" + matrix = { + item = [ + { + tgt = "foo" + version = "1.0" + }, + { + tgt = "bar" + version = "2.0" + } + ] + } + target = item.tgt + args = { + VERSION = item.version + } +} +``` diff --git a/content/build/bake/overrides.md b/content/build/bake/overrides.md new file mode 100644 index 00000000000..6523b262b7d --- /dev/null +++ b/content/build/bake/overrides.md @@ -0,0 +1,332 @@ +--- +title: Overriding configurations +description: Learn how to override configurations in Bake files to build with different attributes. +keywords: build, buildx, bake, buildkit, hcl, json, overrides, configuration +aliases: + - /build/bake/configuring-build/ +--- + +Bake supports loading build definitions from files, but sometimes you need even +more flexibility to configure these definitions. For example, you might want to +override an attribute when building in a particular environment or for a +specific target. + +The following list of attributes can be overridden: + +- `args` +- `cache-from` +- `cache-to` +- `context` +- `dockerfile` +- `labels` +- `no-cache` +- `output` +- `platform` +- `pull` +- `secrets` +- `ssh` +- `tags` +- `target` + +To override these attributes, you can use the following methods: + +- [File overrides](#file-overrides) +- [CLI overrides](#command-line) +- [Environment variable overrides](#environment-variables) + +## File overrides + +You can load multiple Bake files that define build configurations for your +targets. This is useful when you want to separate configurations into different +files for better organization, or to conditionally override configurations +based on which files are loaded. + +### Default file lookup + +You can use the `--file` or `-f` flag to specify which files to load. +If you don't specify any files, Bake will use the following lookup order: + +1. `compose.yaml` +2. `compose.yml` +3. `docker-compose.yml` +4. `docker-compose.yaml` +5. `docker-bake.json` +6. `docker-bake.override.json` +7. `docker-bake.hcl` +8. `docker-bake.override.hcl` + +If more than one Bake file is found, all files are loaded and merged into a +single definition. Files are merged according to the lookup order. + +```console +$ docker buildx bake bake --print +[+] Building 0.0s (1/1) FINISHED + => [internal] load local bake definitions 0.0s + => => reading compose.yaml 45B / 45B 0.0s + => => reading docker-bake.hcl 113B / 113B 0.0s + => => reading docker-bake.override.hcl 65B / 65B +``` + +If merged files contain duplicate attribute definitions, those definitions are +either merged or overridden by the last occurrence, depending on the attribute. + +Bake will attempt to load all of the files in the order they are found. If +multiple files define the same target, attributes are either merged or +overridden. In the case of overrides, the last one loaded takes precedence. + +For example, given the following files: + +```hcl {title=docker-bake.hcl} +variable "TAG" { + default = "foo" +} + +target "default" { + tags = ["username/my-app:${TAG}"] +} +``` + +```hcl {title=docker-bake.override.hcl} +variable "TAG" { + default = "bar" +} +``` + +Since `docker-bake.override.hcl` is loaded last in the default lookup order, +the `TAG` variable is overridden with the value `bar`. + +```console +$ docker buildx bake --print +{ + "target": { + "default": { + "context": ".", + "dockerfile": "Dockerfile", + "tags": ["username/my-app:bar"] + } + } +} +``` + +### Manual file overrides + +You can use the `--file` flag to explicitly specify which files to load, +and use this as a way to conditionally apply override files. + +For example, you can create a file that defines a set of configurations for a +specific environment, and load it only when building for that environment. The +following example shows how to load an `override.hcl` file that sets the `TAG` +variable to `bar`. The `TAG` variable is then used in the `default` target. + +```hcl {title=docker-bake.hcl} +variable "TAG" { + default = "foo" +} + +target "default" { + tags = ["username/my-app:${TAG}"] +} +``` + +```hcl {title=overrides.hcl} +variable "TAG" { + default = "bar" +} +``` + +Printing the build configuration without the `--file` flag shows the `TAG` +variable is set to the default value `foo`. + +```console +$ docker buildx bake --print +{ + "target": { + "default": { + "context": ".", + "dockerfile": "Dockerfile", + "tags": [ + "username/my-app:foo" + ] + } + } +} +``` + +Using the `--file` flag to load the `overrides.hcl` file overrides the `TAG` +variable with the value `bar`. + +```console +$ docker buildx bake -f docker-bake.hcl -f overrides.hcl --print +{ + "target": { + "default": { + "context": ".", + "dockerfile": "Dockerfile", + "tags": [ + "username/my-app:bar" + ] + } + } +} +``` + +## Command line + +You can also override target configurations from the command line with the +[`--set` flag](../../reference/cli/docker/buildx/bake.md#set): + +```hcl +# docker-bake.hcl +target "app" { + args = { + mybuildarg = "foo" + } +} +``` + +```console +$ docker buildx bake --set app.args.mybuildarg=bar --set app.platform=linux/arm64 app --print +``` + +```json +{ + "group": { + "default": { + "targets": ["app"] + } + }, + "target": { + "app": { + "context": ".", + "dockerfile": "Dockerfile", + "args": { + "mybuildarg": "bar" + }, + "platforms": ["linux/arm64"] + } + } +} +``` + +Pattern matching syntax defined in [https://golang.org/pkg/path/#Match](https://golang.org/pkg/path/#Match) +is also supported: + +```console +$ docker buildx bake --set foo*.args.mybuildarg=value # overrides build arg for all targets starting with "foo" +$ docker buildx bake --set *.platform=linux/arm64 # overrides platform for all targets +$ docker buildx bake --set foo*.no-cache # bypass caching only for targets starting with "foo" +``` + +Complete list of attributes that can be overridden with `--set` are: + +- `args` +- `cache-from` +- `cache-to` +- `context` +- `dockerfile` +- `labels` +- `no-cache` +- `output` +- `platform` +- `pull` +- `secrets` +- `ssh` +- `tags` +- `target` + +## Environment variables + +You can also use environment variables to override configurations. + +Bake lets you use environment variables to override the value of a `variable` +block. Only `variable` blocks can be overridden with environment variables. +This means you need to define the variables in the bake file and then set the +environment variable with the same name to override it. + +The following example shows how you can define a `TAG` variable with a default +value in the Bake file, and override it with an environment variable. + +```hcl +variable "TAG" { + default = "latest" +} + +target "default" { + context = "." + dockerfile = "Dockerfile" + tags = ["docker.io/username/webapp:${TAG}"] +} +``` + +```console +$ export TAG=$(git rev-parse --short HEAD) +$ docker buildx bake --print webapp +``` + +The `TAG` variable is overridden with the value of the environment variable, +which is the short commit hash generated by `git rev-parse --short HEAD`. + +```json +{ + "group": { + "default": { + "targets": ["webapp"] + } + }, + "target": { + "webapp": { + "context": ".", + "dockerfile": "Dockerfile", + "tags": ["docker.io/username/webapp:985e9e9"] + } + } +} +``` + +### Type coercion + +Overriding non-string variables with environment variables is supported. Values +passed as environment variables are coerced into suitable types first. + +The following example defines a `PORT` variable with a default value of `8080`. +The `default` target uses a [ternary operator](expressions.md#ternary-operators) +to set the `PORT` variable to the value of the environment variable `PORT` +if it is greater than `1024`, otherwise it uses the default value. + +In this case, the `PORT` variable is coerced to an integer before the ternary +operator is evaluated. + +```hcl +default_port = 8080 + +variable "PORT" { + default = default_port +} + +target "default" { + args = { + PORT = PORT > 1024 ? PORT : default_port + } +} +``` + +Attempting to set the `PORT` variable with a value less than `1024` will result +in the default value being used. + +```console +$ PORT=80 docker buildx bake --print +``` + +```json +{ + "target": { + "default": { + "context": ".", + "dockerfile": "Dockerfile", + "args": { + "PORT": "8080" + } + } + } +} +``` diff --git a/content/build/bake/targets.md b/content/build/bake/targets.md new file mode 100644 index 00000000000..122c879b081 --- /dev/null +++ b/content/build/bake/targets.md @@ -0,0 +1,106 @@ +--- +title: Bake targets +description: Learn how to define and use targets in Bake +keywords: bake, target, targets, buildx, docker, buildkit, default +--- + +A target in a Bake file represents a build invocation. It holds all the +information you would normally pass to a `docker build` command using flags. + +```hcl +target "webapp" { + dockerfile = "webapp.Dockerfile" + tags = ["docker.io/username/webapp:latest"] + context = "https://github.com/username/webapp" +} +``` + +To build a target with Bake, pass name of the target to the `bake` command. + +```console +$ docker buildx bake webapp +``` + +You can build multiple targets at once by passing multiple target names to the +`bake` command. + +```console +$ docker buildx bake webapp api tests +``` + +## Default target + +If you don't specify a target when running `docker buildx bake`, Bake will +build the target named `default`. + +```hcl +target "default" { + dockerfile = "webapp.Dockerfile" + tags = ["docker.io/username/webapp:latest"] + context = "https://github.com/username/webapp" +} +``` + +To build this target, run `docker buildx bake` without any arguments: + +```console +$ docker buildx bake +``` + +## Target properties + +The properties you can set for a target closely resemble the CLI flags for +`docker build`, with a few additional properties that are specific to Bake. + +For all the properties you can set for a target, see the [Bake reference](/build/bake/reference#target). + +## Grouping targets + +You can group targets together using the `group` block. This is useful when you +want to build multiple targets at once. + +```hcl +group "all" { + targets = ["webapp", "api", "tests"] +} + +target "webapp" { + dockerfile = "webapp.Dockerfile" + tags = ["docker.io/username/webapp:latest"] + context = "https://github.com/username/webapp" +} + +target "api" { + dockerfile = "api.Dockerfile" + tags = ["docker.io/username/api:latest"] + context = "https://github.com/username/api" +} + +target "tests" { + dockerfile = "tests.Dockerfile" + contexts = { + webapp = "target:webapp", + api = "target:api", + } + output = ["type=local,dest=build/tests"] + context = "." +} +``` + +To build all the targets in a group, pass the name of the group to the `bake` +command. + +```console +$ docker buildx bake all +``` + +## Additional resources + +Refer to the following pages to learn more about Bake's features: + +- Learn how to use [variables](./variables.md) in Bake to make your build + configuration more flexible. +- Learn how you can use matrices to build multiple images with different + configurations in [Matrices](./matrices.md). +- Head to the [Bake file reference](/build/bake/reference/) to learn about all + the properties you can set in a Bake file, and its syntax. diff --git a/content/build/bake/variables.md b/content/build/bake/variables.md new file mode 100644 index 00000000000..dff87195d85 --- /dev/null +++ b/content/build/bake/variables.md @@ -0,0 +1,138 @@ +--- +title: Variables in Bake +description: +keywords: build, buildx, bake, buildkit, hcl, variables +--- + +You can define and use variables in a Bake file to set attribute values, +interpolate them into other values, and perform arithmetic operations. +Variables can be defined with default values, and can be overridden with +environment variables. + +## Using variables as attribute values + +Use the `variable` block to define a variable. + +```hcl +variable "TAG" { + default = "docker.io/username/webapp:latest" +} +``` + +The following example shows how to use the `TAG` variable in a target. + +```hcl +target "default" { + context = "." + dockerfile = "Dockerfile" + tags = [ TAG ] +} +``` + +## Interpolate variables into values + +Bake supports string interpolation of variables into values. You can use the +`${}` syntax to interpolate a variable into a value. The following example +defines a `TAG` variable with a value of `latest`. + +```hcl +variable "TAG" { + default = "latest" +} +``` + +To interpolate the `TAG` variable into the value of an attribute, use the +`${TAG}` syntax. + +```hcl +target "default" { + context = "." + dockerfile = "Dockerfile" + tags = ["docker.io/username/webapp:${TAG}"] +} +``` + +Printing the Bake file with the `--print` flag shows the interpolated value in +the resolved build configuration. + +```console +$ docker buildx bake --print +``` + +```json +{ + "group": { + "default": { + "targets": ["webapp"] + } + }, + "target": { + "webapp": { + "context": ".", + "dockerfile": "Dockerfile", + "tags": ["docker.io/username/webapp:latest"] + } + } +} +``` + +## Using variables in variables across files + +When multiple files are specified, one file can use variables defined in +another file. In the following example, the `vars.hcl` file defines a +`BASE_IMAGE` variable with a default value of `docker.io/library/alpine`. + +```hcl {title=vars.hcl} +variable "BASE_IMAGE" { + default = "docker.io/library/alpine" +} +``` + +The following `docker-bake.hcl` file defines a `BASE_LATEST` variable that +references the `BASE_IMAGE` variable. + +```hcl {title=docker-bake.hcl} +variable "BASE_LATEST" { + default = "${BASE_IMAGE}:latest" +} + +target "default" { + contexts = { + base = BASE_LATEST + } +} +``` + +When you print the resolved build configuration, using the `-f` flag to specify +the `vars.hcl` and `docker-bake.hcl` files, you see that the `BASE_LATEST` +variable is resolved to `docker.io/library/alpine:latest`. + +```console +$ docker buildx bake -f vars.hcl -f docker-bake.hcl --print app +``` + +```json +{ + "target": { + "default": { + "context": ".", + "contexts": { + "base": "docker.io/library/alpine:latest" + }, + "dockerfile": "Dockerfile" + } + } +} +``` + +## Additional resources + +Here are some additional resources that show how you can use variables in Bake: + +- You can override `variable` values using environment variables. See + [Overriding configurations](./overrides.md#environment-variables) for more + information. +- You can refer to and use global variables in functions. See [HCL + functions](./funcs.md#variables-in-functions) +- You can use variable values when evaluating expressions. See [Expression + evaluation](./expressions.md#expressions-with-variables) diff --git a/content/build/release-notes.md b/content/build/release-notes.md index 8134c90df9a..7a334495aac 100644 --- a/content/build/release-notes.md +++ b/content/build/release-notes.md @@ -415,7 +415,7 @@ The full release note for this release is available for initializing the context with a value of a local OCI layout directory. E.g. `--build-context stagename=oci-layout://path/to/dir`. This feature requires BuildKit v0.11.0+ and Dockerfile 1.5.0+. [docker/buildx#1456](https://github.com/docker/buildx/issues/1456) -- Bake now supports [resource interpolation](bake/configuring-build.md#resource-interpolation) +- Bake now supports [resource interpolation](bake/inheritance.md#reusing-single-attribute-from-targets) where you can reuse the values from other target definitions. [docker/buildx#1434](https://github.com/docker/buildx/issues/1434) - Buildx will now automatically forward `SOURCE_DATE_EPOCH` environment variable if it is defined in your environment. This feature is meant to be used with @@ -605,7 +605,7 @@ For more details, see the complete release notes in the [Buildx GitHub repositor - Build command now accepts `--build-context` flag to [define additional named build contexts](/reference/cli/docker/buildx/build/#build-context) for your builds. [docker/buildx#904](https://github.com/docker/buildx/issues/904) -- Bake definitions now support [defining dependencies between targets](bake/build-contexts.md) +- Bake definitions now support [defining dependencies between targets](bake/contexts.md) and using the result of one target in another build. [docker/buildx#928](https://github.com/docker/buildx/issues/928), [docker/buildx#965](https://github.com/docker/buildx/issues/965), diff --git a/data/toc.yaml b/data/toc.yaml index c64a7436a9b..32fbbf0afcb 100644 --- a/data/toc.yaml +++ b/data/toc.yaml @@ -1961,14 +1961,26 @@ Manuals: section: - path: /build/bake/ title: Overview + - path: /build/bake/introduction/ + title: Introduction + - path: /build/bake/targets/ + title: Targets + - path: /build/bake/inheritance/ + title: Inheritance + - path: /build/bake/variables/ + title: Variables + - path: /build/bake/expressions/ + title: Expressions + - path: /build/bake/funcs/ + title: Functions + - path: /build/bake/matrices/ + title: Matrices + - path: /build/bake/contexts/ + title: Contexts + - path: /build/bake/overrides/ + title: Overriding configuration - path: /build/bake/reference/ title: Bake file reference - - path: /build/bake/configuring-build/ - title: Configuring builds - - path: /build/bake/advanced/ - title: Advanced patterns - - path: /build/bake/build-contexts/ - title: Build contexts and linking targets - path: /build/bake/compose-file/ title: Building from Compose file - path: /build/bake/remote-definition/ diff --git a/hugo_stats.json b/hugo_stats.json index c3ad93c208a..d7cc453f384 100644 --- a/hugo_stats.json +++ b/hugo_stats.json @@ -51,7 +51,6 @@ "GitHub-Actions", "GitLab", "Go", - "HCL", "HTTP", "Heredocs", "Hub",