Open schmitch opened 7 months ago
Have you authenticated to that registry? You still need to authenticate, like any Docker-based tooling. We have some docs on this here - can you check these out and see if you can successfully authenticate?
Have you authenticated to that registry? You still need to authenticate, like any Docker-based tooling. We have some docs on this here - can you check these out and see if you can successfully authenticate?
yeah I did docker login docker.envisia.io
and I tried the SDK_CONTAINER_REGISTRY_UNAME
and SDK_CONTAINER_REGISTRY_PWORD
but I think I can close the image, since I think that might be a problem with nexus sonatype 3 since the command without the base image is successful but does not push the container:
1:7>Done building target "ComputeContainerConfig" in project "Envisia.Erp.Web.csproj".
1:7>Target "PublishContainer" in file "/usr/local/share/dotnet/sdk/8.0.100/Containers/build/Microsoft.NET.Build.Containers.targets" from project "/Users/schmitch/projects/envisia/erp/loki/dotnet/Envisia.Erp.Web/Envisia.Erp.Web.csproj" (entry point):
Using "CreateNewImage" task from assembly "/usr/local/share/dotnet/sdk/8.0.100/Containers/build/../tasks/net8.0/Microsoft.NET.Build.Containers.dll".
Task "CreateNewImage"
Building image 'docker.envisia.io/erp/web-dotnet' with tags 'ef-test' on top of base image 'mcr.microsoft.com/dotnet/aspnet:8.0'.
Setting user from APP_UID environment variable
Setting ports from ASPNETCORE_HTTP_PORTS environment variable
Added port 8080
Setting ports from ASPNETCORE_URLS environment variable
Added port 80
Pushed image 'docker.envisia.io/erp/web-dotnet:ef-test' to local registry via 'docker'.
Done executing task "CreateNewImage".
1:7>Done building target "PublishContainer" in project "Envisia.Erp.Web.csproj".
1:7>Done Building Project "/Users/schmitch/projects/envisia/erp/loki/dotnet/Envisia.Erp.Web/Envisia.Erp.Web.csproj" (Publish;PublishContainer target(s)).
it only exists in my local docker image registry not in docker.envisia.io, so I think the culprint is more likely sonatype nexus 3
yeah if I add <ContainerRegistry>docker.envisia.io</ContainerRegistry>
it fails with the same error, so that looks like a problem with sonatype nexus 3
@schmitch can you clarify some of the parameters that you were using?
I think based on what I'm seeing here that you may have set ContainerBaseImage
to include the registry and that's not intended currently.
Re: Nexus compatibility - we'd like to ensure that this tooling is compatible with all kinds of registries, so if we need to add a 'quirk' for Sonatype such a thing could be done. We've done so for AWS, Google and Azure already.
yeah, I've set the following:
<ContainerRepository>docker.envisia.io/erp/web-dotnet</ContainerRepository>
<ContainerBaseImage>docker.envisia.io/envisia/dotnet/runtime-german:8.0</ContainerBaseImage>
<ContainerRegistry>docker.envisia.io</ContainerRegistry>
the tag needed to be set else I get:
/usr/local/share/dotnet/sdk/8.0.100/Containers/build/Microsoft.NET.Build.Containers.targets(202,5): error MSB4044: The "CreateNewImage" task was not given a value for the required parameter "BaseImageTag". [/Users/schmitch/projects/envisia/erp/loki/dotnet/Envisia.Erp.Web/Envisia.Erp.Web.csproj]
but well inside the docs it uses the full: https://learn.microsoft.com/en-us/dotnet/core/docker/publish-as-container?pivots=dotnet-8-0#containerbaseimage
and the ContainerImageTags
I set with -p
flag: -p ContainerImageTags="ef-test"
(I basically call the command in the reproducer)
OK, I think that's the problem - ContainerRepository
should 'just' be the name of the image - erp/web-dotnet
in this case. The tooling concats this with the ContainerRegistry on your behalf automatically. I've seen this incorrect usage a few different times now, so we should change the tooling to either warn when this is detected, or to property support 'full' ContainerRepository names.
well I tried that aswell:
but even with:
<ContainerRepository>erp/web-dotnet</ContainerRepository>
<ContainerRegistry>docker.envisia.io</ContainerRegistry>
Building image 'erp/web-dotnet' with tags 'ef-test' on top of base image 'mcr.microsoft.com/dotnet/aspnet:8.0'.
Uploading layer 'sha256:2c6d21737d8318aa15c4cc838475029a5efc36c0429e3d8da80d97d0b96d9aaf' to 'docker.envisia.io'.
Uploading layer 'sha256:079870c53803dd776aff8d97b6da1400eefea75fe9ade2b751f2b5e7b9b9e9f5' to 'docker.envisia.io'.
Uploading layer 'sha256:6eb98e67addfff9061459b1005868c94ff3dba8ad0c7ca13b9d1efad25d0ae9c' to 'docker.envisia.io'.
Uploading layer 'sha256:773a6cc66c9c6e324c136436f898c99dc23ac48d5d037492fd156f5cd677a4b2' to 'docker.envisia.io'.
Uploading layer 'sha256:7f7e0ed13130bf9c48a2d6274fca95102064b2d9bf2e78d644f2dcf9260e65fc' to 'docker.envisia.io'.
Uploading layer 'sha256:4d9ee2cd6a123df3df954b336053a3f77bef77dac9f3a4ece1d3abcb32ffc581' to 'docker.envisia.io'.
Uploading layer 'sha256:500668c9e3b1dde81d85ab7618d7473ec64f74c4e313817b12195661f8eaae81' to 'docker.envisia.io'.
/usr/local/share/dotnet/sdk/8.0.100/Containers/build/Microsoft.NET.Build.Containers.targets(202,5): error CONTAINER1016: Unable to access the repository 'erp/web-dotnet' in the registry 'docker.envisia.io'. Please confirm your credentials are correct and that you have access to this repository and registry. [/Users/schmitch/projects/envisia/erp/loki/dotnet/Envisia.Erp.Web/Envisia.Erp.Web.csproj]
looks like a problem with sonatype nexus 3 (I removed my base image)
but well inside the docs it uses the full: learn.microsoft.com/en-us/dotnet/core/docker/publish-as-container?pivots=dotnet-8-0#containerbaseimage
This is a typo on my end - I meant to say ContainerRepository
here. This property should not be fully-qualified.
Ok, I'm going to transfer this to dotnet/sdk-container-builds and rename it to be more clear that we need to investigate Sonatype Nexus quirks.
@schmitch it may be hard for us to find a Nexus instance to test against. It would be very useful to get a sense for the HTTP traffic between the SDK and Nexus - either via a binlog or a http trace from a tool like fiddler, etc. These will have credentials and sensitive data, so if you are ok sending such examples, I would recommend that you open a ticket on DevCommunity, upload the artifacts there as private assets, and then link the ticket here.
@baronfel I can generate a flow file with mitmproxy but I'm not sure if it is helpful.
the only thing that is happening is the following:
HEAD /v2/erp/web-dotnet/blobs/sha256:a5d27c632fdcf7a46101d34ed14b06ed6efe90a5086fa615619564ae7bdfd45d HTTP/1.1
Host: docker.envisia.io
User-Agent: .NET Container Library v8.0.100-rtm.23551.6+e9d13cbe7e8c1d52ce276a8655f52a87e1017c46
content-length: 0
HTTP/1.1 401 Unauthorized
Date: Mon, 27 Nov 2023 17:20:09 GMT
Content-Type: application/json
Content-Length: 0
Connection: keep-alive
X-Content-Type-Options: nosniff
Content-Security-Policy: sandbox allow-forms allow-modals allow-popups allow-presentation allow-scripts allow-top-navigation
X-XSS-Protection: 1; mode=block
WWW-Authenticate: BASIC realm="Sonatype Nexus Repository Manager"
Accept-Ranges: bytes
Docker-Distribution-Api-Version: registry/2.0
Strict-Transport-Security: max-age=15724800; includeSubDomains
multiple HEAD calls without any authencation data at all. it responds with a WWW-Authenticate: BASIC realm="Sonatype Nexus Repository Manager"
but no further request is done. there are multiple of these head calls which basically matches the sha layer that will be pushed Uploading layer 'sha256:a5d27c632fdcf7a46101d34ed14b06ed6efe90a5086fa615619564ae7bdfd45d' to 'docker.envisia.io'.
I think this may be a bug in our authentication implementation. We're checking for WWW-Authenticate schemes case-sensitively, but per the spec schemes should be case-insensitive. If you have any control, can you rewrite the response from Nexus to be WWW-Authenticate: Basic realm="Sonatype Nexus Repository Manager"
instead of BASIC
?
sadly I think that is at least not an option in nexus directly. besides that there is a settings page to reorder the realms which should change the response of www-authenticate, but that did not work on my side. I can try to overwrite it in nginx tomorrow.
@schmitch here's a slightly easier thing to try. I've attached a nuget package of the SDK containers tech built from the changes in dotnet/sdk#37165 - you can drop this in a folder and use that folder as a nuget source via dotnet nuget add source
, then add a PackageReference
to this package and version. You'll need to remove the .zip
for NuGet to recognize the package too.
Once you do this you should be able to publish your app and if this was in fact the problem you should see auth handshakes occur.
looks like it still did nothing, it only did a HEAD request:
HEAD /v2/erp/web-dotnet/blobs/sha256:2c6d21737d8318aa15c4cc838475029a5efc36c0429e3d8da80d97d0b96d9aaf HTTP/1.1
Host: docker.envisia.io
User-Agent: .NET Container Library v8.0.200-dev
content-length: 0
HTTP/1.1 401 Unauthorized
Date: Tue, 28 Nov 2023 08:21:40 GMT
Content-Type: application/json
Content-Length: 0
Connection: keep-alive
X-Content-Type-Options: nosniff
Content-Security-Policy: sandbox allow-forms allow-modals allow-popups allow-presentation allow-scripts allow-top-navigation
X-XSS-Protection: 1; mode=block
WWW-Authenticate: BASIC realm="Sonatype Nexus Repository Manager"
Accept-Ranges: bytes
Docker-Distribution-Api-Version: registry/2.0
Strict-Transport-Security: max-age=15724800; includeSubDomains
just to debug it further I can build the package ah there is a csproj just for that..Microsoft.NET.Build.Containers
myself, however I was unable to pack it, is there an easy way to do that without building the whole sdk?
actually the problem was the Basic
auth header, but on more occurances:
this was the diff (I was inside dotnet/sdk release/8.0.2xx
) that worked for my (don't mind the logs, it helped me understand it!)
Oh awesome - thanks for that validation! I'll adopt your changes on the PR shortly. Kudos for cloning the SDK and building it yourself :)
Ok, it looks like I just missed one other place where we were doing string matching instead of insensitive comparisons. I've updated that PR with the changes if you'd like to review/verify the behavior.
everything looks working now.
the baseimage was authenticated as well, sadly my base image is only an oci v1 container:
/usr/local/share/dotnet/sdk/8.0.100/Containers/build/Microsoft.NET.Build.Containers.targets(202,5): error MSB4018: System.NotImplementedException: CONTAINER2003: The manifest for envisia/dotnet/runtime-german:8.0 from registry https://docker.envisia.io/ was an unknown type: application/vnd.oci.image.index.v1+json. Please raise an issue at https://github.com/dotnet/sdk-container-builds/issues with this message. [/Users/schmitch/projects/envisia/erp/loki/dotnet/Envisia.Erp.Web/Envisia.Erp.Web.csproj]
but thats a problem that I can easily fix on our side. probably some docker buildx
config changes or basically a problem with our docker build that uses application/vnd.oci.image.index.v1+json
instead of application/vnd.docker.distribution.manifest.list.v2+json
, probably just: https://docs.docker.com/build/exporters/#oci-media-types
That's great news! If Nexus only supports OCI Image Indexes then we'd need to teach our tooling how to read those (not just Docker Manifest Lists). This normally isn't horrible to do. The first step would be detecting and parsing those structures in the main 'find the best image for this image name' code here.
I will check what happens if I add the flag and try another registry and than I will see , probably tomorrow or the day after
@schmitch did you choose the OCI
index specifically with docker buildx
? Or was it a default or something? If it's a default that might bump up the priority of implementing support for OCI indexes.
@baronfel no we just use docker buildx bake -f docker-bake.hcl -f env8.hcl
to cross compile images for different arch's we basically base our images from mcr.microsoft.com/dotnet/aspnet:8.0
but we need the german locale and timezone (sadly, we didn't do a good job yet when it comes to timezones and the local provider and it's a long road to get rid of that...) and also we need to add ca-certificates and other stuff to the container. so basically we just add stuff and to "cross build" that we use docker buildx bake
with the following target:
target "runtime-dotnet-german" {
inherits = ["runtime-dotnet-base"]
dockerfile = "runtime-dotnet/Dockerfile.german"
tags = [
"docker.envisia.io/envisia/dotnet/runtime-german:${DOTNET_VERSION}"
]
}
so nothing special, I do not even now if its possible to set oci-mediatypes
with bake
.
But it might also be correctly done by docker buildx bake
and sonatype than changes the image
I pushed a image with bake to the docker hub and the image is still application/vnd.oci.image.index.v1+json
.
I also can't push docker manifests with buildx bake
, it will always says: ERROR: docker exporter does not currently support exporting manifest lists
if I try to set output = ["type=docker"]
it's also impossible to do so with buildx build
:
$ docker buildx build --push --platform linux/amd64,linux/arm64 --build-arg DOTNET_VERSION=8.0 --tag envisia/dotnet-runtime-german:test2 -f runtime-dotnet/Dockerfile.german --output type=docker .
[+] Building 0.0s (0/0) docker-container:crossbuilder
ERROR: push and "docker" output can't be used together
$ docker buildx build --load --platform linux/amd64,linux/arm64 --build-arg DOTNET_VERSION=8.0 --tag envisia/dotnet-runtime-german:test2 -f runtime-dotnet/Dockerfile.german --output type=docker .
[+] Building 0.0s (0/0) docker-container:crossbuilder
ERROR: docker exporter does not currently support exporting manifest lists
somehow I tried:
$ docker buildx build --push --platform linux/amd64,linux/arm64 --build-arg DOTNET_VERSION=8.0 --tag envisia/dotnet-runtime-german:test2 -f runtime-dotnet/Dockerfile.german --output type=image,oci-mediatypes=false .
and it still generated oci images indexes, not sure if it is possible to use docker manifest lists with buildx.
@baronfel sadly there are no news to this, but btw. I found: https://github.com/opencontainers/image-spec/blob/main/image-index.md which is the opencontainers spec which says that "image consumers SHOULD" support the application/vnd.oci.image.index.v1+json
media type, it's probably an easy fix, since it's closely related to application/vnd.docker.distribution.manifest.list.v2+json
Unfortunately I also just ran into this problem that we cannot pull OCI base images (nginx:alpine). In my case JFrog Artifactory provides OCI images (proxying to docker hub).
I already had once created changes for:
https://github.com/dotnet/sdk/pull/35204
Not sure if this might help in handling the flow of using OCI base images as inputs. Generally the formats are a bit different in how they organize the blobs and layers. Funnily I think the OCI format is closer to the Docker API than the Docker Format itself.
Disclaimer: Our use case might be a bit weird. We use the .net SDK container toolkit also to package and bundle any other applications (e.g. angular apps) 😁 in its core the toolkit can be used without .net specifics nicely.
@baronfel Does it make sense to create a dedicated issue for the OCI base image support? I have the feeling the discussion in this issue is a bit mixed. The original problem of pushing to Nexus seems to be fixed with the auth handling.
I might be willing to implement the OCI pull as it is in our interest to have this in the SDK.
@Danielku15 splitting out would be awesome, yes. I think right now we recently gained support for the OCI Layer Scheme, but not the overall Index scheme.
@baronfel
[!IMPORTANT] edit: added https://github.com/dotnet/sdk-container-builds/issues/561 to follow up on the pull topic separately
I just tested today a change on our internal fork of the container-builds toolkit and for us it worked to just extend the switch
with the other mimetype. The JSON replies we have from Artifactory are compatible with the ManifestListV2
:
- SchemaTypes.DockerManifestListV2 => await PickBestImageFromManifestListAsync(
+ SchemaTypes.DockerManifestListV2 or SchemaTypes.OciImageIndexV1 => await PickBestImageFromManifestListAsync(
+ internal const string OciImageIndexV1 = "application/vnd.oci.image.index.v1+json";
And for completess:
+ request.Headers.Accept.Add(new(SchemaTypes.OciImageIndexV1));
The specs seem to align in the properties we need. But setting up correct tests might be a bit tricky. Maybe by tweaking the accept header we can enforce the OCI schema to be returned by registry
.
Describe the bug
if seombody wants to use a
ContainerBaseImage
that is not inside a public repository theLANG=en dotnet publish -c Release -p ContainerImageTags="ef-test" /t:PublishContainer
command would failTo Reproduce
nexus sonatype 3
LANG=en dotnet publish -c Release -p ContainerBaseImage=docker.envisia.io/envisia/dotnet/runtime-german:8.0 -p ContainerImageTags="ef-test" /t:PublishContainer
Exceptions (if any)
Further technical details