Build docker container from solution with multiple projects - c#

I have a .NET Core project that contained 2 projects:
SLN:
- Web-API
- Infrastructure
I was building it with docker using this dockerfile
FROM microsoft/aspnetcore-build:2.0 AS build-env
WORKDIR /app
COPY . ./
RUN dotnet restore
COPY . ./
RUN dotnet publish -c Release -o out
# Build runtime image
FROM microsoft/aspnetcore:2.0
WORKDIR /app
COPY --from=build-env /app/ .
ENTRYPOINT ["dotnet", "/app/Lab/out/API.dll"]
But now I have created a Web application as well in my solution
SLN:
- Web-API
- Web-App
- Infrastructure
Suddenly, docker isn't building anymore. How come?
How can I create two docker containers based on the same solution one for the Web-API and one for the Web-app?
Error message from Docker:
The "GetDotNetHost" task could not be loaded from the assembly /usr/share/dotnet/sdk/NuGetFallbackFolder/microsoft.aspnetcore.mvc.razor.viewcompilation/2.0.3/build/netstandard2.0/Microsoft.AspNetCore.Mvc.Razor.ViewCompilation.Tasks.dll. Assembly with same name is already loaded Confirm that the declaration is correct, that the assembly and all its dependencies are available, and that the task contains a public class that implements Microsoft.Build.Framework.ITask. [/app/Lab/API.csproj]

So this problem is now finally fixed. It actually turned out it was a problem while compiling a .net core 2.0 project when having Razor views available:
Razor view precompilation is currently unavailable when performing a
self-contained deployment (SCD) in ASP.NET Core 2.0. The feature will
be available for SCDs when 2.1 releases. For more information, see
View compilation fails when cross-compiling for Linux on Windows.
What I needed to do was to add the nuget package:
Microsoft.AspNetCore.Mvc.Razor.ViewCompilation
in my project to make it work. Strange thing was that it was building inside visual studio for Mac but not from the command prompt.

Related

It was not possible to find any installed .NET Core SDKs

I am trying to build a Docker image and run a container for my sample ASP.NET Core 3.1 app and am seeing
It was not possible to find any installed .NET Core SDKs
when I run the command
docker run --rm -it -p 8000:80 ppi
My Dockerfile is simple:
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1
COPY publish/ ./
ENTRYPOINT ["dotnet", "sampleapp.dll"]
and I am pre-building my app into the publish folder. My folder structure looks as follows:
root/
source/
SampleApp.csproj
appsettings.json
Startup.cs
Program.cs
publish/
SampleApp.dll
SampleApp.exe
appsettings.json
SampleApp.deps.json
SampleApp.runtimeconfig.json
web.config
Dockerfile
SampleApp.sln
I created the image using the following command
docker build -t ppi
There are no issues with my sample app, as I'm able to launch it locally with the following command
dotnet publish/sampleapp.dll
What am I missing here? I've been working off of the following tutorials:
Building .NET Docker Images
dotnet-docket/samples/aspnetapp
summary answer:
This image mcr.microsoft.com/dotnet/core/aspnet:3.1 is a .NET Runtime.
The recommended way of creating a docker image is to copy the code inside a dotnet sdk image.
And fire all the build commands inside the docker image.
Once done. You copy only the publish folder to a dotnet runtime image (the one you are using).
If you are using visual studio; use the Add Docker Support option to generate a Dockerfile. And everything should work like a charm.
The error message is a little cryptic in saying that not all the files are present for running the application.
Your Dockerfile should look like below:
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 ["myaspnetapp.csproj", ""]
RUN dotnet restore "./myaspnetapp.csproj"
COPY . .
WORKDIR "/src/."
RUN dotnet build "myaspnetapp.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "myaspnetapp.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "myaspnetapp.dll"]
I had the same issue but did not want to build the app using the mcr.microsoft.com/dotnet/core/sdk:3.1-buster image. I discovered the shell running in the Linux container (bash) is case sensitive.
In your Dockerfile, change ENTRYPOINT ["dotnet", "sampleapp.dll"] to ENTRYPOINT ["dotnet", "SampleApp.dll"].
On Windows 10 either command will work since the shell there is case insensitive.
"Works on my machine..." anyone?
I get this error on Windows, when trying to run the Published version, ie just trying to use the runtime, not the sdk.
The solution for me was to change this:
dotnet sample
to this:
dotnet sample.dll

Missing DLL in docker image after copying published tree inside

I am currently experimenting with using JIB for packaging and deploying a dotnet project not written by me (I am not very familiar with dotnet).
I have the dotnet SDK installed (and visual studio 19) on my windows machine and after invoking "dotnet publish -c Release" on my solution which contain a project X and a test project X_test I end up with a bin/Release/netcoreapp2.1\publish folder.
In here I can run "dotnet X.dll" and the application starts.
Now I want to deploy said published folder to a docker image. My first attempt was using mcr.microsoft.com/dotnet/core/runtime:2.1 which caused
It was not possible to find any compatible framework version
The specified framework 'Microsoft.AspNetCore.App', version '2.1.1' was not found.
- Check application dependencies and target a framework version installed at:
/usr/share/dotnet/
- Installing .NET Core prerequisites might help resolve this problem:
https://go.microsoft.com/fwlink/?LinkID=798306&clcid=0x409
- The .NET Core framework and SDK can be installed from:
https://aka.ms/dotnet-download
I then tried using mcr.microsoft.com/dotnet/core/aspnet:2.1 which gave
C:\Users\m86194\git\microsvc-operational-information>docker run -it operational-information-ms:0.0.1-SNAPSHOT bash
Error:
An assembly specified in the application dependencies manifest (Operational_Information.deps.json) was not found:
package: 'Elasticsearch.Net', version: '6.0.0'
path: 'lib/netstandard1.3/Elasticsearch.Net.dll'
There is an "Elasticsearch.Net.dll" file in the root of bin\Release\netcoreapp21\publish folder, but not elsewhere.
I believe there is something about the build process I am missing.
Suggestions?
Try doing a dotnet restore before executing the publish command. Alternatively, you can use a multi stage docker build. See https://docs.docker.com/engine/examples/dotnetcore/ (mind the aspnet core version)
I had the same problem with Asp.Net Core 3 and since I'm neither well versed in Docker nor the .Net build system, I used the default Dockerfile Visual Studio creates.
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build
WORKDIR /src
COPY ["Application/Application.csproj", "Application/"]
COPY ["Dependency1/Dependency1.csproj", "Dependency1/"]
RUN dotnet restore "Application/Application.csproj"
COPY . .
WORKDIR "/src/Application"
RUN dotnet build "Application.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "Application.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "application.dll"]
By default it only runs dotnet restore for the main application. After adding the same for the dependent projects, it works.
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build
WORKDIR /src
COPY ["Application/Application.csproj", "Application/"]
COPY ["Dependency1/Dependency1.csproj", "Dependency1/"]
RUN dotnet restore "Dependency1/Dependency1.csproj" <-- this one is new
RUN dotnet restore "Application/Application.csproj"
COPY . .
WORKDIR "/src/Application"
RUN dotnet build "Application.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "Application.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "application.dll"]
Turned out that I had made a mistake when specifying the docker file deployment.
Instead of using bin\Release\netcoreapp21\publish I used bin\Release\netcoreapp21\ which also has an X.dll along the publish folder but gave the error. Changing to use the publish folder instead, solved the problem.

"Did you mean to run dotnet SDK commands? Please install dotnetsdk" in windows command prompt

I have just installed dot net core sdk and runtime (2.2.1) on my system viz. a Windows Server 2012R2.
I am trying to create a console app using the command prompt using
dotnet new console
but it says
Did you mean to run dotnet SDK commands? Please install dotnetsdk
Is there any other configurations needed. The Environment path variable also contains the following folder C:\Program Files\dotnet.
I have not installed VS2017. Was trying to use VS Code
In my case somehow I also had a C:\Program Files (x86)\dotnet with a runtime version there which was picked from Path instead of the SDK in C:\Program Files\dotnet
This was causing exactly the same error message + it was breaking solutions in Visual Studio (but not in Rider)
Please, make sure you've installed SDK not just runtime.
UPDATE
This is what you will see on the server without SDK installed if you run dotnet.exe --list-sdks command
And this with SDK installed:
One needs to install SDK on a development machine to be able to build and run applications and runtime (usually on an application server or user machine) to be able to just run built applications.
I was getting the same problem when I was trying to dockerize my .Net Core 2.2 Web API solution.
I was using the below images to build the images. Please note that place where the sdk(mcr.microsoft.com/dotnet/core/sdk:2.2) is used.
FROM mcr.microsoft.com/dotnet/core/sdk:2.2 AS base
WORKDIR /app
EXPOSE 5051
FROM mcr.microsoft.com/dotnet/core/aspnet:2.2 AS build
Apparently the order I was used is wrong, So I changed it as preceding .
FROM mcr.microsoft.com/dotnet/core/aspnet:2.2 AS base
WORKDIR /app
EXPOSE 5051
FROM mcr.microsoft.com/dotnet/core/sdk:2.2 AS build
WORKDIR /src
........
RUN dotnet restore "Api.csproj"
WORKDIR "/src/Api"
COPY . .
WORKDIR "/src/Api"
RUN dotnet build "Api.csproj" -c Release -o /app
FROM build AS publish
RUN dotnet publish "Api.csproj" -c Release -o /app
FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENV ASPNETCORE_ENVIRONMENT DevStaging
ENV ASPNETCORE_URLS=http://+:5051
ENTRYPOINT ["dotnet", "Api.dll"]
This fixed my issue. Hope it helps.

Building a Docker image from a multi project dot net core solution

I am trying to build a docker image from a visual studio solution that consists of two projects:
one project contains common code (http methods, logging etc)
the other is the business logic and application
I can build and run in Visual Studio, which produces a Docker image that I am able to deploy to our test environment. However, any POSTs sent to the API in the test environment return a 500 error. I can see references like: '/Users/Tim/Documents/Dotnet Code/dotnetcore-app/App/MyClass.cs' in the error response, which leads me to suspect there is something up with the image - that path is on my laptop.
Hoping someone else may have come across something similar, or could provide some pointers about building a multi project solution like this into a Docker container.
Disclaimer: this is my first time working with dotnet core and visual studio - I have some experience with docker.
If you use "standard" Dockerfile template from Visual Studio, you might have issue with having your "common" project being built on your local PC (probably windows) and the "main" project being built in docker container (probably Linux). the "main" dll is referencing windows-built dll, hence the issues.
Make sure you are copying not only main project, but also the common project, so dotnet can build it in docker also.
Try out this dockerfile:
FROM microsoft/aspnetcore:2.0 AS base
WORKDIR /app
ENV ASPNETCORE_ENVIRONMENT=Production
ENV ASPNETCORE_URLS http://*:5000
EXPOSE 5000
FROM microsoft/aspnetcore-build:2.0 AS builder
ARG Configuration=Release
WORKDIR /src
COPY *.sln ./
COPY Project.Main/Project.Main.csproj Project.Main/
COPY Project.Common/Project.Common.csproj Project.Common/
RUN dotnet restore
COPY . .
WORKDIR /src/ProjectMain
RUN dotnet build -c $Configuration -o /app
FROM builder AS publish
ARG Configuration=Release
RUN dotnet publish -c $Configuration -o /app
FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "Project.Main.dll"]
Although is to build the "Main" project, it's executed on the sln level.

Exclude docker directory in .net core application

I have problems with running .net core app on my Debian 9. All .net core versions below 2.0 preview returns
"Failed to initialize CoreCLR, HRESULT: 0x80131500" error during execute dotnet new, restore or e.g --version.
.NET core 2.0 preview works correctly but framework doesn't want to cooperate with JwtBearer - becasue Bearer has 1.1.2 version and dotnet returns
"Downgrade package detected bla bla...."
(Maybe you have idea how to build app with downgrade package?)
So I decided to move project to docker.
I downloaded docker with .net core 1.1. I created docker-compose file, where I add a volume mount to docker see my application.
Everything works correctly, but with one small exception.
When I execute dotnet restore, build and run on my docker, everyting is beeing override, so my Visual Studio Code immidietly shows me warrining "Unresolved dependencies ...." and all references to dotnet namespaces, class etc are highlighted in red.
How I can fix it?
Below is my docker-compose.yml
version: '2'
services:
webapi:
build: .
command: "/bin/bash"
container_name: webapi
volumes:
- /home/pb/docker-test/docker-compose:/app
- /home/pb/docker-test/docker-compose/Evento.Api/obj/
ports:
- "5000:80"
tty: true
/home/pb/docker-test/docker-compose/Evento.Api/obj/ I think that this directory makes problems becouse contains a few path which are changing after dotnet restore.
I tried to exclude that directory in this way, but it doesn't work. Event if direcotry is not mounted, dotenet creates it after dotnet restore, and override on host.
Dockerfile
FROM microsoft/aspnetcore-build
WORKDIR /app

Categories