how to avoid manually copying csproj files in docker file - c#

I have multiple dotnet projects with multi level nesting and I am specifying each csproj with their path structure below for each and every application's docker file.
Whenever there is a addition and deletion of projects all docker file have to be update.
Can I avoid it and make some generic docker file?
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 My.sln .
COPY ["Core/Events.csproj", "Core/"]
COPY ["Core/Infra/Services/Services.csproj", "Core/Infra/Services/"]
COPY ["Features/Feature.A.API/Feature.A.API.csproj", "Features/Feature.A.API/"]
RUN dotnet restore
COPY . .

You could store all needed projects in a root dir lets call it src then you just have to use the main project for restore/build/publish (the one with your asp .net core webapi), all the other sources (dependencies) needed during build would then be present (in the src dir), with correct paths.
For example:
src/Core/....
src/Features/...
src/Features/Feature.A.API/Dockerfile
The docker file would then look like this (aspnet 5.0):
with place holders:
[API_DIR] in your case: Features/Feature.A.API/
[API_PROJECT] in your case: Feature.A.API
FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS base
WORKDIR /app
EXPOSE 80
FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
WORKDIR /src
COPY ["src/[API_DIR]/[API_PROJECT].csproj", "[API_DIR]/"]
RUN dotnet restore "[API_DIR]/[API_PROJECT].csproj"
COPY ["src/", "."]
WORKDIR "src/[API_DIR]"
RUN dotnet build "[API_PROJECT].csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "[API_PROJECT].csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "[API_PROJECT].dll"]
Run it from Folder which contains the src dir (this is your build context), with:
docker build src/Features/Feature.A.API/Dockerfile

Related

Unable to build Docker image for Arm32v7 with external assembly

I have an aspnet application which is using an external Assembly (from another project of mine).
I have added this as a project reference, and I can build and run my application locally fine, with no errors or problems.
But when trying to build this for Docker with Arm32v7 (Raspberry Pi) I get the error:
warning MSB3245: Could not resolve this reference. Could not locate
the assembly "SAM Shared". Check to make sure the assembly exists on
disk. If this reference is required by your code, you may get
compilation errors.
My docker file
#Below is changed to use the appropiate image for Rpi, arm32v7
FROM mcr.microsoft.com/dotnet/aspnet:6.0.1-bullseye-slim-arm32v7 AS base
WORKDIR /app
EXPOSE 80
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["HomeMonitor/HomeMonitor.csproj", "HomeMonitor/"]
COPY ["HomeMonitor.Shared/HomeMonitor.Shared.csproj", "HomeMonitor.Shared/"]
RUN dotnet restore "HomeMonitor/HomeMonitor.csproj"
COPY . .
WORKDIR "/src/HomeMonitor"
RUN dotnet build "HomeMonitor.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "HomeMonitor.csproj" -c Release -o /app/publish /p:UseAppHost=false
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "HomeMonitor.dll"]

mcr.microsoft.com/dotnet/aspnet:6.0-jammy-chiseled: not found

I have created the default WeatherForecast web api project with Docker support.
By default, the dockerfile is using aspnet: 6.0
But I would like to upgrade it to 6.0-jammy-chiseled. This is my dockerfile after I have updated it to 6.0-jammy-chiseled
FROM mcr.microsoft.com/dotnet/aspnet:6.0-jammy-chiseled AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
FROM mcr.microsoft.com/dotnet/sdk:6.0-jammy-chiseled AS build
WORKDIR /src
COPY ["Weather2.csproj", "."]
RUN dotnet restore "./Weather2.csproj"
COPY . .
WORKDIR "/src/."
RUN dotnet build "Weather2.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "Weather2.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "Weather2.dll"]
When I run it, I got an error:
mcr.microsoft.com/dotnet/aspnet:6.0-jammy-chiseled: not found
I try to pull the image manually with docker pull mcr.microsoft.com/dotnet/nightly/aspnet:6.0-jammy-chiseled and it pull without issue.
Based on the Docker file of the official sample app, I think that your Docker file should be revised as
FROM mcr.microsoft.com/dotnet/nightly/aspnet:6.0-jammy-chiseled AS base (add nightly in the image path)
and
FROM mcr.microsoft.com/dotnet/sdk:6.0-jammy AS build (remove -chiseled as SDK has no need to be chiseled and Microsoft will not publish chiseled SDK but only chiseled runtime.

Azure Devops Pipeline - file not found in build context

Getting an error in the Azure DevOps Pipeline:
Step 7/17 : COPY ["demo6/demo6.csproj", "demo6/"]
COPY failed: file not found in build context or excluded by .dockerignore: stat demo6/demo6.csproj: file does not exist
NOTES-run the pipeline in diagnostics mode and the .sln file exists
##[debug]cwd=/home/vsts/work/1/s
##[debug] /home/vsts/work/1/s/demo6.sln (file)
##[debug] /home/vsts/work/1/s/demo6/demo6.csproj (file)
I have a multi-project Asp.Net Core solution with the folder structure and projects as follows:
demo6
|--demo6/demo6.csproj
|--demo6.api/demo6.api.csproj
The app is demo6 which references demo6.api which is a class library.
This is in GitHub in a repository demo6. I modified the autogenerated Dockerfile to add the extra demo6/ to see if that works but no.
Appreciate any help.
Dockerfile below:
FROM mcr.microsoft.com/dotnet/aspnet:3.1 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
FROM mcr.microsoft.com/dotnet/sdk:3.1 AS build
WORKDIR /src
COPY ["demo6/demo6.csproj", "demo6/"]
RUN dotnet restore "demo6/demo6.csproj"
COPY . .
WORKDIR "/src/demo6"
RUN dotnet build "demo6.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "demo6.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "demo6.dll"]
Also tried this:
FROM mcr.microsoft.com/dotnet/aspnet:3.1 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
FROM mcr.microsoft.com/dotnet/sdk:3.1 AS build
WORKDIR /src
COPY ["demo6/demo6/demo6.csproj", "ddemo6/"]
RUN dotnet restore "ddemo6/demo6.csproj"
COPY . .
WORKDIR "/src/ddemo6"
RUN dotnet build "demo6.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "demo6.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "demo6.dll"]
Got this error:
Step 7/17 : COPY ["demo6/demo6/demo6.csproj", "ddemo6/"]
COPY failed: file not found in build context or excluded by .dockerignore: stat demo6/demo6/demo6.csproj: file does not exist
##[error]COPY failed: file not found in build context or excluded by .dockerignore: stat demo6/demo6/demo6.csproj: file does not exist
here's the repo structure
The reason of file not found error may be the relative path of the Dockerfile and the csproj are different. Try to set the Dockerfile in the root of the solution should solve your error.
Also you need to add a buildContext with the csproj folder.
buildContext: Path to the build context
Also, here is a case you can refer to.
One more possible cause of COPY failed: no source files were specified is .dockerignore file present in your workspace
Look for .dockerignore file because of docker’s CLI (command line interface) it sends context to the docker daemon to load the .dockerignore file.
If the .dockerignore file exist in the context than it might be possible there is exclude entry to ignore the build directory
# ignore or exclude build directory
*/build*
*/*/build*

How to lower down the size of dockerized .Net Core apps?

I normally use Rider for that but for reproduction purposes I will describe the process by using the terminal
I created a .Net 5 Web Api and want to add Docker support for it. I tried to get into it by playing around with a sample app. So with the terminal I create a new Web Api
mkdir project
cd project
dotnet new sln
dotnet new webapi -o Api
dotnet sln add ./Api
I check that everything is fine with
cd Api
dotnet run
call https://localhost:5001/weatherforecast in the browser
close with ctrl + c
Inside the Api project I create a Dockerfile with this content
FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
WORKDIR /app
COPY *.csproj ./
RUN dotnet restore
COPY . ./
RUN dotnet publish -c Release -o out
FROM mcr.microsoft.com/dotnet/aspnet
WORKDIR /app
EXPOSE 80
COPY --from=build /app/out .
ENTRYPOINT [ "dotnet", "Rest.dll" ]
I also create a .dockerignore file with this content
.git
Dockerfile
bin/
obj/
I'm building the image with
docker build -t api .
When I now run
docker images
this image has a size of 209MB. I would like to know if this is "the best/right way to go" or if there is something I can improve in the Dockerfile or .dockerignore file.
Thanks in advance
You can base your Dockerfile off a smaller image. Searching the catalogue of available images in the Microsoft container registry (MCR) here, the Linux alpine (5.0-alpine) is probably the most lightweight. Note that for the other distros, there may be a regular and slim variant, where the regular is the SDK environment and the slim is the production environment.
Then you can structure your Dockerfile as follows to move the artefacts from the build output in the SDK image to the final lightweight deployment image:
FROM mcr.microsoft.com/dotnet/core/runtime:3.1-buster-slim AS base
WORKDIR /app
# Main build (SDK environment)
FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build
WORKDIR /src
RUN dotnet restore "webapi.csproj"
COPY . .
WORKDIR "/src/webapi"
RUN dotnet build "webapi.csproj" -c Release -o /app/build
# Publish build outputs to /app dir
FROM build AS publish
RUN dotnet publish "webapi.csproj" -c Release -o /app/publish
# Final deployment image
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "api.dll"]
In my example, I've used the Debian buster SDK image for the build stage and the buster slim for deployment.

Missing files when running ASP.NET Core application in Docker: How to display files when the container is running?

I have a simple ASP.NET Core solution that I dockerize and seems that some files that are supposedly copied to the output as always are not present when my application is running via Docker.
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-bionic AS base
ENV RUNNING_IN_DOCKER=true
WORKDIR /app
EXPOSE 80
FROM mcr.microsoft.com/dotnet/core/sdk:3.1-bionic AS source
WORKDIR /src
COPY ["SecretProject.Core/SecretProject.Core.csproj", "SecretProject.Core/"]
COPY ["SecretProject.DAL/SecretProject.DAL.csproj", "SecretProject.DAL/"]
COPY ["SecretProject.Utils/SecretProject.Utils.csproj", "SecretProject.Utils/"]
COPY ["SecretProject.Externals/SecretProject.Externals.csproj", "SecretProject.Externals/"]
COPY ["NuGet.Config", "/"]
RUN dotnet restore "SecretProject.Core/SecretProject.Core.csproj"
FROM source AS build
COPY . .
WORKDIR "/src/SecretProject.Core"
RUN dotnet build "SecretProject.Core.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "SecretProject.Core.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "SecretProject.Core.dll"]
Missing files are the ones there: SecretProject.Core/Views/EmailTemplates/*.*
I would like to see the files when the container is running, I am indeed suspecting that not everything is copied.
Instead of having all these lines
COPY ["SecretProject.Core/SecretProject.Core.csproj", "SecretProject.Core/"]
COPY ["SecretProject.DAL/SecretProject.DAL.csproj", "SecretProject.DAL/"]
COPY ["SecretProject.Utils/SecretProject.Utils.csproj", "SecretProject.Utils/"]
COPY ["SecretProject.Externals/SecretProject.Externals.csproj", "SecretProject.Externals/"]
COPY ["NuGet.Config", "/"]
Replace for
COPY . .

Categories