Visual Studio: docker build fails when linked files are in the project - docker

I have a .NET 6 Console project that includes 2 binaries as linked files:
<ItemGroup>
<None Include="..\HFMath\bin\HFMath.dll" Link="HFMath.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="..\HFMath\bin\libHFMath.so" Link="libHFMath.so">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
I need to deploy it as a docker container. The Dockerfile scaffolded by Visual Studio is
FROM mcr.microsoft.com/dotnet/runtime:6.0 AS base
WORKDIR /app
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["ConsoleApp1/ConsoleApp1.csproj", "ConsoleApp1/"]
RUN dotnet restore "ConsoleApp1/ConsoleApp1.csproj"
COPY . .
WORKDIR "/src/ConsoleApp1"
RUN dotnet build "ConsoleApp1.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "ConsoleApp1.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "ConsoleApp1.dll"]
when I run docker build, I get the following error:
#15 1.054 Determining projects to restore...
#15 1.322 All projects are up-to-date for restore.
#15 2.552 /usr/share/dotnet/sdk/6.0.100/Microsoft.Common.CurrentVersion.targets(5100,5): error MSB3030: Could not copy the file "/src/HFMath/bin/libHFMath.so" because it was not found. [/src/ConsoleApp1/ConsoleApp1.csproj]
#15 2.552 /usr/share/dotnet/sdk/6.0.100/Microsoft.Common.CurrentVersion.targets(5100,5): error MSB3030: Could not copy the file "/src/HFMath/bin/HFMath.dll" because it was not found. [/src/ConsoleApp1/ConsoleApp1.csproj]
#15 2.556
#15 2.556 Build FAILED.
I know that docker doesn't support symlinks, but I still need to build the image.
How do I fix this (without changing the .NET project)?

Problem
If you have auto generated the Dockerfile using Visual Studio, it will also have created a .dockerignore file (usually in the .sln folder). That file will contain an entry to exclude **/bin from the build context.
This means when the COPY . . executes, it is ignoring the files in any bin folder
Solution
Find and edit the .dockerignore file.
Add the line !HFMath/bin/ - this will tell Docker to NOT ignore the HFMath/bin folder
Run your docker build command again

Related

Confirm that the expression in the Import declaration is correct docker csproj

I have an API project named TIcket in ASP.Net 6.0. I added a shared project named Models and its import in Ticket.csproj looks like this <Import Project="..\Models\Models.projitems" Label="Shared" />. Now I want to build a docker image docker build -t ticket . and getting this error
/src/Ticket.csproj(18,3): error MSB4019: The imported project "/Models/Models.projitems" was not found. Confirm that the expression in the Import declaration "../Models/Models.projitems" is correct, and that the file exists on disk.
executor failed running [/bin/sh -c dotnet publish]: exit code: 1
While the shared file path is correct. Project opens, run and builds successfully.
docker file content in Ticket project are
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY Ticket.csproj .
RUN dotnet restore
COPY . .
RUN dotnet publish
FROM mcr.microsoft.com/dotnet/aspnet:6.0
WORKDIR /app
COPY --from=build /app .
ENTRYPOINT ["dotnet", "Ticket.dll"]

cannot run docker build when using docker setup from Visual Studio

I created a web-project named ProjectService and added docker-support for it using Visual Studio 2022. I can build and debug the image pretty well from within VS.
Now I try to build and run the image from the command-line in order to have it within my build-pipeline. So I execute this from the root-directory of my repo:
docker build -t myrep/demo:latest ./ProjectService
However when I do that I get the following error:
#11 ERROR: "/ProjectService/ProjectService.csproj" not found: not found
#12 [build 4/8] COPY [DatabaseManager/DatabaseManager.csproj, DatabaseManager/]
#12 sha256:b881c00e01ebb7ea687c2f8c5d5f585e237bf6151b63cd21110ed1a7bdf74af6
#12 ERROR: "/DatabaseManager/DatabaseManager.csproj" not found: not found
I think this is because within my docker-file paths are relative:
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["ProjectService/ProjectService.csproj", "ProjectService/"]
COPY ["DatabaseManager/DatabaseManager.csproj", "DatabaseManager/"]
RUN dotnet restore "ProjectService/ProjectService.csproj"
COPY . .
WORKDIR "/src/ProjectService"
RUN dotnet build "ProjectService.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "ProjectService.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "ProjectService.dll"]
when I execute docker from within the ProjectService-drectory itself, I get the same error, though.
My folder-structure is this:
root
ProjectService
ProjectService.csproj
DockerFile
DatabaseManager
DatabaseManager.csproj
where ProjectService depends on DatabaseManager.
Your Dockerfile looks like it assumes that the build context is the root directory.
So to build it you can either do it from the root directory with
docker build -t myrep/demo:latest -f ProjectService/Dockerfile .
or from the ProjectService directory with
docker build -t myrep/demo:latest ..
A 3rd option is to move the Dockerfile to the root directory. Then your Dockerfile will be in the directory that's assumed to be the build context. That's how most projects are organized. Then you can build with
docker build -t myrep/demo:latest .

ASP.NET Core build docker image having shared libraries

I'm working in a microservice environemnt where there are shared libraries between these microservices.
These libraries are stored in a different location on the disk, a "shared" location, and are directly referenced by these microservices.
In a .csproj of such a microservice you would see something like this.
<ItemGroup>
<ProjectReference Include="..\..\..\Shared1.csproj" />
<ItemGropu>
Now in each of these microservices I have a dockerfile
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base
WORKDIR /app
EXPOSE 80
FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build
WORKDIR /src
COPY . .
COPY ../../../Users/boris/Desktop/shared/Shared/Shared/Shared.csproj .
RUN dotnet restore "WebUi.csproj"
WORKDIR /src/.
RUN dotnet build "WebUi.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "WebUi.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
RUN ls
ENTRYPOINT ["dotnet", "WebUi.dll"]
when building a image
docker build -f dockerfile .
I'm getting
ERROR [build 4/7] COPY ..\..\..\Users\boris\Desktop\shared\Shared\Shared\Shared.csproj .
[build 4/7] COPY
......\Users\boris\Desktop\shared\Shared\Shared\Shared.csproj .:
failed to solve with frontend dockerfile.v0: failed to build LLB:
failed to compute cache key:
"/..\..\..\Users\boris\Desktop\shared\Shared\Shared\Shared.csproj"
not found: not found PS C:.demos\hangfire-dashboard\WebUi> docker
build -f .\dockerfile -t web . [+] Building 0.2s (10/18)
I'm thinking it's because of the build context, but not sure.
Any ideas on how can I fix this ?
Ok first thing first rename the dockerfile to Dockerfile. Next up is the path correct in the first place? I assume your csproj exists in the same folder as your Dockerfile and in your csproj you use <ProjectReference Include="..\..\..\Shared1.csproj" /> whereas in the docker file you use ../../../Users/boris/Desktop/shared/Shared/Shared/Shared.csproj so if the csproj AND the Dockerfile exist in the same directory the path is simply incorrect.

error NETSDK1064: Package DnsClient, 1.2.0 was not found

I have an Asp.Net core docker image. The last time I tried building it was 2 months ago. Now, I'm getting an error while trying to build it.
Any ideas? Did something break the Microsoft docker image? This is also breaking when trying to publish and run on an Elasticbeanstalk instance.
Complete Error Log:
/usr/share/dotnet/sdk/3.1.201/Sdks/Microsoft.NET.Sdk/targets/Microsoft.PackageDependencyResolution.targets(234,5): error NETSDK1064: Package DnsClient, version 1.2.0 was not found. It might have been deleted since NuGet restore. Otherwise, NuGet restore might have only partially completed, which might have been due to maximum path length restrictions. [/app/BacktraderDataApi.csproj]
The command '/bin/sh -c dotnet publish -c Release -o out' returned a non-zero code: 1
Dockerfile:
FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build-env
WORKDIR /app
COPY *.csproj ./
RUN dotnet restore
COPY . ./
RUN dotnet publish -c Release -o out
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1
WORKDIR /app
COPY --from=build-env /app/out .
EXPOSE 5000
ENTRYPOINT ["dotnet", "myApp.dll"]
When solutions like using --no-cache are not restoring at all work, it usually indicates that artifact from the host machine are getting copied into the build container. This can cause problems when the host machine and build container have different RIDs. This can commonly occur on Windows machines when running linux containers. The .NET Core Docker Samples suggest using a .dockerignore file to avoid coping the bin and obj directories with your Dockerfiles.
For me it helped adding a --no-cache flag
RUN dotnet publish -c Release -o out --no-cache
Based on the information posted at https://github.com/microsoft/containerregistry/issues/20 for this same issue as well as the information here I tried the following:
dotnet new web
Edit the csproj and added the following:
<ItemGroup>
<PackageReference Include="MongoDB.Driver" Version="2.10.1" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
</ItemGroup>
Created the following Dockerfile
# https://hub.docker.com/_/microsoft-dotnet-core
FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build
WORKDIR /source
# copy csproj and restore as distinct layers
COPY *.csproj .
RUN dotnet restore
# copy and publish app and libraries
COPY . .
RUN dotnet publish -c release -o /app --no-restore
# final stage/image
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1
WORKDIR /app
COPY --from=build /app ./
ENTRYPOINT ["dotnet", "aspnetapp.dll"]
Created the following .dockerignore
# directories
**/bin/
**/obj/
**/out/
# files
Dockerfile*
**/*.trx
**/*.md
**/*.ps1
**/*.cmd
**/*.sh
docker build --pull -t test .
The Dockerfile built without issue. Can you try these steps and report back the results?
I had a very similar problem
error MSB4018: NuGet.Packaging.Core.PackagingException: Unable to find fallback package folder '/usr/local/share/dotnet/sdk/NuGetFallbackFolder'.
I added RUN mkdir -p /usr/local/share/dotnet/sdk/NuGetFallbackFolder.
Then it got a lot farther but failed with a library resolution for something that I believe is just distributed with the SDK.
/usr/share/dotnet/sdk/3.1.201/Sdks/Microsoft.NET.Sdk/targets/Microsoft.PackageDependencyResolution.targets(234,5): error NETSDK1064: Package Microsoft.EntityFrameworkCore.Analyzers, version 3.1.1 was not found. It might have been deleted since NuGet restore. Otherwise, NuGet restore might have only partially completed, which might have been due to maximum path length restrictions.
I think the mcr.microsoft.com/dotnet/core/sdk:3.1 4/09/2010 Docker image with tags 3.1.201-buster, 3.1-buster, 3.1.201, 3.1, latest is broken.
I changed to the image based on Ubuntu bionic and it just worked again.
USE mcr.microsoft.com/dotnet/core/sdk:3.1-bionic
I was having the same issue, after i read this link https://github.com/dotnet/sdk/issues/3059
I just appended the /restore to build command and it worked.
just like this
RUN dotnet publish --no-restore -c Release -o /app --no-cache /restore
and now it is working just fine.

Docker compose build copy failed

I am really curious to how to interpret and debug with the following error:-
C:\users\project>docker-compose build
Step 6/15 : COPY *.csproj ./
ERROR: Service 'invoiceservice' failed to build: COPY failed: no source files were specified
This is particular micro-service as i have few more such services.
docker file :-
FROM mcr.microsoft.com/dotnet/core/runtime:2.2 AS base
WORKDIR /app
EXPOSE 80
FROM mcr.microsoft.com/dotnet/core/sdk:2.2 AS build
WORKDIR /src
COPY *.csproj ./
RUN dotnet restore -s https://api.nuget.org/v3/index.json -s https://www.myget.org/F/autoweb/api/v3/index.json
COPY . .
WORKDIR /src/src/InvoiceManagement/InvoiceService
RUN dotnet publish -c Release -o out
FROM build AS publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/out .
ENTRYPOINT ["dotnet", "InvoiceService.dll"]
Interesting part is when I build this from Visual Studio IDE, its being built fine but it does not build on CLI.
docker compose file:-
invoiceservice:
image: ${DOCKER_REGISTRY-}invoiceservice
build:
context: .
dockerfile: src/InvoiceManagement/InvoiceService/Dockerfile
I don't understand why CLI could not find the source location and copy where as VS works fine. Any clue???
It's likely an issue with your Docker context. Commands in Dockerfiles are relative to where the docker/docker-compose CLI tool is run, not relative to the Dockerfile location.
In other words, if you run the command from the solution root, then your csproj file is actually under ./src/InvoiceManagement/InvoiceService. As a result, *.csproj finds no files, because there's no project files literally in your solution root.
I tried replicating your problem and I was able to copy all the files successfully (instead of .csproj, I used .txt). The problem occurred when there was no txt file to copy. My COPY command failed with exactly the same message as yours.
Now, why is VS able to build the image successfully? That is because VS build the project first! When the project's build procedure is completed, a .csproj file is generated and that gets copied to the image.
To confirm the results, ls your current directory (when the build fails from command line) and see if there is any .csproj file in that directory.

Resources