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

BuildX: Missing package description / untagged Images at build with Platform: xy parameter #447

Closed
alexanderwwagner opened this issue Aug 27, 2021 · 6 comments

Comments

@alexanderwwagner
Copy link

Behaviour

If I push my docker image with an action workflow to github packages, then I can find my docker image in the package chapter
of my desired repository.

  • Aside from that my currently pushed docker image is tagged with the right tag (latest and Release version):
    image

  • Additional I can find the right description of the docker image:
    image

Problem:
I need my docker Image for multiple architecture available.
Because of that I insert the line: platforms: linux/amd64,linux/arm64,linux/arm/v7 in my workflow file.
The push to the github package registry works fine with this, but I have this two problems:

  • Missing docker description after push with this parameter
    image

  • At each push there I can find my new docker Image with the right tag (latest and Release version), but there are additional three untagged Images pushed
    image

image

Expected behaviour

If I use the platform parameter there should still be a description for my docker image.
There should not be untagged docker images after push with the platform parameter.

Thank you for your response!

My workflow.yml

name: Build/Update Docker Image

on:
  release:
      types: # This configuration does not affect the page_build event above
        - published

  #pull_request:
  #  branches: [ main ]
env:
  REGISTRY: ghcr.io
  IMAGE_NAME: ${{ github.repository }}

jobs:

  build-and-push-image:

    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write

    steps:
    # Checkout repository
    - name: Checkout repository
      uses: actions/checkout@v2
    
    # Login to Docker registry
    - name: Login to GitHub Container Registry
      uses: docker/login-action@v1
      with:
        registry: ghcr.io
        username: ${{ github.actor }}
        password: ${{ secrets.GITHUB_TOKEN }}
    
    
    # Extract metadata for Docker
    - name: Extract metadata (tags, labels) for Docker
      id: meta
      uses: docker/metadata-action@v3
      with:
        images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
    
    
    # https://github.com/docker/setup-qemu-action
    - name: Set up QEMU
      uses: docker/setup-qemu-action@v1
    
    
    # Setup buildx
    - name: Set up Docker Buildx
      uses: docker/setup-buildx-action@v1
      
      
    # Available platforms  
    - name: Available platforms
      run: echo ${{ steps.buildx.outputs.platforms }}
    
    
    # Get Tag version
    - name: Get Tag Version
      run: |
        echo "RELEASE_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV
        echo $RELEASE_VERSION
        echo ${{ env.RELEASE_VERSION }}
    
    
    # Build and push Docker image
    - name: Build and push Docker image
      uses: docker/build-push-action@v2
      with:
        context: .
        platforms: linux/amd64,linux/arm64,linux/arm/v7
        push: true
        tags: ${{ steps.meta.outputs.tags }}
        labels: ${{ steps.meta.outputs.labels }}
@crazy-max
Copy link
Member

@alexanderwwagner

At each push there I can find my new docker Image with the right tag (latest and Release version), but there are additional three untagged Images pushed

Afaik there should be an untagged version left behind assuming the new build is different. Tag-less stick around until you delete them on GHCR.

Missing docker description after push with this parameter.

Not sure how it works on GHCR. I suggest to open a thread on https://github.uint.cloudmunity about that. WDYT @dhadka? The description is not displayed because it's a application/vnd.docker.distribution.manifest.list.v2+json?

@luislhl
Copy link

luislhl commented Jan 5, 2022

It seems I'm experiencing the same behavior.

Afaik there should be an untagged version left behind assuming the new build is different. Tag-less stick around until you delete them on GHCR.

The untagged images are new ones pushed at the same time as the last tagged image, they are not old images whose tag was taken by the new one.

Example:

@nitrocode
Copy link

I see the same behavior in runatlantis/atlantis images

The description label exists on the image

✗ docker pull ghcr.io/runatlantis/atlantis:dev
✗ docker inspect ghcr.io/runatlantis/atlantis:dev | jq '.[].Config.Labels'
{
  "authors": "Anubhav Mishra, Luke Kysow",
  "org.opencontainers.image.created": "2023-02-24T05:39:39.985Z",
  "org.opencontainers.image.description": "Terraform Pull Request Automation",
  "org.opencontainers.image.licenses": "Apache-2.0",
  "org.opencontainers.image.revision": "c960b4d9ea6ad138f227a0a12c0efec84b0e44c2",
  "org.opencontainers.image.source": "https://github.com/runatlantis/atlantis",
  "org.opencontainers.image.title": "atlantis",
  "org.opencontainers.image.url": "https://github.com/runatlantis/atlantis",
  "org.opencontainers.image.version": "main"
}

The description label is put on the image using the docker/metadata-action

https://github.com/runatlantis/atlantis/blob/c960b4d9ea6ad138f227a0a12c0efec84b0e44c2/.github/workflows/atlantis-image.yml#L51-L63

https://github.com/runatlantis/atlantis/blob/c960b4d9ea6ad138f227a0a12c0efec84b0e44c2/.github/workflows/atlantis-image.yml#L126

The workflow that builds the images are using multi arch images. When navigating to ghcr's container images, the description field seems to be missing

https://github.com/runatlantis/atlantis/pkgs/container/atlantis/72928905?tag=dev

With the following message

For multi-arch images, set a value for the org.opencontainers.image.description key in the annotations field of the manifest:
"annotations": { "org.opencontainers.image.description": "DESCRIPTION" }

Is there a way to set this annotations in the manifest using docker/build-push-action ? or using the docker/metadata-action?

Ref


I also looked for some other examples of ghcr. The puppeteer project does not use multi arch and I do see its description showing up.

https://github.com/puppeteer/puppeteer/pkgs/container/puppeteer/71913069?tag=19.7.2

✗ docker inspect ghcr.io/puppeteer/puppeteer:19.7.2 | jq '.[].Config.Labels'
{
  "org.opencontainers.image.created": "2023-02-20T17:33:20.768Z",
  "org.opencontainers.image.description": "Headless Chrome Node.js API",
  "org.opencontainers.image.licenses": "Apache-2.0",
  "org.opencontainers.image.revision": "e0330d82bda2c66c3780b23ca10c876abc2c700b",
  "org.opencontainers.image.source": "https://github.com/puppeteer/puppeteer",
  "org.opencontainers.image.title": "puppeteer",
  "org.opencontainers.image.url": "https://github.com/puppeteer/puppeteer",
  "org.opencontainers.image.version": "19.7.2"
}
✗ docker manifest inspect ghcr.io/puppeteer/puppeteer:19.7.2 | grep -i description
✗

The home-builder project uses multi arch and docker manifest annotate but doesn't annotate description. Worth looking into if we want to manually annotate.

https://github.com/home-assistant/core/blob/ba929dfc79b32f4bd7aad1711224eb4385ad7745/.github/workflows/builder.yml#L369-L371
https://github.com/home-assistant/core/pkgs/container/home-assistant/72554896?tag=2023.3.0b0


Only issue I could find on the github.community

https://github.com/orgs/community/discussions/25664


It would be nice if the build-push-action allowed adding arbitrary fields to the manifest

      -
        name: Build and push
        uses: docker/build-push-action@v4
        with:
          context: .
          push: true
          tags: user/app:latest
          manifest:
            annotations:
              "org.opencontainers.image.description": "DESCRIPTION"

@crazy-max
Copy link
Member

crazy-max commented Feb 24, 2023

Is there a way to set this annotations in the manifest using docker/build-push-action ? or using the docker/metadata-action?

@nitrocode Yes with the outputs input, see https://docs.docker.com/build/exporters/image-registry/#annotations. Maybe we could also handle this in the metadata action 🤔

@nitrocode
Copy link

Ah, I should have looked all the way at the bottom

https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-container-registry#adding-a-description-to-multi-arch-images

which shows

- name: Build and push Docker image
  uses: docker/build-push-action@ad44023a93711e3deb337508980b4b5e9bcdc5dc
  with:
    context: .
    file: ./Dockerfile
    platforms: ${{ matrix.platforms }}
    push: true
    outputs: type=image,name=target,annotation-index.org.opencontainers.image.description=My multi-arch image

Split up

  • type=image
  • name=target
  • annotation-index.org.opencontainers.image.description=My multi-arch image

I wonder why this has -index here. Does the index need to be filled in such as -0 ?

If we wanted to add multiple outputs, how would it look like?

    outputs: |
      type=image,name=target,annotation-index.org.opencontainers.image.description=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.description'] }}
      type=image,name=target,annotation-index.org.opencontainers.image.source=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.source'] }}
      type=image,name=target,annotation-index.org.opencontainers.image.licenses=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.licenses'] }}

or

    outputs: |
      type=image,name=target,annotation-0.org.opencontainers.image.description=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.description'] }}
      type=image,name=target,annotation-1.org.opencontainers.image.source=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.source'] }}
      type=image,name=target,annotation-2.org.opencontainers.image.licenses=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.licenses'] }}

I imagine the former since the latter is a complete guess. I'll have to experiment a little.

Thanks again @crazy-max for looking into this with me.

@crazy-max
Copy link
Member

crazy-max commented Feb 26, 2023

I wonder why this has -index here. Does the index need to be filled in such as -0 ?

No annotation-index is to set annotations at the image index level, so that the annotation is shared between all architectures, see https://github.com/moby/buildkit/blob/master/docs/annotations.md

I imagine the former since the latter is a complete guess. I'll have to experiment a little.

I don't think this is what you want. In your case you want X annotations when exporting your image. Not multiple exporters (this is also not yet supported moby/buildkit#2760).

In your case it would look like this:

outputs: |
      type=image,name=target,annotation-index.org.opencontainers.image.description=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.description'] }},annotation-index.org.opencontainers.image.source=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.source'] }},annotation-index.org.opencontainers.image.licenses=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.licenses'] }}

I do agree that UX is not great. Maybe an annotations input would be better for this use case.

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

No branches or pull requests

4 participants