Joxit/docker-registry-ui

Bug when listing multi-arch images

loliee opened this issue · 11 comments

Hi, I use this docker registry UI and I have an issue in list page for some multi-arch images.

Bug description

Some multi-arch images are not well displayed in list page, detail page works well.

How to Reproduce

Here what I did :

skopeo copy --insecure-policy  --multi-arch=all docker://docker.io/nginx:1.23 docker://myregistry.url/nginx:1.23

And go to nginx list page, (first time list is correctly displayed) but If I go on detail page and come back on the list page I have the bug and it never disappear, cf. screenshot.

Expected behavior

I would like to see images with date, size and digest.

Screenshots

Screen Shot 2022-08-03 at 1 01 34 PM

System information

  • Browser:
    • Name: Chrome
    • Version: Version 103.0.5060.134 (Official Build) (x86_64)
    • Name: Firefox
    • Version: 103.0.1 (64-bit)
  • Docker registry UI:
    • Version: 2.2.1
    • Server: docker
  • Registry
    • Version: 2.8.1
    • Server: docker

Additional context

In my browser console I have the following error for the XHR GET https://myregistry.url/v2/nginx/manifests/1.23:

Uncaught TypeError: r.layers is undefined
    value https://myregistry.url/ui/docker-registry-ui.js:20
    value https://myregistry.url/ui/docker-registry-ui.js:20
    value https://myregistry.url/ui/docker-registry-ui.js:20
    value https://myregistry.url/ui/docker-registry-ui.js:20
    e https://myregistry.url/ui/docker-registry-ui.js:20
    xr https://myregistry.url/ui/docker-registry-ui.js:20
    xr https://myregistry.url/ui/docker-registry-ui.js:20
    onMounted https://myregistry.url/ui/docker-registry-ui.js:20
    mount https://myregistry.url/ui/docker-registry-ui.js:20
    mount https://myregistry.url/ui/docker-registry-ui.js:20
    update https://myregistry.url/ui/docker-registry-ui.js:20
    mount https://myregistry.url/ui/docker-registry-ui.js:20
    mount https://myregistry.url/ui/docker-registry-ui.js:20
    mount https://myregistry.url/ui/docker-registry-ui.js:20
    o https://myregistry.url/ui/docker-registry-ui.js:20
    update https://myregistry.url/ui/docker-registry-ui.js:20
    update https://myregistry.url/ui/docker-registry-ui.js:20
    mount https://myregistry.url/ui/docker-registry-ui.js:20
    mount https://myregistry.url/ui/docker-registry-ui.js:20
    mount https://myregistry.url/ui/docker-registry-ui.js:20
    mount https://myregistry.url/ui/docker-registry-ui.js:20
    mount https://myregistry.url/ui/docker-registry-ui.js:20
    mount https://myregistry.url/ui/docker-registry-ui.js:20
    mount https://myregistry.url/ui/docker-registry-ui.js:20
    mount https://myregistry.url/ui/docker-registry-ui.js:20
    update https://myregistry.url/ui/docker-registry-ui.js:20
    mount https://myregistry.url/ui/docker-registry-ui.js:20
    mount https://myregistry.url/ui/docker-registry-ui.js:20
    mount https://myregistry.url/ui/docker-registry-ui.js:20
    mount https://myregistry.url/ui/docker-registry-ui.js:20
    mount https://myregistry.url/ui/docker-registry-ui.js:20
    update https://myregistry.url/ui/docker-registry-ui.js:20
    mount https://myregistry.url/ui/docker-registry-ui.js:20
    mount https://myregistry.url/ui/docker-registry-ui.js:20
    mount https://myregistry.url/ui/docker-registry-ui.js:20
    update https://myregistry.url/ui/docker-registry-ui.js:20
    update https://myregistry.url/ui/docker-registry-ui.js:20
    update https://myregistry.url/ui/docker-registry-ui.js:20
    update https://myregistry.url/ui/docker-registry-ui.js:20
    display https://myregistry.url/ui/docker-registry-ui.js:20
    value https://myregistry.url/ui/docker-registry-ui.js:20
    value https://myregistry.url/ui/docker-registry-ui.js:20
    display https://myregistry.url/ui/docker-registry-ui.js:20
    onMounted https://myregistry.url/ui/docker-registry-ui.js:20
    mount https://myregistry.url/ui/docker-registry-ui.js:20
    mount https://myregistry.url/ui/docker-registry-ui.js:20
    update https://myregistry.url/ui/docker-registry-ui.js:20
    mount https://myregistry.url/ui/docker-registry-ui.js:20
    mount https://myregistry.url/ui/docker-registry-ui.js:20
    mount https://myregistry.url/ui/docker-registry-ui.js:20
    mount https://myregistry.url/ui/docker-registry-ui.js:20
    mount https://myregistry.url/ui/docker-registry-ui.js:20
    mount https://myregistry.url/ui/docker-registry-ui.js:20
    update https://myregistry.url/ui/docker-registry-ui.js:20
    update https://myregistry.url/ui/docker-registry-ui.js:20
    update https://myregistry.url/ui/docker-registry-ui.js:20
    update https://myregistry.url/ui/docker-registry-ui.js:20
    onRoute https://myregistry.url/ui/docker-registry-ui.js:20
    zt https://myregistry.url/ui/docker-registry-ui.js:20
    zt https://myregistry.url/ui/docker-registry-ui.js:20
    push https://myregistry.url/ui/docker-registry-ui.js:20
    promise callback*push https://myregistry.url/ui/docker-registry-ui.js:20
    zt https://myregistry.url/ui/docker-registry-ui.js:20

The JSON response doesn't contains the layers key, cf the response:

{"manifests":[{"digest":"sha256:f26fbadb0acab4a21ecb4e337a326907e61fbec36c9a9b52e725669d99ed1261","mediaType":"application\/vnd.docker.distribution.manifest.v2+json","platform":{"architecture":"amd64","os":"linux"},"size":1570},{"digest":"sha256:df0d884bcf2e51ad370f16bcbe6d4cef68fd8057b63da89b77c228a680e7ed8a","mediaType":"application\/vnd.docker.distribution.manifest.v2+json","platform":{"architecture":"arm","os":"linux","variant":"v5"},"size":1570},{"digest":"sha256:ef2ad3781f412ae3052ef56f5938be93fef49d4204ecb36af2cec4d443ad9895","mediaType":"application\/vnd.docker.distribution.manifest.v2+json","platform":{"architecture":"arm","os":"linux","variant":"v7"},"size":1570},{"digest":"sha256:f5bee9654d19467f16c259fb577c4a28c082f8008914befd30805f803fa56e99","mediaType":"application\/vnd.docker.distribution.manifest.v2+json","platform":{"architecture":"arm64","os":"linux","variant":"v8"},"size":1570},{"digest":"sha256:d830cc525721daa5769bf9876db421987aefeff16c5074edc0c6b9061f8ff359","mediaType":"application\/vnd.docker.distribution.manifest.v2+json","platform":{"architecture":"386","os":"linux"},"size":1570},{"digest":"sha256:3e7402f0eb053ffd769097c9c726b39b0318e3f5a2538e7b63779714e646de93","mediaType":"application\/vnd.docker.distribution.manifest.v2+json","platform":{"architecture":"mips64le","os":"linux"},"size":1570},{"digest":"sha256:f1d915d7215a80b1a294ec8e9005a4b7984e650e06cb9b52f57e830576245c74","mediaType":"application\/vnd.docker.distribution.manifest.v2+json","platform":{"architecture":"ppc64le","os":"linux"},"size":1570},{"digest":"sha256:ead4adf366b0333e5f7e10f32b2b7814b3ea39807db3c3ac029d4404140da5b0","mediaType":"application\/vnd.docker.distribution.manifest.v2+json","platform":{"architecture":"s390x","os":"linux"},"size":1570}],"mediaType":"application\/vnd.docker.distribution.manifest.list.v2+json","schemaVersion":2}

Thanks you

Confirmed: same here for multiarch images created with buildx. The images are recognized fine (History of shows both linux/amd64 and linux/arm64 are visible).

Same issue here.

Noticed this after upgrading to the 2.2.0 version. It worked fine in the old 1.X version(s).

Here, I selected the history of the last image and then when going 'back' I now see the '?'.
image

Here, I clicked the history of the middle image and then 'back' and it's now a '?'.
image

Joxit commented

Hi, thank you for using my project and submitting issues 😄

I will try this ASAP. So you are all using buildx right ?

Yes, I am. I'm using buildx to generate multi-arch containers (amd64/arm64) and then push those (manifests) into my private docker registry.

Joxit commented

Can I have your command line?

docker buildx build \ --platform linux/amd64,linux/arm64 \ --build-arg DIND_VERSION=$(DIND_VERSION) \ --rm \ --progress plain \ --push \ --tag $(REGISTRY)/$(BUILD_ENV)/$(IMAGE):$(DIND_VERSION)-$(BUILD_VERSION) .

I am also using buildx.

It's also easy to reproduce by using skopeo to copy official nginx images in the private registry, e.g: skopeo copy --insecure-policy --multi-arch=all docker://docker.io/nginx:1.23 docker://[your-registry-url]/nginx:1.23.

Joxit commented

Thank you for your patience, I could not reproduce your issue but I found where it came from.

Your registry server does not respect the Manifest Specification. When the media type is application/vnd.docker.distribution.manifest.list.v2+json the response object must have a layers key, in your case you have a manifests key...

I have a fix for this, I will publish this now!

Thanks you for the fix @Joxit !

About the registry it's weird because I use the official image in the latest version 2.8.1 and same behavior with previous 2.X versions.

I made a test with the 2.2.2 version of the ui and it's much better but I notice that now when I go back on list page from details page I have the following popup showing for a few seconds:

Screen Shot 2022-09-07 at 5 14 03 PM

Joxit commented

Yes, it's weird... I tried will several versions too...

Ok, I may have found the issue, the registry server use the same Etag header even if the content is not the same (due to different Accept headers)... This causes our browser to not trigger the request when the cache is activated...
Working on it

Joxit commented

Can you try this PR #265 ?
You will need to change the registry ui image: joxit/docker-registry-ui:feat-no-cache and add the option ADD_NO_CACHE_HEADER and set it to true.

Also your registry server configuration (see the PR)