dockergitlab-cinuget-packagecontainer-registry

Impossible to get nuget package from another gitlab project (error NU1301)


I installed Gitlab locally. I have two projects: a toolkit (project 1) and a second project (project 2) which uses the nuget package from this first project. The nuget package is stored in Gitlab's package registry of project 1.

I want to create a docker image of project 2 and store it in the Gitlab container registry of project 2.

My gitlab-ci.yml file is as follows:

stages:
  - deploy

deploy-solution:
  stage: deploy
  image: docker:20.10.16
  services:
    - docker:20.10.16-dind
  before_script:
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
  script:
    - docker build --pull -t $CI_REGISTRY_IMAGE --build-arg TOKEN=$CI_JOB_TOKEN --no-cache .
    - docker push $CI_REGISTRY_IMAGE
  only:
    - main

My nuget.config file is as follows:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <packageSources>
    <clear />
    <add key="gitlab" value="https://<localdomain>/api/v4/projects/<project1_id>/packages/nuget/index.json" />
    <add key="nuget" value="https://api.nuget.org/v3/index.json" />
  </packageSources>
  <packageSourceCredentials>
    <gitlab>
      <add key="Username" value="gitlab-ci-token" />
      <add key="ClearTextPassword" value="$TOKEN_ENV" />
    </gitlab>
  </packageSourceCredentials>
</configuration>

My Dockerfile is as follows:

FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

# Build
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build

## Certificates SSL
WORKDIR /usr/local/share/ca-certificates/
COPY ["ca.crt", "."]
RUN update-ca-certificates -f

## Copy sources and build
WORKDIR /src
COPY ["nuget.config", "."]
ARG TOKEN
ENV TOKEN_ENV=$TOKEN
#RUN sed -i "s/PASSWORD/$TOKEN_ENV/" nuget.config <-- By replacing a keyword in the nuget.config file
COPY ["Project2.API/Project2.API.csproj", "Project2.API/"]
RUN dotnet restore "Project2.API/Project2.API.csproj"
COPY . .
WORKDIR "/src/Project2.API"
RUN dotnet build "Project2.API.csproj" -c Release -o /app/build

# Publish
FROM build AS publish
RUN dotnet publish "Project2.API.csproj" -c Release -o /app/publish /p:UseAppHost=false

# Deploy
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "Project2.API.dll"]

The command in the gitlab-ci.yml file docker build --pull -t $CI_REGISTRY_IMAGE --build-arg TOKEN=$CI_JOB_TOKEN --no-cache . passes the token $CI_JOB_TOKEN as argument. This is retrieved in the Dockerfile and stored in an environment variable. This environment variable is used in the nuget.config file as $TOKEN_ENV.

When the restoring of the nuget package of project 1 is carried out with the command RUN dotnet restore "Project2.API/Project2.API.csproj", the following error is displayed:

error NU1301: Unable to load the service index for source https://<localdomain>/api/v4/projects/<project1_id>/packages/nuget/index.json. [/src/Project2.API/Project2.API.csproj]

I also tried to replace a keyword by the token in the nuget.config file with the command RUN sed -i "s/PASSWORD/$TOKEN_ENV/" nuget.config (see the line commented in the Dockerfileabove) after copying thenuget.config` file and after filling the environment variable with the token.

<add key="ClearTextPassword" value="PASSWORD" />

A reading of the file shows the keyword is replaced by [MASKED] and not by the token. So, I still get the same error.

Note that the project 2 has a token access to project 1 with a Gitlab's configuration in the project 1 (Project 1 > Settings > CI/CD > Access token).

How to fix the error ?


Solution

  • I added a stage build in the gitlab-ci file by reproducing the same preliminary steps as in the stage deploy:

    It works!

    I was then able to create an artifact of the result and reuse it for the stage deploy by copying it in a docker image.

    artifacts:
      paths:
        - publish/
    

    I was thus able to avoid the dependency restoring (causing the problem), the build and the publication in the Dockerfile which is simplified by the steps of port exposing, copying of application (artifact) and adding the entrypoint.

    FROM mcr.microsoft.com/dotnet/aspnet:6.0
    WORKDIR /app
    EXPOSE 80
    EXPOSE 443
    COPY publish .
    ENTRYPOINT ["dotnet", "OrderService.API.dll"]
    

    To conclude, the use of artifacts allowed me to solve the problem and to structure better the steps.