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

Multi-arch containers #90

Open
ksmithut opened this issue Jan 30, 2023 · 4 comments
Open

Multi-arch containers #90

ksmithut opened this issue Jan 30, 2023 · 4 comments

Comments

@ksmithut
Copy link

It's cumbersome to know how many versions make up a single build of a multi-arch container. It seems that each distro needs it's own version, but then there are some magic ones that are also around. It could be that I'm misconfiguring my build. Here's my jobs:

jobs:
  docker:
    name: Docker
    runs-on: ubuntu-latest
    timeout-minutes: 10
    steps:
      - uses: actions/checkout@v3
      - uses: docker/setup-qemu-action@v2
      - uses: docker/setup-buildx-action@v2
        with:
          platforms: 'linux/amd64,linux/arm64'
      - id: version
        shell: bash
        run: echo "version=$(date +%Y%m%d%H%M%S)" >> $GITHUB_OUTPUT
      - uses: docker/login-action@v2
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GH_TOKEN }}
      - uses: docker/build-push-action@v3
        with:
          context: '.'
          push: true
          platforms: 'linux/amd64,linux/arm64'
          tags: ${{ env.BUILD_DOCKER_IMAGE }}:${{ steps.version.outputs.version }},${{ env.BUILD_DOCKER_IMAGE }}:latest
          cache-from: type=registry,ref=${{ env.BUILD_DOCKER_IMAGE }}:latest
          cache-to: type=inline
      - uses: actions/delete-package-versions@v4
        with:
          package-name: ${{ env.APP_NAME }}
          package-type: container
          min-versions-to-keep: 1
          token: ${{ secrets.GH_TOKEN }}

When this runs and I try to pull afterward, I get manifest unknown. When I bump it to 2, same thing. 3, sometimes works but sometimes not. 4 seemed to consistently work until this morning. My goal is to only store the latest docker image but I'm having trouble figuring out how to selectively keep all the "latest" images for the various architectures I need to support.

MrAnno added a commit to axoflow/axosyslog that referenced this issue Mar 10, 2023
delete-package-versions seems to be buggy with multi-arch images.

actions/delete-package-versions#90

This reverts commit 4bdc542.

Signed-off-by: László Várady <[email protected]>
@lluked
Copy link

lluked commented Jul 22, 2023

I've been having the same problem, the thing here is that from my understanding multi-arch images are not an actual image but a pointer to images for different architectures.

This means not all the images are tagged, only the pointer image is tagged as only one image can have the same tag, the rest are left untagged.

So when delete-only-untagged-versions: 'true' or min-versions-to-keep: 1 is used all the images that are pointed to by the multi arch image are deleted leaving only the multi-arch "image" that points to them. Because they have been deleted the manifest error occurs on pull.

If you only have images being built one way, e.g. on merge or on release, it is relatively simple to delete old images, you can just keep the last x untagged images where x is the number of architectures being build.

If you are building on schedule, on merge, on release, manually with different tags being used for each this becomes a nightmare as all of them produce untagged images at different intervals and you couldn't delete the last x images because if you would risk deleting an image referenced by another tag that may not be updated so frequently.

For example if schedule was run daily and release was weekly, and then you have some adhoc builds thrown in also by the time your on day 6 you may have 30 odd images and if you delete x amount you could risk deleting the images referenced by main because a lot of pr's happened after the last release on main.

Really to safely delete old multi-arch containers a list of tags would need to be used, that would be needed to be used to pull the multi-arch manifests and find the images referenced in them, then everything else could be deleted. I'm not sure whether or not that would be in the scope of this package but believe it is a valid want for developers.

michel-kraemer added a commit to steep-wms/aerial-image-segmentation that referenced this issue Aug 25, 2023
Set 'provenance: false' so there won't be a build for an unknown
architecture (docker/build-push-action#820) and
calling delete-package-versions will not result in an 'manifest unknown'
error (actions/delete-package-versions#90).
@ManiMatter
Copy link

ManiMatter commented Mar 27, 2024

Also interested in this. Took me a while to figure out why I'm getting "manifest unkown" after switching to multi-arch / buildx.

I agree it should be possible that only untagged packages get deleted that are not referenced by other multi-arch packages.

For explanation:
(@lluked 's explanation is very good, just adding here to it with screenshots to make it hopefully even more clear why this is a super important feature...)

This github action creates the below docker images that are compatible with arm64 and amd64:

      - name: "Build, Tag, and push the Docker image"
        env:
          IMAGE_NAME: ghcr.io/manimatter/decluttarr
          IMAGE_TAG: ${{ steps.setversion.outputs.new_tag }} 
        run: |
          docker buildx build \
            --platform linux/amd64,linux/arm64 -f docker/Dockerfile . \
            --progress plain \
            -t $IMAGE_NAME:$IMAGE_TAG \
            -t $IMAGE_NAME:latest \
            --label com.decluttarr.version=$IMAGE_TAG \
            --label com.decluttarr.commit=$SHORT_COMMIT_ID \
            --build-arg IMAGE_TAG=$IMAGE_TAG \
            --build-arg SHORT_COMMIT_ID=$SHORT_COMMIT_ID \
            --push \

This code has created the below below package 1.3.3.

As visible on the screenshot, the 1.3.3. packages points to 3 other sub-packages which correspond to the respective architecture (arm64, amd64, and an extra one if the architecture can't be established).

The same packages can be found under "all packages" .

If I now were to run this snipped here, then the 4 sub-packages listed under 'all packages' would be deleted, thus including the 3 packages that belong to 1.3.3., and hence 1.3.3. would stop working.

Therefore, what I think is needed is a way to tell delete-package-versions to not delete untagged / unlabelled packages if they belong to a parent package that does in fact have a label.

# - name: "Delete untagged versions"
   #   uses: actions/delete-package-versions@v4
   #   with: 
   #     package-name: 'decluttarr'
   #     package-type: 'container'
   #     delete-only-untagged-versions: 'true'

Explanation

ManiMatter added a commit to ManiMatter/decluttarr that referenced this issue Mar 27, 2024
Cause was the automated removal of untagged versions, which does not work with multi-arch containers.
See actions/delete-package-versions#90
ManiMatter added a commit to ManiMatter/decluttarr that referenced this issue Mar 29, 2024
@rohanmars
Copy link

Specifically for ghcr.io containers packages I figured out how todo this in a new action I wrote: https://github.com/dataaxiom/ghcr-cleanup-action

@ManiMatter
Copy link

ManiMatter commented Jun 3, 2024

Specifically for ghcr.io containers packages I figured out how todo this in a new action I wrote: https://github.com/dataaxiom/ghcr-cleanup-action

This worked for me and I have switched to that github action instead.

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

Successfully merging a pull request may close this issue.

4 participants