2

I have the following dockerfile

FROM mcr.microsoft.com/dotnet/sdk:6.0-alpine3.16 as build
WORKDIR /app

RUN apk add --no-cache bash
RUN wget -qO- https://aka.ms/install-artifacts-credprovider.sh | bash
ENV VSS_NUGET_EXTERNAL_FEED_ENDPOINTS '{"endpointCredentials": [{"endpoint":"https://<myprivatefeed>/_packaging/<myName>/nuget/v3/index.json", "password":"<PAT>"}]}'

COPY . .
RUN dotnet restore
RUN dotnet publish -o /app/published-app

FROM mcr.microsoft.com/dotnet/aspnet:6.0-alpine3.16 as runtime
WORKDIR /app
COPY --from=build /app/published-app /app
ENTRYPOINT [ "dotnet", "/app/ApplicationConfigurationApi.WebApi.dll" ]

but when I try to build an image I get the following error:

/app/ApplicationConfigurationApi.WebApi/ApplicationConfigurationApi.WebApi.csproj : error NU1301: Unable to load the service index for source https://<myprivatefeed>/_packaging/<myName>/nuget/v3/index.json. [/app/ApplicationConfigurationApi.sln]

I try to copy my gitlab *.crt downloaded from chrome, inside the container adding these instruction:

...
COPY . .
COPY ./mycert.crt /usr/local/share/ca-certificates/mycert.crt
RUN cat /usr/local/share/ca-certificates/mycert.crt >> /etc/ssl/certs/mycert.crt && \
     apk --no-cache add \
         curl
RUN update-ca-certificates
RUN dotnet restore
...

I also try to add (without the certificate) this RUN line:

...
COPY . .
RUN dotnet nuget update source "gitlab" --username "<my-userName>" --password "<PAT>" --store-password-in-clear-text --valid-authentication-types basic
RUN dotnet restore
...

Using this feed on my host machine does not cause any issue and I can perform restore operation correctly. I tried to use 'dotnet restore --verbosity detailed' and on the output seems that the feed has been persisted succesfully.

 NuGet Config files used:
   /app/nuget.config
   /root/.nuget/NuGet/NuGet.Config

 Feeds used:
   https://api.nuget.org/v3/index.json              
   https://<myprivatefeed>/_packaging/<myName>/nuget/v4/index.json

Nuget packages coming from api.nuget.org are successfully fetched, the ones from my private feed not.

docker version output is:

Server: Docker Desktop 4.15.0 (93002)
 Engine:
  Version:          20.10.21
  API version:      1.41 (minimum version 1.12)
  Go version:       go1.18.7
  Git commit:       3056208
  Built:            Tue Oct 25 18:00:19 2022   
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.6.10
  GitCommit:        770bd0108c32f3fb5c73ae1264f7e503fe7b2661
 runc:
  Version:          1.1.4
  GitCommit:        v1.1.4-0-g5fd4c4d
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0

dotnet solution is net6.0

----UPDATE Here I will put the dockerfile updated with some suggestion in comments below:

FROM mcr.microsoft.com/dotnet/sdk:6.0-focal as build
WORKDIR /app

RUN wget -O - https://raw.githubusercontent.com/Microsoft/artifacts-credprovider/master/helpers/installcredprovider.sh | bash
RUN wget -qO- https://aka.ms/install-artifacts-credprovider.sh | bash
ENV NUGET_CREDENTIALPROVIDER_SESSIONTOKENCACHE_ENABLED true
ENV VSS_NUGET_EXTERNAL_FEED_ENDPOINTS "{\"endpointCredentials\": [{\"endpoint\":\"${MY-PRIVATE-FEED-BASE-URL}\", \"username\":\"${USERNAME}\", \"password\":\"${PAT}\"}]}"

COPY . .

RUN echo | openssl s_client -host <my-private-feed-base-url> -port 443 -prexit -showcerts> tmpfile
RUN echo | sed -n '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' tmpfile > /usr/local/share/ca-certificates/<my-private-feed-base-url>.crt
RUN apt-get install -y ca-certificates
RUN chmod 644 /usr/local/share/ca-certificates/<my-private-feed-base-url>.crt && update-ca-certificates
RUN dotnet restore
RUN dotnet publish -o /app/published-app

FROM mcr.microsoft.com/dotnet/aspnet:6.0-focal as runtime
WORKDIR /app
COPY --from=build /app/published-app /app
ENTRYPOINT [ "dotnet", "/app/ApplicationConfigurationApi.WebApi.dll" ]

The error is the same as with the first dockerfile. I will attach also a screenshot about solution structure (maybe could be helpful)Solution structure

----END UPDATE

I tried also the following solution but no one worked:

Thanks in advance, Dave.

DavideP
  • 57
  • 10
  • Did you install the certificate of your private feed? – howardButcher Jan 05 '23 at 16:08
  • Is that the only NuGet error that's output? Often times there's additional errors that indicate the root cause. What does your nuget.config file look like? FWIW, there is documentation on how to target a private feed at https://github.com/dotnet/dotnet-docker/blob/2bc09827a8c0179fbddbcd7167407b4ca54aff71/documentation/scenarios/nuget-credentials.md. But what you've provided here seems to generally align with that approach. – Matt Thalman Jan 05 '23 at 16:20
  • @howardButcher I have updated the post, please give me a feedback if I'm doing something wrong and how to fix it :) – DavideP Jan 05 '23 at 20:20
  • @MattThalman yes is the only error that occurred in the logs... :( – DavideP Jan 05 '23 at 20:21
  • 1
    Does a simple `RUN curl https:///_packaging//nuget/v3/index.json` work? – mu88 Jan 06 '23 at 14:55
  • I try with a fresh dockerfile to test your @mu88 this is what I have done: ```FROM ubuntu:20.04 RUN apt-get update && apt-get -y install iputils-ping curl RUN curl https:///api/v4/projects/408/packages/nuget/index.json --insecure I have to add --insecure``` to successfully curl my endpoint – DavideP Jan 06 '23 at 15:25
  • Without --insecure flag this is the error: ```curl: (60) SSL certificate problem: unable to get local issuer certificate``` – DavideP Jan 06 '23 at 15:27
  • 1
    Please install your root CA certificate (not the cert of ``, but its root CA) before running curl – mu88 Jan 06 '23 at 15:47

1 Answers1

1

You probably did not install the certificate for your private feed. For debian-based docker images you can use following snipped in your Dockerfile to download and install the certificate:

RUN echo | openssl s_client -host <private-feed-domain> -port 443 -prexit -showcerts> tmpfile
RUN echo | sed -n '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' tmpfile > /usr/local/share/ca-certificates/<private-feed-domain>.crt
RUN apt-get install -y ca-certificates
RUN chmod 644 /usr/local/share/ca-certificates/<private-feed-domain>.crt && update-ca-certificates

Disclaimer: Use this snippet only if you are in charge of the destination, otherwise its a security risk.

For a more secure approach, download your CA manuelly (if its a chained one ,the root and any intermediate CA as well), verify it and copy it to your docker container:

RUN apt-get install -y ca-certificates
COPY <private-feed-domain>.crt /usr/local/share/ca-certificates/<private-feed-domain>.crt
RUN chmod 644 /usr/local/share/ca-certificates/<private-feed-domain>.crt && update-ca-certificates
howardButcher
  • 331
  • 1
  • 9
  • Hi @howardButcher I add your snippet in a fresh alpine dockerfile and work, but if I add these lines before the ```RUN dotnet restore --verbosity detailed``` dotnet restore continue failing as mentioned in my post :( – DavideP Jan 07 '23 at 16:18
  • What do you mean by a fresh alpine dockerfile? What’s the output of „ update-ca-certificates“ ? – howardButcher Jan 08 '23 at 10:51
  • 1
    Hi @howardButcher I mean that the curl to the endpoint work (does not get SSL connection error) but the dotnet restore stuck as before with the same error message. How can I see the result of ```update-ca-certificates``` in console? Thanks a lot – DavideP Jan 08 '23 at 12:13
  • It should be visible when running docker build —no-cache. Any chance to try „ FROM mcr.microsoft.com/dotnet/sdk:6.0-focal as build“ instead of „ FROM mcr.microsoft.com/dotnet/sdk:6.0-alpine3.16 as build“? – howardButcher Jan 08 '23 at 12:49
  • Hi @howardButcher, running these lines in a test dockerfile: ```FROM mcr.microsoft.com/dotnet/sdk:6.0-focal as build RUN echo | openssl s_client -host -port 443 -prexit -showcerts> tmpfile RUN echo | sed -n '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' tmpfile > /usr/local/share/ca-certificates/.crt RUN apt-get install -y ca-certificates RUN chmod 644 /usr/local/share/ca-certificates/.crt && update-ca-certificates RUN curl -f -LI https:///api/v4/projects/408/packages/nuget/index.json``` – DavideP Jan 08 '23 at 14:22
  • running the code attached in my previous post I get a 401 ```curl: (22) The requested URL returned error: 401``` – DavideP Jan 08 '23 at 14:25
  • 401 means unauthorized. Which means the connection could be established. Do you need authorization for your nuget feed? – howardButcher Jan 08 '23 at 15:49
  • Yes I have inside the nuget.config the username and password that is a PAT I have generated in gitlab. nuget.config is at solution level and is copied inside the container – DavideP Jan 08 '23 at 15:55
  • What’s the output of Dotnet restore in the „focal“ dockerfile? – howardButcher Jan 08 '23 at 16:02
  • I get the same error in the focal version... – DavideP Jan 08 '23 at 16:12
  • Are your envs properly escaped? Like: ENV VSS_NUGET_EXTERNAL_FEED_ENDPOINTS "{\"endpointCredentials\": [{\"endpoint\":\"${ARTIFACTS_ENDPOINT}\", \"password\":\"${ACCESS_TOKEN}\"}]}" – howardButcher Jan 08 '23 at 16:20
  • Also try to set ENV NUGET_CREDENTIALPROVIDER_SESSIONTOKENCACHE_ENABLED true – howardButcher Jan 08 '23 at 16:21
  • Hi @howardButcher, I added to my original post a UPDATE section with suggestion received but despite those, error persist :( – DavideP Jan 08 '23 at 20:58
  • What about passing the endpoints via -s argument to be sure nothing is wrong with the nuget.config – howardButcher Jan 08 '23 at 23:01
  • 1
    Hi @howardButcher, I understand the issue. I have my gitlab that host nugets, but the only .crt is not enought. I have to copy in the ```/usr/local/share/ca-certificates/``` the ROOT CA, the Intermediate CA, and finally .crt. If only one crt is missing I got that error. FINALLY! Seems that is as LINUX would the certificate chain. – DavideP Jan 09 '23 at 08:58
  • Glad to here it works! Do you know if its possible to get the chained CA at once? – howardButcher Jan 09 '23 at 13:09
  • Honestly I don't know right now how to / if is possible to get the cained CA one shot; I tried this way cause speaking with my IT colleague he told me that on LINUX he had trouble with certificates and he had to rebuild all certificate chain so I followed his idea. – DavideP Jan 09 '23 at 14:23