"nofile=1024:1024"
]
}
```
> [!NOTE]
> If you do not provide a `hard limit`, the `soft limit` is used
> for both values. If no `ulimits` are set, they are inherited from
> the default `ulimits` set on the daemon.
> [!NOTE]
> In most cases, it is recommended to let the builder automatically determine
> the appropriate configurations. Manual adjustments should only be considered
> when specific performance tuning is required for complex build scenarios.
## Group
Groups allow you to invoke multiple builds (targets) at once.
```hcl
group "default" {
targets = ["db", "webapp-dev"]
}
target "webapp-dev" {
dockerfile = "Dockerfile.webapp"
tags = ["docker.io/username/webapp:latest"]
}
target "db" {
dockerfile = "Dockerfile.db"
tags = ["docker.io/username/db"]
}
```
Groups take precedence over targets, if both exist with the same name.
The following bake file builds the `default` group.
Bake ignores the `default` target.
```hcl
target "default" {
dockerfile-inline = "FROM ubuntu"
}
group "default" {
targets = ["alpine", "debian"]
}
target "alpine" {
dockerfile-inline = "FROM alpine"
}
target "debian" {
dockerfile-inline = "FROM debian"
}
```
## Variable
The HCL file format supports variable block definitions.
You can use variables as build arguments in your Dockerfile,
or interpolate them in attribute values in your Bake file.
```hcl
variable "TAG" {
type = string
default = "latest"
}
target "webapp-dev" {
dockerfile = "Dockerfile.webapp"
tags = ["docker.io/username/webapp:${TAG}"]
}
```
You can assign a default value for a variable in the Bake file,
or assign a `null` value to it. If you assign a `null` value,
Buildx uses the default value from the Dockerfile instead.
You can override variable defaults set in the Bake file using environment variables.
The following example sets the `TAG` variable to `dev`,
overriding the default `latest` value shown in the previous example.
```console
$ TAG=dev docker buildx bake webapp-dev
```
Variables can also be assigned an explicit type.
If provided, it will be used to validate the default value (if set), as well as any overrides.
This is particularly useful when using complex types which are intended to be overridden.
The previous example could be expanded to apply an arbitrary series of tags.
```hcl
variable "TAGS" {
default = ["latest"]
type = list(string)
}
target "webapp-dev" {
dockerfile = "Dockerfile.webapp"
tags = [for tag in TAGS: "docker.io/username/webapp:${tag}"]
}
```
This example shows how to generate three tags without changing the file
or using custom functions/parsing:
```console
$ TAGS=dev,latest,2 docker buildx bake webapp-dev
```
### Variable typing
The following primitive types are available:
* `string`
* `number`
* `bool`
The type is expressed like a keyword; it must be expressed as a literal:
```hcl
variable "OK" {
type = string
}
# cannot be an actual string
variable "BAD" {
type = "string"
}
# cannot be the result of an expression
variable "ALSO_BAD" {
type = lower("string")
}
```
Specifying primitive types can be valuable to show intent (especially when a default is not provided),
but bake will generally behave as expected without explicit typing.
Complex types are expressed with "type constructors"; they are:
* `tuple([<type>,...])`
* `list(<type>)`
* `set(<type>)`
* `map(<type>)`
* `object({<attr>=<type>},...})`
The following are examples of each of those, as well as how the (optional) default value would be expressed:
```hcl
# structured way to express "1.2.3-alpha"
variable "MY_VERSION" {
type = tuple([number, number, number, string])
default = [1, 2, 3, "alpha"]
}
# JDK versions used in a matrix build
variable "JDK_VERSIONS" {
type = list(number)
default = [11, 17, 21]
}
# better way to express the previous example; this will also
# enforce set semantics and allow use of set-based functions
variable "JDK_VERSIONS" {
type = set(number)
default = [11, 17, 21]
}
# with the help of lookup(), translate a 'feature' to a tag