How to generate runtimeconfig.json for dependency with dotnet publish - docker

I'm building a .Net Core 2.1 library. It has a runnable dependency, which I need to start first.
However dotnet publish generates .runtimeconfig.json only for my library and not for my dependency.
Is there a way to force dotnet to generate .runtimeconfig.json for a dependency?
I have tried:
<PropertyGroup>
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
<GenerateDependencyFile>true</GenerateDependencyFile>
</PropertyGroup>
but it did not help.
As a workaround I can copy my app .runtimeconfig.json to the dependency .runtimeconfig.json but it seems hacky. Is there a better option?
I have prepared the test case, if anyone wants to take a crack at it:
git clone https://github.com/eduard93/gerenate-runtimeconfig.json.git
cd gerenate-runtimeconfig.json
docker build --tag mbs .
docker run --name mbs mbs
docker rm mbs --force
If you remove the comment from Line 24 in the Dockerfile with the copy workaround the image would run successfully.
Without workaround I get this error:
A fatal error was encountered. The library 'libhostpolicy.so' required to execute the application was not found in '/app/'.
Failed to run as a self-contained app. If this should be a framework-dependent app, add the /app/IRISGatewayCore21.runtimeconfig.json file specifying the appropriate framework.

Related

"dotnet publish" command within dotnetcoresdk container produces EXE without Details

We are attempting to build a .NET core 3.1 app within a container, using dotnet publish, dotnet build or dotnet msbuild commands, with different parameters. Which succeeds, but the problem is that EXE output never shows any file Details (Copyright, File version, etc. are empty), while DLLs do contain specified information. We've tried several different containers, as well as researching online and trying different command parameters, for versioning (there are a few). Also, running identical dotnet publish command on my Windows 10 machine directly, works as expected, no issues.
I've also attempted separating dotnet build and dotnet publish (--no-build) commands and copying a code signed EXE in-between, in case there is a trust issue, but nothing worked.
Dockerfile content (also used dotnet publish instead of msbuild):
FROM mcr.microsoft.com/dotnet/core/sdk:3.1-alpine3.11
ARG Version="5.6.7"
WORKDIR /build
COPY ./src $WORKDIR
RUN dotnet restore
RUN echo $Version
RUN dotnet msbuild abc.csproj /t:Build /p:PublishSingleFile=True /p:SelfContained=True /p:PublishProtocol=FileSystem /p:Configuration=Release /p:Platform=x64 /p:TargetFrameworks=netcoreapp3.1 /p:PublishDir=publish /p:RuntimeIdentifier=win-x64 /p:PublishReadyToRun=False /p:PublishTrimmed=False /p:VersionNumber=$Version /p:VersionPrefix=$Version /p:Version=$Version /p:AssemblyVersion=$Version /p:AssemblyVersionAttribute=$Version /p:FileVersion=$Version /p:AssemblyFileVersionAttribute=$Version
Steps to reproduce:
Create Dockerfile, similar to above
Run docker build command for a .NET Core console application (replace abc.csproj)
Run docker run command using container ID
Copy publish contents to local file system and review EXE file Details
This issue is described here: https://github.com/dotnet/sdk/issues/4127. From that link:
The PE resources are transferred from App.dll to the host App.exe only
when building on Windows -- because the resource handling code
currently uses native Win32 API. So, when the app is published from
Linux or nanoserver, the resources are not transfered.
That issue was closed, pointing to planned cross-platform work to re-write the way these resources are written (https://github.com/dotnet/runtime/issues/3828). That work has been pushed off to the dotnet 6.0.0 milestone, so unfortunately for now the only way to get the .exe to include these assembly info resources is to run the dotnet publish command directly on a Windows host.
I think there is an issue which is still open, I think you should see what is the differnet in the SDK versions between your Container and Windows and try to use that working version in your container
In this thread I found a solution for myself which also solves the problem discussed here:
https://stackoverflow.com/a/67336316/8041403
TL;DR
the nanoserver image is the problem (which is the base of the standard .NET core images)
use mcr.microsoft.com/dotnet/sdk:5.0-windowsservercore-ltsc2019 as image, which uses servercore

Safe way to include a NuGet private source in a Docker container

I'm setting up a Docker container for my ASP.NET Core server and need to find a safe way for restoring NuGet packages before building and running the project.
I've managed to mount a drive containing a new NuGet.config file solely created for this purpose, as my team doesn't include the config file as a part of the Git repository, but it feels wrong.
As the official Docker image for .NET Core runtime/sdk doesn't include nuget as a part of the library, some have suggesting downloading a windows image just to run nuget source add but that seems terrible as well.
My Dockerfile:
FROM mcr.microsoft.com/dotnet/core/aspnet:2.2 AS base
WORKDIR /app
EXPOSE 5050
FROM mcr.microsoft.com/dotnet/core/sdk:2.2 AS build
WORKDIR /src
COPY . .
#Config file needs to be in root of solution or in User/share
RUN dotnet restore "MyProject.csproj"
Adding a private NuGet source should be achievable without downloading a 2GB windows image or copying an existing config file that includes the password.
Have a nuget.config file that lists only the package sources, not credentials, that's commit in your repo with your source code.
Use cross platform authentication providers to allow devs and CI machines to authenticate to your private feeds.
set the nuget's source path is not good enough?
RUN dotnet restore -s https://api.nuget.org/v3/index.json -s https://my-local-private-nuget-source/nuget/nuget

Could not find 'xxx.Program' specified for Main method when building dotnet app in Docker container

I am having issues when building a dotnet core application inside a docker container. I am using dotnet core 2.2.
The setting for the project are:
Output: Console App
Startup Project: Web.Project
When running the command below inside the container:
RUN dotnet build "Web.csproj" -c Release -o /app
I get the error below:
Could not find 'Web.Program' specified for Main method [/src/Web/Web.csproj]
If the project is just an assembly (dll) everything works fine but I'm unable to run the web app.
Any ideas?
The solution to my problem was to remove the following line from my csproj file:
<OutputType>EXE</OutputType>
It seems like visual studio 2107 adds that tag when changing the output type. Once I removed that, I was able to build and publish inside a Docker Container and Windows.
In my case that was folder with repository /home/ubuntu/project was the same folder as i targeted to build dotnet build -C Release --runtime ubuntu.18.04-x64 --output /home/ubuntu/project`.
Solution was to change it dotnet build -C Release --runtime ubuntu.18.04-x64 --output /home/ubuntu/project_build`
Using my case, since I changed the name of the namespace and solution.
I edited the .csproj
at every tag where I found the old name, I replaced it with the new one,
Cleaned build, build and the error went away

How to create a docker container using a project solution where lib projects are located one level higher than the building context

I have a VS2017 (v5.18.0) solution which contains a .NET Core 2.0 console application "ReferenceGenerator" as the "startup" application. The solution contains also two .Net Core lib 2.0 projects FwCore and LibReferenceGenerator, which are "homegrown" libs. I have added docker support (Linux) and so all files needed to create a docker application are added. I can debug the application in the "docker-compose" mode with "docker for windows in Linux mode". And the application works fine. If I try to build a release version I get an error that a COPY occurs from an illegal path. The docker file looks like this:
FROM microsoft/dotnet:2.0-runtime AS base
WORKDIR /app
FROM microsoft/dotnet:2.0-sdk AS build
WORKDIR /src
COPY ReferenceGenerator/ReferenceGenerator.csproj
ReferenceGenerator/
COPY ../LibReferenceGenerator/LibReferenceGenerator.csproj ../LibReferenceGenerator/
COPY ../FwCore/FwCore/FwCore.csproj ../FwCore/FwCore/
RUN dotnet restore
ReferenceGenerator/ReferenceGenerator.csproj
COPY . .
WORKDIR /src/ReferenceGenerator
RUN dotnet build ReferenceGenerator.csproj -c Release -o /app
FROM build AS publish
RUN dotnet publish ReferenceGenerator.csproj -c Release -o /app
FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "ReferenceGenerator.dll"]
The line with beneath content:
COPY ../LibReferenceGenerator/LibReferenceGenerator.csproj ../LibReferenceGenerator/
Is causing error:
Step 6/17 : COPY ../LibReferenceGenerator/LibReferenceGenerator.csproj ../LibReferenceGenerator/
1>Service 'referencegenerator' failed to build: COPY failed: Forbidden path outside the build context: ../LibReferenceGenerator/LibReferenceGenerator.csproj ()
I have read that relative paths are not allowed, so be it. But the output of the compiler is already complete in the bin directory of the project ReferenceGenerator. I already tried to remove the two copy lines referencing the libs but then the build complains about the missing lib project files at the dotnet build stage.
Having some "homebuild" lib projects being included in an solution seems to me a very common situation. I am a newbee on docker containers and I have no idea how to fix this, anyone?
Additional info my file structure looks like this:
/Production/ReferenceGenerator/ReferenceGenerator.sln
/Production/ReferenceGenerator/ReferenceGenerator/ReferenceGenerator.csproj
/Production/LibReferenceGenerator/LibReferenceGenerator.csproj
/Production/FwCore/FwCore/FwCore.csproj
/Production/ReferenceGenerator/ReferenceGenerator/Dockerfile
Please anyone. The people that tried to help me have not succeeded in doing so. I'm completely stuck in development....
The answer is, there is no solution...
If you need libraries you must include them by using (private) nuget libraries.
It is not a neat solution because while debugging you do not have the sources of your libraries available but including libs outside the build context is a no go I learned researching the internet...
Also in a micro-service environment sharing code should be minized to avoid teams breaking code of other teams. Sorry for all developers who liked to have a solution for this problem, again beside a workaround using nuget packages there is none!
As the error says, you can't copy files that exist outside of the build context. When you run a command like docker image build ., that last argument (.) specifies the build context. That context is copied to the Docker engine for building. Files outside of that (e.g., ../LibReferenceGenerator/LibReferenceGenerator.csproj) simply don't exist.
So, for your example to work, you need to adjust your build context up one level in order to access LibReferenceGenerator and FwCore. Then, make the source of your COPY instructions relative to that one-level up context.
Note that the default location of the Dockerfile is a file named Dockerfile at your build context. You'll need to either move your Dockerfile, or specify a custom path using the -f, --file option.
docker image build documentation
You are missing one level in the copy.
It should be:
COPY ../../LibReferenceGenerator/LibReferenceGenerator.csproj ../LibReferenceGenerator/

How to ask sbt to only fetch dependencies, without compiling?

Is there a way to only download the dependencies but do not compile source.
I am asking because I am trying to build a Docker build environment for my bigger project.
The Idear is that during docker build I clone the project, download all dependencies and then delete the code.
Then use docker run -v to mount the frequently changing code into the docker container and start compiling the project.
Currently I just compile the code during build and then compile it again on run. The problem ist that when a dependencie changes I have to build from scratch and that takes a long time.
Run sbt's update command. Dependencies will be resolved and retrieved.

Resources