1. docker buildx bake
从文件构建镜像
Bake 是一个高级的构建命令。每个指定的目标将作为构建的一部分并行运行。
[!NOTE|style:flat] 请注意,如果需要的话,
buildx bake
命令可能会接收到向后不兼容的特性。我们正在寻找改进命令和进一步扩展功能的反馈。
1.1. 帮助
# docker buildx bake --help
Usage: docker buildx bake [OPTIONS] [TARGET...]
Build from a file
Aliases:
bake, f
Options:
--builder string Override the configured builder instance
-f, --file stringArray Build definition file
--load Shorthand for --set=*.output=type=docker
--no-cache Do not use cache when building the image
--print Print the options without building
--progress string Set type of progress output (auto, plain, tty). Use plain to show container output (default "auto")
--pull Always attempt to pull a newer version of the image
--push Shorthand for --set=*.output=type=registry
--set stringArray Override target value (eg: targetpattern.key=value)
1.2. 选项
参数 | 类型 | 默认 | 描述 |
---|---|---|---|
[`--builder`](#builder) | `string` | 指定一个明确的 builder 实例 | |
[`-f`](#file), [`--file`](#file) | `stringArray` | 指定一个构建定义文件 | |
`--load` | 缩写 `--set=*.output=type=docker` | ||
`--metadata-file` | `string` | 将构建的的结果元数据写入到一个文件 | |
[`--no-cache`](#no-cache) | 在构建镜像时不使用缓存 | ||
[`--print`](#print) | 打印构建结果不需要开始构建 | ||
[`--progress`](#progress) | `string` | `auto` | 设置进度输出(auto,plain,tty),使用 plain 显示容器标准输出(默认是 “auto”) |
[`--pull`](#pull) | 总是尝试下载所有最新版本的镜像 | ||
`--push` | 缩写 `--set=*.output=type=registry` | ||
[`--set`](#set) | `stringArray` | 覆盖目标的 values 配置(如:targetpattern.key=value) |
1.3. 示例
1.3.1. 指定一个构建定义文件 (-f, --file)
默认情况下,dockerx bake
会查找当前目录下的构建定义文件,以下内容默认会被识别:
docker-compose.yml
docker-compose.yaml
docker-bake.json
docker-bake.override.json
docker-bake.hcl
docker-bake.override.hcl
使用 -f
/ --file
来指定构建定义文件使用。该文件可以是 Docker Compose ,JSON 或 HCL 文件。如果指定多个文件,这些文件会同时读取并整合配置。
这个示例使用 docker-compose.dev.yaml
的 Docker Compose 文件作为构建定义文件,并且构建文件中的所有目标:
$ docker buildx bake -f docker-compose.dev.yaml
[+] Building 66.3s (30/30) FINISHED
=> [frontend internal] load build definition from Dockerfile 0.1s
=> => transferring dockerfile: 36B 0.0s
=> [backend internal] load build definition from Dockerfile 0.2s
=> => transferring dockerfile: 3.73kB 0.0s
=> [database internal] load build definition from Dockerfile 0.1s
=> => transferring dockerfile: 5.77kB 0.0s
...
可以通过名称来构建指定的目标。这个例子是构建 docker-compose.dev.yaml
文件中的 backend
和 database
目标,跳过 frontend
的构建。
$ docker buildx bake -f docker-compose.dev.yaml backend database
[+] Building 2.4s (13/13) FINISHED
=> [backend internal] load build definition from Dockerfile 0.1s
=> => transferring dockerfile: 81B 0.0s
=> [database internal] load build definition from Dockerfile 0.2s
=> => transferring dockerfile: 36B 0.0s
=> [backend internal] load .dockerignore 0.3s
...
也可以使用远程的 git
进行 bake 定义:
$ docker buildx bake "https://github.com/docker/cli.git#v20.10.11" --print
#1 [internal] load git source https://github.com/docker/cli.git#v20.10.11
#1 0.745 e8f1871b077b64bcb4a13334b7146492773769f7 refs/tags/v20.10.11
#1 2.022 From https://github.com/docker/cli
#1 2.022 * [new tag] v20.10.11 -> v20.10.11
#1 DONE 2.9s
{
"group": {
"default": {
"targets": [
"binary"
]
}
},
"target": {
"binary": {
"context": "https://github.com/docker/cli.git#v20.10.11",
"dockerfile": "Dockerfile",
"args": {
"BASE_VARIANT": "alpine",
"GO_STRIP": "",
"VERSION": ""
},
"target": "binary",
"platforms": [
"local"
],
"output": [
"build"
]
}
}
}
As you can see the context is fixed to https://github.com/docker/cli.git
even if
no context is actually defined
in the definition.
如果你想从 bake 文件中访问 bake 命令的主上下文,你可以使用 BAKE_CMD_CONTEXT
内置变量:
$ cat https://raw.githubusercontent.com/tonistiigi/buildx/remote-test/docker-bake.hcl
target "default" {
context = BAKE_CMD_CONTEXT
dockerfile-inline = <<EOT
FROM alpine
WORKDIR /src
COPY . .
RUN ls -l && stop
EOT
}
$ docker buildx bake "https://github.com/tonistiigi/buildx.git#remote-test" --print
{
"target": {
"default": {
"context": ".",
"dockerfile": "Dockerfile",
"dockerfile-inline": "FROM alpine\nWORKDIR /src\nCOPY . .\nRUN ls -l \u0026\u0026 stop\n"
}
}
}
$ touch foo bar
$ docker buildx bake "https://github.com/tonistiigi/buildx.git#remote-test"
...
> [4/4] RUN ls -l && stop:
#8 0.101 total 0
#8 0.102 -rw-r--r-- 1 root root 0 Jul 27 18:47 bar
#8 0.102 -rw-r--r-- 1 root root 0 Jul 27 18:47 foo
#8 0.102 /bin/sh: stop: not found
$ docker buildx bake "https://github.com/tonistiigi/buildx.git#remote-test" "https://github.com/docker/cli.git#v20.10.11" --print
#1 [internal] load git source https://github.com/tonistiigi/buildx.git#remote-test
#1 0.429 577303add004dd7efeb13434d69ea030d35f7888 refs/heads/remote-test
#1 CACHED
{
"target": {
"default": {
"context": "https://github.com/docker/cli.git#v20.10.11",
"dockerfile": "Dockerfile",
"dockerfile-inline": "FROM alpine\nWORKDIR /src\nCOPY . .\nRUN ls -l \u0026\u0026 stop\n"
}
}
}
$ docker buildx bake "https://github.com/tonistiigi/buildx.git#remote-test" "https://github.com/docker/cli.git#v20.10.11"
...
> [4/4] RUN ls -l && stop:
#8 0.136 drwxrwxrwx 5 root root 4096 Jul 27 18:31 kubernetes
#8 0.136 drwxrwxrwx 3 root root 4096 Jul 27 18:31 man
#8 0.136 drwxrwxrwx 2 root root 4096 Jul 27 18:31 opts
#8 0.136 -rw-rw-rw- 1 root root 1893 Jul 27 18:31 poule.yml
#8 0.136 drwxrwxrwx 7 root root 4096 Jul 27 18:31 scripts
#8 0.136 drwxrwxrwx 3 root root 4096 Jul 27 18:31 service
#8 0.136 drwxrwxrwx 2 root root 4096 Jul 27 18:31 templates
#8 0.136 drwxrwxrwx 10 root root 4096 Jul 27 18:31 vendor
#8 0.136 -rwxrwxrwx 1 root root 9620 Jul 27 18:31 vendor.conf
#8 0.136 /bin/sh: stop: not found
1.3.2. 在构建镜像时不使用缓存 (--no-cache)
和 build --no-cache
类似。在构建镜像时不使用缓存
1.3.3. 打印构建结果不需要开始构建 (--print)
在 JSON 中打印想要构建的目标的结果选项格式,无需开始构建。
$ docker buildx bake -f docker-bake.hcl --print db
{
"group": {
"default": {
"targets": [
"db"
]
}
},
"target": {
"db": {
"context": "./",
"dockerfile": "Dockerfile",
"tags": [
"docker.io/tiborvass/db"
]
}
}
}
1.3.4. 设置构建进度类型 (--progress)
和 dockerx build --progress
类似。 设置进度显示类型(支持 auto,plain,tty),默认 "auto".
也可以使用
BUILDKIT_PROGRESS
环境变量来设置
以下构建示例使用 plain
的输出类型:
$ docker buildx bake --progress=plain
#2 [backend internal] load build definition from Dockerfile.test
#2 sha256:de70cb0bb6ed8044f7b9b1b53b67f624e2ccfb93d96bb48b70c1fba562489618
#2 ...
#1 [database internal] load build definition from Dockerfile.test
#1 sha256:453cb50abd941762900a1212657a35fc4aad107f5d180b0ee9d93d6b74481bce
#1 transferring dockerfile: 36B done
#1 DONE 0.1s
...
1.3.5. 在构建是尝试下载最新版本镜像 (--pull)
参考 buildx build --pull
1.3.6. 通过命令行覆盖目标配置 (--set)
--set targetpattern.key[.subkey]=value
通过命令行覆盖目标配置
格式支持定义 https://golang.org/pkg/path/#Match
$ docker buildx bake --set target.args.mybuildarg=value
$ docker buildx bake --set target.platform=linux/arm64
$ 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'
可设置字段的完整列表:
args
, cache-from
, cache-to
, context
, dockerfile
, labels
, no-cache
,
output
, platform
, pull
, secrets
, ssh
, tags
, target
1.3.7. 文件定义
除了组合文件外,bake 还支持 JSON 和一个等价的 HCL 文件 用于定义构建组和目标的格式。
目标反映了单个 docker 构建调用的相同选项 你可以指定 docker build
。组就是一组目标。
多个文件可以包含相同的目标和最终的构建选项,通过将它们合并在一起来决定。
在组合文件的情况下,每个服务对应一个目标。
一个组可以通过 targets
选项指定它的目标列表。一个目标可以通过将 inherits
选项设置为目标或列表来继承构建选项,或要继承的组。
注: bake 命令的设计正在进行中,用户体验可能会基于反馈发生变化。
HCL 定义示例:
group "default" {
targets = ["db", "webapp-dev"]
}
target "webapp-dev" {
dockerfile = "Dockerfile.webapp"
tags = ["docker.io/username/webapp"]
}
target "webapp-release" {
inherits = ["webapp-dev"]
platforms = ["linux/amd64", "linux/arm64"]
}
target "db" {
dockerfile = "Dockerfile.db"
tags = ["docker.io/username/db"]
}
Complete list of valid target fields:
args
, cache-from
, cache-to
, context
, contexts
, dockerfile
, inherits
, labels
,
no-cache
, no-cache-filter
, output
, platform
, pull
, secrets
, ssh
, tags
, target
1.3.8. 全局作用域的属性
您可以在 HCL/JSON 中定义全局作用域属性,并将它们用于代码重用以及设置变量的值。这意味着你可以做一个“只有数据”的HCL文件,使用你想要设置/覆盖的值,并在正则列表中使用它输出文件。
# docker-bake.hcl
variable "FOO" {
default = "abc"
}
target "app" {
args = {
v1 = "pre-${FOO}"
}
}
你可以直接使用这个文件:
$ docker buildx bake --print app
{
"group": {
"default": {
"targets": [
"app"
]
}
},
"target": {
"app": {
"context": ".",
"dockerfile": "Dockerfile",
"args": {
"v1": "pre-abc"
}
}
}
}
或者创建一个覆盖配置文件:
# env.hcl
WHOAMI="myuser"
FOO="def-${WHOAMI}"
同时调用 bake 和这两个文件:
$ docker buildx bake -f docker-bake.hcl -f env.hcl --print app
{
"group": {
"default": {
"targets": [
"app"
]
}
},
"target": {
"app": {
"context": ".",
"dockerfile": "Dockerfile",
"args": {
"v1": "pre-def-myuser"
}
}
}
}
1.3.9. HCL 变量和函数
类似于 Terraform 提供的方法定义变量, HCL 文件格式也支持变量块定义。这些都可以使用当前环境提供的值定义变量,或未设置时的默认值。
go-cty提供的 一组常用函数 , 可以在 HCL 文件中使用。此外,用户定义函数 也支持。
使用插值来标记图像的 git sha
Bake 支持变量块,它被分配给匹配的环境变量或默认值。
# docker-bake.hcl
variable "TAG" {
default = "latest"
}
group "default" {
targets = ["webapp"]
}
target "webapp" {
tags = ["docker.io/username/webapp:${TAG}"]
}
或者,在 json 格式:
{
"variable": {
"TAG": {
"default": "latest"
}
}
"group": {
"default": {
"targets": ["webapp"]
}
},
"target": {
"webapp": {
"tags": ["docker.io/username/webapp:${TAG}"]
}
}
}
$ docker buildx bake --print webapp
{
"group": {
"default": {
"targets": [
"webapp"
]
}
},
"target": {
"webapp": {
"context": ".",
"dockerfile": "Dockerfile",
"tags": [
"docker.io/username/webapp:latest"
]
}
}
}
$ TAG=$(git rev-parse --short HEAD) docker buildx bake --print webapp
{
"group": {
"default": {
"targets": [
"webapp"
]
}
},
"target": {
"webapp": {
"context": ".",
"dockerfile": "Dockerfile",
"tags": [
"docker.io/username/webapp:985e9e9"
]
}
}
}
使用 add
函数
你可以使用 go-cty
stdlib functions.
这里示例 add
function.
# docker-bake.hcl
variable "TAG" {
default = "latest"
}
group "default" {
targets = ["webapp"]
}
target "webapp" {
args = {
buildno = "${add(123, 1)}"
}
}
$ docker buildx bake --print webapp
{
"group": {
"default": {
"targets": [
"webapp"
]
}
},
"target": {
"webapp": {
"context": ".",
"dockerfile": "Dockerfile",
"args": {
"buildno": "124"
}
}
}
}
自定义 increment
函数
支持 用户自定义函数.
这个例子定了一个单间的 increment
函数
# docker-bake.hcl
function "increment" {
params = [number]
result = number + 1
}
group "default" {
targets = ["webapp"]
}
target "webapp" {
args = {
buildno = "${increment(123)}"
}
}
$ docker buildx bake --print webapp
{
"group": {
"default": {
"targets": [
"webapp"
]
}
},
"target": {
"webapp": {
"context": ".",
"dockerfile": "Dockerfile",
"args": {
"buildno": "124"
}
}
}
}
使用 notequal
可以保障只在变量非空时添加 tag
这里使用条件判断函数 notequal
,使用方式和 equal
类似。
# docker-bake.hcl
variable "TAG" {default="" }
group "default" {
targets = [
"webapp",
]
}
target "webapp" {
context="."
dockerfile="Dockerfile"
tags = [
"my-image:latest",
notequal("",TAG) ? "my-image:${TAG}": "",
]
}
$ docker buildx bake --print webapp
{
"group": {
"default": {
"targets": [
"webapp"
]
}
},
"target": {
"webapp": {
"context": ".",
"dockerfile": "Dockerfile",
"tags": [
"my-image:latest"
]
}
}
}
在函数中使用变量
你可以像目标块一样将变量引用到其他变量。Stdlib函数也可以被调用,但是用户函数目前不能被调用。
# docker-bake.hcl
variable "REPO" {
default = "user/repo"
}
function "tag" {
params = [tag]
result = ["${REPO}:${tag}"]
}
target "webapp" {
tags = tag("v1")
}
$ docker buildx bake --print webapp
{
"group": {
"default": {
"targets": [
"webapp"
]
}
},
"target": {
"webapp": {
"context": ".",
"dockerfile": "Dockerfile",
"tags": [
"user/repo:v1"
]
}
}
}
跨文件在变量中使用变量
当指定多个文件时,一个文件可以使用另一个文件中定义的变量。
# docker-bake1.hcl
variable "FOO" {
default = upper("${BASE}def")
}
variable "BAR" {
default = "-${FOO}-"
}
target "app" {
args = {
v1 = "pre-${BAR}"
}
}
# docker-bake2.hcl
variable "BASE" {
default = "abc"
}
target "app" {
args = {
v2 = "${FOO}-post"
}
}
$ docker buildx bake -f docker-bake1.hcl -f docker-bake2.hcl --print app
{
"group": {
"default": {
"targets": [
"app"
]
}
},
"target": {
"app": {
"context": ".",
"dockerfile": "Dockerfile",
"args": {
"v1": "pre--ABCDEF-",
"v2": "ABCDEF-post"
}
}
}
}
使用类型的变量
也可以接受非字符串变量。传递给 env 的值首先被解析为合适的类型。
# 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"
}
}
$ docker buildx bake --print app
{
"group": {
"default": {
"targets": [
"app"
]
}
},
"target": {
"app": {
"context": ".",
"dockerfile": "Dockerfile",
"args": {
"v1": "lower",
"v2": "yes"
}
}
}
}
1.3.10. 定义额外的构建上下文和链接目标
除了定义构建上下文的主 context
外,每个目标还可以通过一个用 context
键定义的映射来定义额外的命名上下文。这些值映射到build 命令中的 ——build-context
标志。
在 Dockerfile 中,这些上下文可以与 FROM
指令或 --from
标志一起使用。
该值可以是本地源目录、容器镜像(带有 docker-image:// 前缀)、Git URL、HTTP URL 或 Bake 文件中另一个目标的名称(带有 target: 前缀)。
引用 alpine image
# Dockerfile
FROM alpine
RUN echo "Hello world"
# docker-bake.hcl
target "app" {
contexts = {
alpine = "docker-image://alpine:3.13"
}
}
使用额外的目录
# Dockerfile
FROM scratch AS src
FROM golang
COPY --from=src . .
# docker-bake.hcl
target "app" {
contexts = {
src = "../path/to/source"
}
}
使用一个目标的结果作为另一个目标的基础镜像
要使用一个目标的结果作为另一个目标的构建上下文,请使用 target:
前缀指定目标名称。
# Dockerfile
FROM baseapp
RUN echo "Hello world"
# docker-bake.hcl
target "base" {
dockerfile = "baseapp.Dockerfile"
}
target "app" {
contexts = {
baseapp = "target:base"
}
}
请注意,在大多数情况下,对于类似的行为,你应该只使用一个带有多个目标的多阶段 Dockerfile。当你有多个 Dockerfile,但不能轻易合并成一个 Dockerfile 时,推荐使用这种情况。
1.3.11. Compose 的扩展字段
Special extension
field x-bake
can be used in your compose file to evaluate fields that are not
(yet) available in the build definition.
# docker-compose.yml
services:
addon:
image: ct-addon:bar
build:
context: .
dockerfile: ./Dockerfile
args:
CT_ECR: foo
CT_TAG: bar
x-bake:
tags:
- ct-addon:foo
- ct-addon:alp
platforms:
- linux/amd64
- linux/arm64
cache-from:
- user/app:cache
- type=local,src=path/to/cache
cache-to: type=local,dest=path/to/cache
pull: true
aws:
image: ct-fake-aws:bar
build:
dockerfile: ./aws.Dockerfile
args:
CT_ECR: foo
CT_TAG: bar
x-bake:
secret:
- id=mysecret,src=./secret
- id=mysecret2,src=./secret2
platforms: linux/arm64
output: type=docker
no-cache: true
$ docker buildx bake --print
{
"group": {
"default": {
"targets": [
"aws",
"addon"
]
}
},
"target": {
"addon": {
"context": ".",
"dockerfile": "./Dockerfile",
"args": {
"CT_ECR": "foo",
"CT_TAG": "bar"
},
"tags": [
"ct-addon:foo",
"ct-addon:alp"
],
"cache-from": [
"user/app:cache",
"type=local,src=path/to/cache"
],
"cache-to": [
"type=local,dest=path/to/cache"
],
"platforms": [
"linux/amd64",
"linux/arm64"
],
"pull": true
},
"aws": {
"context": ".",
"dockerfile": "./aws.Dockerfile",
"args": {
"CT_ECR": "foo",
"CT_TAG": "bar"
},
"tags": [
"ct-fake-aws:bar"
],
"secret": [
"id=mysecret,src=./secret",
"id=mysecret2,src=./secret2"
],
"platforms": [
"linux/arm64"
],
"output": [
"type=docker"
],
"no-cache": true
}
}
}
Complete list of valid fields for x-bake
:
tags
, cache-from
, cache-to
, secret
, ssh
, platforms
, output
,
pull
, no-cache
, no-cache-filter
1.3.12. 内置变数
BAKE_CMD_CONTEXT
can be used to access the maincontext
for bake commandfrom a bake file that has been imported remotely.BAKE_LOCAL_PLATFORM
returns the current platform's default platform specification (e.g.linux/amd64
).