Bake 中的繼承

目標可以使用 inherits 屬性從其他目標繼承屬性。例如,假設您有一個為開發環境構建 Docker 映象的目標

docker-bake.hcl
target "app-dev" {
  args = {
    GO_VERSION = "1.24"
  }
  tags = ["docker.io/username/myapp:dev"]
  labels = {
    "org.opencontainers.image.source" = "https://github.com/username/myapp"
    "org.opencontainers.image.author" = "moby.whale@example.com"
  }
}

您可以建立一個新目標,該目標使用相同的構建配置,但針對生產構建的屬性略有不同。在此示例中,app-release 目標繼承了 app-dev 目標,但覆蓋了 tags 屬性並添加了新的 platforms 屬性

docker-bake.hcl
target "app-release" {
  inherits = ["app-dev"]
  tags = ["docker.io/username/myapp:latest"]
  platforms = ["linux/amd64", "linux/arm64"]
}

常用的可複用目標

一種常見的繼承模式是定義一個通用目標,其中包含專案中所有或許多構建目標的共享屬性。例如,以下 _common 目標定義了一組公共構建引數

docker-bake.hcl
target "_common" {
  args = {
    GO_VERSION = "1.24"
    BUILDKIT_CONTEXT_KEEP_GIT_DIR = 1
  }
}

然後,您可以在其他目標中繼承 _common 目標以應用共享屬性

docker-bake.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"]
}

覆蓋繼承的屬性

當一個目標繼承另一個目標時,它可以覆蓋任何繼承的屬性。例如,以下目標覆蓋了繼承目標的 args 屬性

docker-bake.hcl
target "app-dev" {
  inherits = ["_common"]
  args = {
    GO_VERSION = "1.17"
  }
  tags = ["docker.io/username/myapp:dev"]
}

app-release 中的 GO_VERSION 引數設定為 1.17,它覆蓋了 app-dev 目標的 GO_VERSION 引數。

有關覆蓋屬性的更多資訊,請參閱覆蓋配置頁面。

從多個目標繼承

inherits 屬性是一個列表,這意味著您可以從多個其他目標重用屬性。在以下示例中,app-release 目標重用了 app-dev_common 目標的屬性。

docker-bake.hcl
target "_common" {
  args = {
    GO_VERSION = "1.24"
    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"]
}

當從多個目標繼承屬性且存在衝突時,inherits 列表中最後出現的目標具有優先權。前面的示例在 _common 目標中定義了 BUILDKIT_CONTEXT_KEEP_GIT_DIR,並在 app-dev 目標中覆蓋了它。

app-release 目標繼承了 app-dev 目標和 _common 目標。app-dev 目標中的 BUILDKIT_CONTEXT_KEEP_GIT_DIR 引數設定為 0,而 _common 目標中設定為 1。app-release 目標中的 BUILDKIT_CONTEXT_KEEP_GIT_DIR 引數設定為 1,而不是 0,因為 _common 目標出現在繼承列表的最後。

從目標中重用單個屬性

如果您只想從一個目標繼承單個屬性,您可以使用點表示法從另一個目標引用該屬性。例如,在以下 Bake 檔案中,bar 目標重用了 foo 目標的 tags 屬性

docker-bake.hcl
target "foo" {
  dockerfile = "foo.Dockerfile"
  tags       = ["myapp:latest"]
}
target "bar" {
  dockerfile = "bar.Dockerfile"
  tags       = target.foo.tags
}