build(bake): add expressions and functions descriptions

Signed-off-by: David Karlsson <35727626+dvdksn@users.noreply.github.com>
This commit is contained in:
David Karlsson 2024-06-17 13:35:25 +02:00
parent d04c833e69
commit e70449124f
4 changed files with 300 additions and 350 deletions

View File

@ -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"
}
}
}
}
```

View File

@ -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"
}
}
}
}
```

152
content/build/bake/funcs.md Normal file
View File

@ -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"]
}
}
}
```

View File

@ -1959,12 +1959,14 @@ Manuals:
title: Inheritance
- path: /build/bake/variables/
title: Variables
- path: /build/bake/expressions/
title: Expressions
- path: /build/bake/funcs/
title: Functions
- path: /build/bake/overrides/
title: Overriding configuration
- path: /build/bake/reference/
title: Bake file reference
- path: /build/bake/advanced/
title: Advanced patterns
- path: /build/bake/build-contexts/
title: Build contexts and linking targets
- path: /build/bake/compose-file/