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 文件中的 backenddatabase 目标,跳过 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 main context 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).

2. 参考

Copyright © 温玉 2021 | 浙ICP备2020032454号 all right reserved,powered by Gitbook该文件修订时间: 2023-05-22 14:19:45

results matching ""

    No results matching ""