dotnet / sdk-container-builds

Libraries and build tooling to create container images from .NET projects using MSBuild
https://learn.microsoft.com/en-us/dotnet/core/docker/publish-as-container
MIT License
181 stars 39 forks source link

Using localhost registry does not work with containerd image store on Windows #597

Closed jackhorton closed 1 month ago

jackhorton commented 1 month ago

We need a custom base image for one of our projects, and because the .NET SDK tools don't support pulling from the local docker image store, we run a local registry locally using the official docker registry container. This method was working fine until i had to reinstall docker desktop for unrelated reasons, at which point it started failing with the following error message: Files\dotnet\sdk\8.0.401\Containers\build\Microsoft.NET.Build.Containers.targets(242,5): error CONTAINER1015: Unable to access the repository 'swarm-agent-base' at tag 'latest' in the registry 'localhost:5000'. Please confirm that this name and tag are present in the registry. [D:\edge\es\4\swarm\Swarm.Agent\Swarm.Agent.csproj]. It seems this issue is caused by using the containerd image store on Docker for Windows, because turning that option off makes this scenario work again (I must have had it off before reinstalling docker desktop).

Repro steps:

  1. Create a custom dockerfile based on one of the runtime images. For instance:
    FROM mcr.microsoft.com/dotnet/runtime:8.0-jammy
    RUN apt-get update && apt-get install -y git
  2. Build and push this image to a localhost registry:
    docker run --rm --detach --publish 5000:5000 -e REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY=/var/registry -v my-registry-volume:/var/registry --name registry registry:latest
    docker build . -f Dockerfile -t localhost:5000/my-custom-base:latest
    docker push localhost:5000/my-custom-base:latest
  3. Instruct your csproj to base off of your localhost image, and only publish when the registry container is running in the background:
    <ContainerBaseImage>localhost:5000/my-custom-base:latest</ContainerBaseImage>
  4. dotnet publish --runtime linux-x64 --configuration Release /t:PublishContainer wil work if containerd is not used, but will fail with the above error if it is used.

The setting in question: image

baronfel commented 1 month ago

Thanks for this report @jackhorton - I'll try to take a look as the protocol-level communication here and see if anything jumps out.

baronfel commented 1 month ago

Good news! This is actually because the SDK tooling doesn't support reading OCI Image Indexes as the base image, but we have a PR out to support that already. When I ran your test thread, I checked the logs of the local registry container and found the following (emphasis mine):

2024-10-04 14:19:51 time="2024-10-04T19:19:51.420735775Z" level=error msg="response completed with error" err.code="manifest unknown" err.message="OCI index found, but accept header does not support OCI indexes" http.request.host="localhost:5000" http.request.method=GET http.request.remoteaddr="172.17.0.1:33426" http.request.uri="/v2/my-custom-base/manifests/latest" http.request.useragent=".NET Container Library v8.0.400-rtm.24374.10+375e4940f138725b41a8a1b75a7ceec82fe426cc"
http.response.status=404 vars.name=my-custom-base vars.reference=latest

Since I had https://github.com/dotnet/sdk/pull/43631 cloned locally already, I used it to do the publish and was successful:

2024-10-04 14:23:54 time="2024-10-04T19:23:54.686546251Z" level=info msg="response completed" go.version=go1.20.8 http.request.host="localhost:5000" http.request.id=75b7bb1d-6073-4d25-98bb-326ecf490f53 http.request.method=GET http.request.remoteaddr="172.17.0.1:60912" http.request.uri="/v2/my-custom-base/manifests/latest" http.request.useragent=".NET Container Library v10.0.100-dev" http.response.contenttype="application/vnd.oci.image.index.v1+json" http.response.duration="966.931µs" http.response.status=200 http.response.written=856

The rest of the publish completed as expected. I'll get backports for this PR set up both for .NET 8 and .NET 9.