How to dockerize .NET6 AWS Lambda project with dependent class library projects - c#

I have four projects in one solution:
App.Data - class library
App.Core - class library
App.LambdaOne - AWS Lambda project
App.LambdaTwo - AWS Lambda project
The solution structure looks like this:
Solution:
App.Data
App.Core
App.LambdaOne
Dockerfile
App.LambdaTwo
Dockerfile
I am trying to create two docker images for App.LambdaOne and App.LambdaTwo, so I can deploy them separately.
So far, I have got a simple lambda project without any dependent project works using the Dockfile below.
Docker command in App.LambdaSimple's directory
docker build -t LambdaSimpleImage .
Dockerfile
FROM public.ecr.aws/lambda/dotnet:6 AS base
FROM mcr.microsoft.com/dotnet/sdk:6.0-bullseye-slim as build
WORKDIR /src
COPY ["App.LambdaSimple.csproj", "App.LambdaSimple/"]
RUN dotnet restore "App.LambdaSimple.csproj"
WORKDIR "/src/App.LambdaSimple"
COPY . .
RUN dotnet build "App.LambdaSimple.csproj" --configuration Release --output /app/build
FROM build AS publish
RUN dotnet publish "App.AWSLambdaOne.csproj" \
--configuration Release \
--runtime linux-x64 \
--self-contained false \
--output /app/publish \
-p:PublishReadyToRun=true
FROM base AS final
WORKDIR /var/task
COPY --from=publish /app/publish .
CMD ["App.LambdaSimple::App.LambdaSimple.Function::FunctionHandler"]
But the tricky part is that App.LambdaOnedepend on App.Data and App.Core. I tried to modify the working sample to deploy App.LambdaOne, but no luck so far. By running the same Docker command. Errors occurred, I have added those to the comments
FROM public.ecr.aws/lambda/dotnet:6 AS base
FROM mcr.microsoft.com/dotnet/sdk:6.0-bullseye-slim as build
WORKDIR /src
COPY ["App.AWSLambdaOne.csproj", "App.AWSLambdaOne/"]
#Error: cannot find App.Data.csproj
COPY ["App.Data.csproj", "App.Data/"]
RUN dotnet restore "App.LambdaOne.csproj"
WORKDIR "/src/App.AWSLambdaOne"
COPY . .
RUN dotnet build "App.AWSLambdaOne.csproj" --configuration Release --output /app/build
FROM build AS publish
RUN dotnet publish "App.AWSLambdaOne.csproj" \
--configuration Release \
--runtime linux-x64 \
--self-contained false \
--output /app/publish \
-p:PublishReadyToRun=true
FROM base AS final
WORKDIR /var/task
COPY --from=publish /app/publish .
CMD ["App.AWSLambdaOne::App.AWSLambdaOne.Function::FunctionHandler"]
I can understand why the error occurred, which is due to the Docker Context being under App.AWSLambdaOne. But cannot find any solution to fix it.
A partial solution I found is to have the Dockerfile at the Solution level, so Docker context includes all projects when building it. However, it does not fit my purpose since I want to build two images for different projects.
I have been searching for a clue in the last two days, it is driving me crazy. May I ask if it is possible to achieve what I am after with the existing project structure? If not can anyone please point me to the right direction?
THANKS A LOT in advance!

You can't access host files outside the build context, so you must move the build context up a directory to be able to access the code for the other projects. So to start, let's change the build command to
docker build -t LambdaSimpleImage ..
Now we need to adjust the Dockerfile so it fits the new context
FROM public.ecr.aws/lambda/dotnet:6 AS base
FROM mcr.microsoft.com/dotnet/sdk:6.0-bullseye-slim as build
WORKDIR /src
COPY ["App.LambdaSimple/App.LambdaSimple.csproj", "App.LambdaSimple/"]
COPY ["App.Data/App.Data.csproj", "App.Data/"]
COPY ["App.Core/App.Core.csproj", "App.Core/"]
RUN dotnet restore "App.LambdaSimple/App.LambdaSimple.csproj"
COPY . .
RUN dotnet build "App.LambdaSimple/App.LambdaSimple.csproj" --configuration Release --output /app/build
FROM build AS publish
RUN dotnet publish "App.LambdaSimple/App.LambdaSimple.csproj" \
--configuration Release \
--runtime linux-x64 \
--self-contained false \
--output /app/publish \
-p:PublishReadyToRun=true
FROM base AS final
WORKDIR /var/task
COPY --from=publish /app/publish .
CMD ["App.LambdaSimple::App.LambdaSimple.Function::FunctionHandler"]

Related

Unable to load the service index for source error for a CodeArtifact feed using a Dockerfile

It's my first question here so let me know if I have to change something or add more information.
We’re using AWS CodeArtifact for storing our packages and when we try to build a Docker image from our Dockerfile it fails because it's unable to load the source during the restore process.
We have a web API in .Net we want to deploy using AWS Fargate. This project runs smoothly from Visual Studio 2022 using Docker but we can’t build the image from PowerShell after adding our packages from CodeArtifact.
Our approach to include the credentials in the build is to pass the NuGet.Config stored on the host using Buildkit.
This’s our Dockerfile:
#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
EXPOSE 80
ENV ASPNETCORE_URLS=http://+:49151
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY . .
WORKDIR /src
COPY ["Src/Presentation/Project.API/Project.API.csproj", "Src/Presentation/Project.API/"]
RUN --mount=type=cache,id=nuget,target=/root/.nuget/packages \
--mount=type=secret,id=nugetconfig \
dotnet restore "Src/Presentation/Project.API/Project.API.csproj" \
--configfile /run/secrets/nugetconfig
COPY . .
WORKDIR "/src/Src/Presentation/Project.API"
RUN --mount=type=cache,id=nuget,target=/root/.nuget/packages \
dotnet build "Project.API.csproj" -c Release -o /app/build \
--no-restore
FROM build AS publish
RUN --mount=type=cache,id=nuget,target=/root/.nuget/packages \
dotnet publish "Project.API.csproj" -c Release -o /app/publish \
--no-restore
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "Project.API.dll"]
Our script in PowerShell:
docker buildx build --secret id=nugetconfig,src=$HOME\AppData\Roaming\NuGet\NuGet.Config -f "Src\Presentation\Project.API\Dockerfile" -t my-dotnet-image .
Output:
#14 [build 6/9] RUN --mount=type=cache,id=nuget,target=/root/.nuget/packages --mount=type=secret,id=nugetconfig dotnet restore "Src/Presentation/Project.API/Project.API.csproj"
--configfile /run/secrets/nugetconfig
#14 1.175 Determining projects to restore...
#14 2.504 /src/Src/Presentation/Project.API/Project.API.csproj : error NU1301: Unable to load the service index for source
https://domain-123456789012.d.codeartifact.us-east-2.amazonaws.com/nuget/repository/v3/index.json.
What are we missing here? Once we have the Dockerfile working we want to use CDK for deploying the Docker image alongside our infrastructure.
We’re using aws codeartifact login command to authenticate with the service. We work on windows with a Linux container

Fail to create DockerFile - copy error, project not found

Fail to create DockerFile (Linux target) which was generated automatically using VS2019 -> add docker support,
my project structure is:
D:\MasterProjects\WebApi\WebApi\WebApi.csproj
D:\MasterProjects\Proj1\Proj1\Proj1.vbproj
D:\MasterProjects\Proj1\Proj2\Proj2.vbproj
In the WebApi project, there is a reference to Proj1
In the Proj1 project, there is a reference to Proj2
I've tried to add also a copy section to the third project (Proj2) without any luck,
tried also to run the docker file from the sln folder (changing the copy path), also no luck
my docker file located in D:\MasterProjects\WebApi\WebApi
I get a copy error on the second project which can't be found
the docker file content is:
WORKDIR /app
EXPOSE 80
EXPOSE 443
FROM mcr.microsoft.com/dotnet/sdk:3.1 AS build
WORKDIR /src
COPY ["WebApi.csproj", "WebApi/"]
COPY ["../Proj1/Proj1/Proj1.vbproj", "../Proj1/Proj1/"]
RUN dotnet restore "WebApi/WebApi.csproj"
COPY . .
WORKDIR "/src/WebApi"
RUN dotnet build "WebApi.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "WebApi.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "WebApi.dll"]````

libhostpolicy.so not found when trying to run a framework dependent build

I am trying to build docker images for my asp.net 3.1 services. When I build self-contained I can use the mcr.microsoft.com/dotnet/core/runtime-deps base image just fine. However to improve build speed I am trying to use the mcr.microsoft.com/dotnet/core/runtime or aspnet as my base image and copy the no-self-contained (framework dependent) publish output (from an earlier stage in docker build).
However when I try to run the container I see A fatal error was encountered. The library 'libhostpolicy.so' required to execute the application was not found in '/usr/share/dotnet'.
I can reproduce this using the webapi sample project and the following Dockerfile
FROM mcr.microsoft.com/dotnet/core/sdk:3.1-bionic as build
WORKDIR /src
COPY . .
RUN dotnet restore --runtime ubuntu.18.04-x64
RUN dotnet build --no-restore -c Release --runtime ubuntu.18.04-x64
RUN dotnet publish --no-restore --no-build -c Release -r ubuntu.18.04-x64 -o publish --self-contained false ./app.csproj
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-bionic
WORKDIR /app
COPY --from=build /src/publish/. /app/
CMD [ "./app" ]
Also I can see the libhostpolicy.so bin does exist in /usr/share/dotnet/shared/Microsoft.NETCore.App/3.1.3/libhostpolicy.so
Can you see what I am doing wrong here?
I am still unsure what the cause of the error was but I can produce a container the same size as the problematic one that works properly by omitting the runtime from the dotnet commands as follows:
FROM mcr.microsoft.com/dotnet/core/sdk:3.1-bionic as build
WORKDIR /src
COPY . .
RUN dotnet restore
RUN dotnet build --no-restore -c Release
RUN dotnet publish --no-restore --no-build -c Release -o publish ./app.csproj
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-bionic
WORKDIR /app
COPY --from=build /src/publish/. /app/
CMD [ "./app" ]
If anyone knows why passing the RID caused a runtime dependency error I would be interested to know but for now I am happy

How to build one docker image for multiple projects?

In my project I am using .net core 2.2 , recently I am using additional class library inside my project.
When I am trying to build my image it can not found my dll.
My docker file looks like:
FROM mcr.microsoft.com/dotnet/core/sdk:2.2 AS build-env
WORKDIR /app
# Copy csproj and restore as distinct layers
COPY *.csproj ./
RUN dotnet restore
COPY . ./
RUN dotnet publish -c Release -o out
# Build runtime image
FROM mcr.microsoft.com/dotnet/core/aspnet:2.2
WORKDIR /app
EXPOSE 80
COPY --from=build-env /app/out .
ENTRYPOINT ["dotnet", "LibvirtManagement.dll"]
I am getting error like this:
The project file "/JenkinsService/JenkinsService.csproj" was not found.
[/app/LibvirtManagement.sln]
The command '/bin/sh -c dotnet publish -c Release -o out' returned a non-zero code: 1
The error message is pretty straightforward, you're missing JenkinsService.csproj and other files from this project in docker container where you build it. You need to copy these files as well.
If you're using Visual Studio the easiest way to do it is to right-click executable project file (LibvirtManagement in your case) and then select Add -> Docker Support.... It will auto-generate correct Dockerfile for you
EDIT: this is what this tool created for me:
#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.
FROM mcr.microsoft.com/dotnet/core/aspnet:2.2-stretch-slim AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
FROM mcr.microsoft.com/dotnet/core/sdk:2.2-stretch AS build
WORKDIR /src
COPY ["LibvirtManagement/LibvirtManagement.csproj", "LibvirtManagement/"]
COPY ["JenkinsService/JenkinsService.csproj", "JenkinsService/"]
RUN dotnet restore "LibvirtManagement/LibvirtManagement.csproj"
COPY . .
WORKDIR "/src/LibvirtManagement"
RUN dotnet build "LibvirtManagement.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "LibvirtManagement.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "LibvirtManagement.dll"]

.net core Failed to run as a self-contained app. on a docker

I have this Dockerfile for .net core
FROM mcr.microsoft.com/dotnet/core/aspnet:3.0-buster-slim AS base
WORKDIR /app
EXPOSE 8080
FROM mcr.microsoft.com/dotnet/core/sdk:3.0-buster AS build
WORKDIR /src
COPY ["./WebApplication1.csproj", "WebApplication1/"]
RUN dotnet restore "WebApplication1/WebApplication1.csproj"
COPY . .
WORKDIR "/src/WebApplication1"
RUN dotnet build "WebApplication1.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "WebApplication1.csproj" -c Release -o /app/publish --self-contained
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "WebApplication1.dll"]
When I run the docker I get the error:
A fatal error was encountered. The library 'libhostpolicy.so' required to execute the application was not found in '/app/'.
I read this, and it is not related to my problem
--self-contained require a -r (--runtime)
-r, --runtime The target runtime to publish for. This is used when creating a self-contained deployment.
The default is to publish a framework-dependent application.
I'd start with changing the publish command in Dockerfile to this:
RUN dotnet publish "WebApplication1.csproj" -c Release -o /app/publish --self-contained --runtime linux-64
New Part:
I run the below command
$ RUN dotnet publish "WebApplication1.csproj" -c Release -o /app/publish --self-contained
and I got below error:
/usr/local/share/dotnet/sdk/3.0.100/Sdks/Microsoft.NET.Sdk/targets/Microsoft.NET.RuntimeIdentifierInference.targets(127,5): error NETSDK1031: It is not supported to build or publish a self-contained application without specifying a RuntimeIdentifier. Please either specify a RuntimeIdentifier or set SelfContained to false. [/Users/ziaullahkhan/Code/SelfContainedApp/SelfContainedApp.csproj]
I changed the command to this:
$ dotnet publish -c Release --self-contained --runtime linux-x64 -o out
and it published everything successfully.
I then built the docker image. Started shell on the container
$ docker run -it khanziaullah/sca bash
root#eb5dc8083aa3:/app/out# ls -l libhostpolicy.so
-rwxr--r-- 1 root root 327384 Sep 13 15:21 libhostpolicy.so
root#eb5dc8083aa3:/app/out# dotnet SelfContainedApp.dll
Hello World!
so I see the libhostpolicy.so file.
Try starting a shell and look for your build and copy location for all the dependencies. COPY command might have gone wrong.
Try to add the following code to the csproj
<PackageReference Include="Microsoft.NETCore.App" Version="1.0.1" />

Categories

Resources