.NetCore CI pipeline error on docker tasks - docker

I am creating a CI pipeline in Azure for a .NetCore 3.1 application and adding Docker "buildandpush" tasks. i have 2 cases, if i run only .Netcore tasks (restore, build, test, publish) my build success With out any error, if i disable above .NetCore tasks and run only docker(buildAndpublish) Tasks my build success and image pushed into my ACR, but if I enable above .NetCore tasks along with Docker tasks throw an error here.
Can any one tell me the Build definition of .netCore tasks, is i am doing the right things.
ERROR
C:\Program Files\dotnet\sdk\3.1.100\NuGet.targets(123,5): error :
Access to the path 'C:\src\RINWeb\obj\RINMVC.csproj.nuget.dgspec.json'
is denied. [C:\src\RINWeb\RINMVC.csproj]
Build FAILED.
C:\Program Files\dotnet\sdk\3.1.100\NuGet.targets(123,5): error :
Access to the path 'C:\src\RINWeb\obj\RINMVC.csproj.nuget.dgspec.json'
is denied. [C:\src\RINWeb\RINMVC.csproj]
0 Warning(s)
1 Error(s)
Time Elapsed 00:00:01.34
The command 'cmd /S /C dotnet build "RINMVC.csproj" -c Release -o /app/build' returned a non-zero code: 1
[error]The process 'C:\Program Files\Docker\docker.exe' failed with exit code 1
My docker file is:
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-nanoserver-1809 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
FROM mcr.microsoft.com/dotnet/core/sdk:3.1-nanoserver-1809 AS build
WORKDIR /src
#####COPY ["RINWeb/RINMVC.csproj", "RINWeb/"]
COPY ["RINMVC.csproj", "RINWeb/"]
RUN dotnet restore "RINWeb/RINMVC.csproj"
#####COPY . .
COPY . RINWeb/
WORKDIR "/src/RINWeb"
RUN dotnet build "RINMVC.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "RINMVC.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "RINMVC.dll"]

You can use two agent jobs to run your pipeline. On agent job to run the dotnet tasks and the second to run the docker task.
If you are using classic view build pipeline. You can click on the (...) on the Pipeline to add an agent job. Please check below screenshot.
Then run docker tasks in agent job2 and configure agent job2 to depend the successful run of agent job1. Please check below screenshot.
If you are using yaml pipeline. You can define multiple jobs. You can check here for more information.
Update:
Here is an example to build and push to ACR in Microsoft. You donot need to use dotnet tasks to build and publish your project only to check if the build is successful or not, since your dockfile is just repeating the the same dotnet commands. You can only use a docker task to build the dockfile.
Or you can modify your dockerfile to only have the last copy step to copy the published files from output folder of the dotnet publish task(remove the dotnet restore, build, publish steps from dockerfile), for your dotnet tasks already did the retore build and publish tasks.

Related

Docker Pull Access Denied for Repository does not exist or login required

I want to place the existing web api inside the docker container. I added the Docker file through visual studio.
The application build is successful. But when I try to run the docker. It doesn't provide any information.
The docker repository is created
when i run the below cmd it executes and doesn't throw any error
The IOswagger is my application image.
When I run the image without the tag. The command automatically takes the tag of another image and it throws an error saying the repository doesn't exists.
In the docker the image is running.
Docker FIle :
#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.
#Depending on the operating system of the host machines(s) that will build or run the containers, the image specified in the FROM statement may need to be changed.
#For more information, please see https://aka.ms/containercompat
FROM mcr.microsoft.com/dotnet/core/aspnet:3.0-nanoserver-1903 AS base
WORKDIR /app
EXPOSE 80
FROM mcr.microsoft.com/dotnet/core/sdk:3.0-nanoserver-1903 AS build
WORKDIR /src
COPY ["aspnetcore-server/src/IO.Swagger/IO.Swagger.csproj", "aspnetcore-server/src/IO.Swagger/"]
RUN dotnet restore "aspnetcore-server/src/IO.Swagger/IO.Swagger.csproj"
COPY . .
WORKDIR "/src/aspnetcore-server/src/IO.Swagger"
RUN dotnet build "IO.Swagger.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "IO.Swagger.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "IO.Swagger.dll"]
When I try to build the application using docker it fails. The build is failed by throwing "Command failed with exit code 1"
I don't know how to proceed further. Not sure whether my application is even running or not.
It's a bit late and not exactly the case what you described, but I have faced with the same error when specified in Dockerfile wrong link to docker image like
FROM microsoft-dotnet-aspnet:5.0 AS base
when it should be:
FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS base
or
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1 AS base

Is there a way to export files during a docker build?

I do a multistage build right now. The first stage compiles with credentials for my internal repos and I just keep the binaries as per this example: https://github.com/dotnet/dotnet-docker/blob/master/documentation/scenarios/nuget-credentials.md
But I want to run in CI server and need to provider the CI server with test and coverage reports. It would be most elegant to do this in the build layer but how do I get files out of a docker image during build?
For example:
FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build
WORKDIR /app
# Copy csproj and restore as distinct layers
COPY *.csproj .
COPY ./nuget.config .
RUN dotnet restore
# Copy and publish app and libraries
COPY . .
############ Get this files out #####################
# Generate test report. copy this to external directory
RUN dotnet test --logger trx
# Generate coverage report. copy this to external directory
RUN dotCover.sh dotnet --output=myRep.html --reportType=HTML -- test
#######################################################
RUN dotnet publish -c Release -o out --no-restore
FROM mcr.microsoft.com/dotnet/core/runtime:3.1 AS runtime
WORKDIR /app/
COPY --from=build /app/out ./
ENTRYPOINT ["dotnet", "dotnetapp.dll"]
So I want to be able to run docker build and have it dump a test and coverage report to the current directory where docker build command was run. Is this possible? It would make this seamless for CI because all server must do is run docker build and it get reports
docker build supports an --output flag. I think it requires BuildKit (DOCKER_BUILDKIT=1). Here's one example usage.
https://docs.docker.com/engine/reference/commandline/build/ - then find --output on the page
https://docs.docker.com/engine/reference/commandline/build/#output

Docker Build does not break on compiling .NetCore Projects with missing files - instead it says "successfull"

Is there a possibility to break the docker build process if there are sources which cannot be found?
My colleagues and I thought this would be like every other build process: Expected source is not found? -> Cancel the process.
But we found out, docker build ignores these errors and builds happily and succesful a container, which explode at runtime.
I found the reason why the build failed and repaired the Dockerfile (missing copy instruction), but this is not the question. The problem is: why can the build be successful if files are missing? And how to tell docker build to stop working if there are errors?
Build Log:
...
Skipping project "/SomeFolders/MyOtherProject/MyOtherProject.csproj" because it was not found.
Restore completed in 225.55 ms for /MyProject/MyProject.csproj.
Restore completed in 225.56 ms for
MyProject/MyProject -> /MyProject/MyProject/bin/Release/netcoreapp3.1/MyProject/MyProject.dll
...
Build succeeded.
... some more steps ...
Successfully built 6c96bf48a019, Step 27/27
Dockerfile:
FROM mcr.microsoft.com/dotnet/core/runtime:3.1.1-alpine AS base
WORKDIR /app
FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build
LABEL maintainer="ECKD KIGST GmbH"
COPY ["nuget.config", "./"]
COPY ["SomeFolders/", "./"] (this was missing in the first run)
COPY ["Nachricht/", "./Nachricht"]
WORKDIR MyProject
RUN dotnet restore "MyProject.csproj"
RUN dotnet build "MyProject.csproj" -c Release --no-restore
FROM build AS publish
RUN dotnet publish "MyProject.csproj" -c Release --no-restore --no-build -o /app/publish
...
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "MyProject.dll"]
Build.ps1
$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
& docker build -f $scriptDir/Dockerfile --build-arg http_proxy=$env:http_proxy --build-arg https_proxy=$env:https_proxy --build-arg no_proxy=$env:no_proxy -t my-project:latest $scriptDir/../../.
Has anyone a solution for that?
Reading the build log for "Skipping project" is not an option. Especially not in automated build and deployment pipelines...
We are happy and thankful for any help.

Dotnet publish on linux error in docker (Azure DevOps build)

I have self-hosted linux build agent in Azure DevOps. I try to build&push docker task and i have an error like this(locally dotnet build worked):
The specified task executable "node" could not be run. System.ComponentModel.Win32Exception (2): No such file or directory [/src/Cillian.csproj]
My log:
...
Step 11/26 : RUN dotnet build -c Release -o /app
---> Running in 9233fd642015
Microsoft (R) Build Engine version 16.5.0+d4cbfca49 for .NET Core
Copyright (C) Microsoft Corporation. All rights reserved.
Restore completed in 1.51 sec for /src/Cillian.csproj.
/root/.nuget/packages/microsoft.typescript.msbuild/3.0.0/tools/Microsoft.TypeScript.targets(293,5): error MSB6003: The specified task executable "node" could not be run. System.ComponentModel.Win32Exception (2): No such file or directory [/src/Cillian.csproj]
...
Pipeline: AzureDevOpsImg
My Dockerfile:
FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build
WORKDIR /src
COPY *.csproj ./
RUN dotnet restore
COPY . .
WORKDIR /src
RUN dotnet build -c Release -o /app
FROM build AS publish
RUN dotnet publish -c Release -o /app
FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "Cillian.dll"]
No such file or directory
Just focus on this error message, dotnet build could not find the csproj file to continue the build. This is the mostly prone error in Azure devops even if it can be built successfully in local.
That is because the docker runs at the Repos/solution level locally(e.g. VS). BUT, for Azure devops CI, it running the docker in the directory where the dockerfile lives, which is at project level.
The nutshell is the relative path which can succeed to used in the local to find csproj, not avilable in the Azure devops at all. Because the working directory has changed.
Please specify $(Build.Repository.LocalPath) to the Docker 2.* argument Build context.
For YAML:
- task: Docker#2
displayName: build
inputs:
containerRegistry: DockerHub
repository: xxx/xxx
Dockerfile: Docker/TestWebApi/Dockerfile
buildContext: '$(Build.Repository.LocalPath)' # Specify the context
tags: latest

Unit Test Results from 'dotnet test' call in Docker

I am starting to investigate Azure Devops and its pipelines feature for setting up a continuous integration workflow. I have a pipeline that builds a Docker image of my application using the following dockerfile:
FROM mcr.microsoft.com/dotnet/core/sdk:2.2-stretch AS build-env
WORKDIR /cicd
# restore (put more volatile, changing projects later in process)
COPY src/WebApp/WebApp.csproj ./src/WebApp/
RUN dotnet restore src/WebApp/WebApp.csproj -s http://mycontainerrepo.acme.com/repository/nuget/
COPY tests/WebApp.Test/WebApp.Test.csproj ./tests/WebApp.Test/
RUN dotnet restore tests/WebApp.Test/WebApp.Test.csproj -s http://mycontainerrepo.acme.com/repository/nuget/
# copy source
COPY . .
# test (if tests fail, no final image, yay)
RUN dotnet test tests/WebApp.Test/WebApp.Test.csproj
# publish
RUN dotnet publish src/WebApp/WebApp.csproj -o /publish
# runtime stage
FROM mcr.microsoft.com/dotnet/core/aspnet:2.2-stretch-slim AS release
COPY --from=build-env /publish /publish
WORKDIR /publish
ENTRYPOINT ["dotnet", "WebApp.dll"]
The call to run dotnet test executes just fine and outputs results to the console, but I don't know of any way to make use of this result in the pipeline. In TeamCity, you could set an environment variable to sort of trick it into outputting the test results (xUnit only, I think...). But not sure if there's a similar trick here...
I saw this post on Github about making a separate test image just for testing but was hoping to avoid that route unless its my only option.
Any other CI/CD Azure Devops gurus out there?

Resources