Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generating tags for multiple bake targets #398

Open
Pesa opened this issue Apr 1, 2024 · 5 comments
Open

Generating tags for multiple bake targets #398

Pesa opened this issue Apr 1, 2024 · 5 comments

Comments

@Pesa
Copy link

Pesa commented Apr 1, 2024

Description

Let's say I have the following docker-bake.hcl:

group "default" {
  targets = ["foo", "bar"]
}

target "foo" {
  dockerfile = "Dockerfile.foo"
  tags = ["my/foo:latest"]
}

target "bar" {
  dockerfile = "Dockerfile.bar"
  tags = ["my/bar:latest"]
}

The tags listed above function a bit like defaults, i.e., they're used when I run bake locally for testing. On GitHub Actions, however, I'd like to use docker/metadata-action to generate a list of tags based on various criteria (semver, date, etc...). These generated tags should replace the :latest tag from docker-bake.hcl, but I still want to keep the base name of the two images (my/foo and my/bar).

This would be trivial to accomplish with a single target (using the images input), but I didn't find a way to do it for multiple targets, where each target has a distinct image name.

Apologies if I missed something obvious (seems odd that this use case isn't already supported, since the whole point of bake is orchestrating the build of multiple targets).

@crazy-max
Copy link
Member

You can use the matrix feature for this purpose, like:

target "default" {
  name = "build-${tgt}"
  matrix = {
    tgt = ["foo", "bar"]
  }
  dockerfile = "Dockerfile.${tgt}"
  tags = ["my/${tgt}:latest"]
}

@Pesa
Copy link
Author

Pesa commented Jun 14, 2024

@crazy-max sorry, I'm not sure I understand. How would I combine the matrix with the tags generated by docker/metadata-action? If I set:

inherits = ["docker-metadata-action"]

isn't that going to overwrite the whole tag my/${tgt}:latest?

@Pesa
Copy link
Author

Pesa commented Jun 14, 2024

Basically, I would need something like this:

// docker-bake.hcl

target "default" {
  name = "${tgt}-${version}"
  matrix = {
    tgt = ["foo", "bar"]
    version = [...list of version tags generated by metadata-action...] // ???
  }
  dockerfile = "Dockerfile.${tgt}"
  tags = ["my/${tgt}:${version}"]
}

And then I'd call metadata-action with an empty images input so that it generates raw version tags without base name.

@int128
Copy link

int128 commented Dec 8, 2024

I could generate the tags for each target using for expression. Here are examples.

Using string interpolation

      - uses: docker/metadata-action@v5
        id: metadata
      - uses: docker/bake-action@v5
        env:
          TAG_BASE: my/foo # something like ghcr.io/${{ github.repository }}
        with:
          push: true
          files: |
            ./docker-bake.hcl
            ${{ steps.metadata.outputs.bake-file }}
variable "TAG_BASE" {}

target "docker-metadata-action" {}

target "service1" {
  inherits = ["docker-metadata-action"]
  context = "."
  dockerfile = "service1.dockerfile"
  tags = [for tag in target.docker-metadata-action.tags : "${TAG_BASE}/service1:${tag}"]
}

target "service2" {
  inherits = ["docker-metadata-action"]
  context = "."
  dockerfile = "service2.dockerfile"
  tags = [for tag in target.docker-metadata-action.tags : "${TAG_BASE}/service2:${tag}"]
}

It will build the image tags of my/foo/service1:latest and my/foo/service2:latest.

Using replace function

      - uses: docker/metadata-action@v5
        id: metadata
        with:
          images: ghcr.io/${{ github.repository }}/__service__
      - uses: docker/bake-action@v5
        with:
          push: true
          files: |
            ./docker-bake.hcl
            ${{ steps.metadata.outputs.bake-file }}
target "docker-metadata-action" {}

target "service1" {
  inherits = ["docker-metadata-action"]
  context = "."
  dockerfile = "service1.dockerfile"
  tags = [for tag in target.docker-metadata-action.tags : replace(tag, "__service__", "service1")]
}

target "service2" {
  inherits = ["docker-metadata-action"]
  context = "."
  dockerfile = "service2.dockerfile"
  tags = [for tag in target.docker-metadata-action.tags : replace(tag, "__service__", "service2")]
}

@Pesa
Copy link
Author

Pesa commented Dec 9, 2024

Thanks for the suggestion @int128, I will give it a try.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants