问题
The build context
for Docker is important, since not having the context set to a location in the path "high up" will normally give you the dreaded Forbidden path outside the build context
problem.
This discussion, regarding .NET project with Project References, led me to the conclusion that the Docker tools in Visual Studio places the Dockerfile incorrectly in the project folder, when it seems it needs to be in the folder where the solution file exists. This is so that the build context
is the same folder as the solution file, and thus, the dependencies of the underlying projects are found (the .net core project file DockerfileContext
tag doesn't seem to have any effect).
However, I think it normal that not all references needed are below the sln-folder, but instead are referenced even higher up. This is the case for me, when I use GIT submodules, and those submodules are placed higher up than the folder of the solution. Something like this:
+ MyGitRepo
|
+-- MySolution
| |
| +-- MyProject (ref: MyCoolLibrary)
| |
| +-- MyOtherProject (ref: MyCoolLibrary)
|
+-- Submodules
|
+-- MyCoolLibrary
The MyProject
is something I want as a stand-alone container. Visual Studio fixed with the the built-in tools, but then placed the Dockerfile inside the project folder, and I got the "Forbidden path..." error.
I then placed the Dockerfile in the "MySolution" folder, but of course, that didn't help, since the submodules are a level up.
So I thought, in the docker-compose.yml
I specify context: ../.
and that should work, right? I ended up with a docker-compose file like this, placed in the MySolution
folder:
version: '3.4'
services:
alfacom:
image: ${DOCKER_REGISTRY-}MyProject
build:
context: ../.
dockerfile: MySolution/Dockerfile-MyProject
But, the problem I think I have is that I have a lot of projects in the repo folder, and then I read this:
A context is processed recursively. So, a PATH includes any subdirectories... The build is run by the Docker daemon, not by the CLI. The first thing a build process does is send the entire context (recursively) to the daemon.
This would be madness; sending all that to the daemon is not only huge, but unnecessary, as the "MySolution" does not depend on everything in the MyGitRepo, but only some of the submodules.
What can be done here? I really want to keep the MySolution in that repo, cause the repo contains all solutions and projects for this system, sort of. How should I approach this?
回答1:
The only solution I have found is this:
Do not have file system references (project or dll ref), it is basically not doable (unless all those ref are in subfolders to your solution). The only way is to have NuGet references, it seems.
Switching from project ref to NuGet is a pain, and messes other very important things up, like code browsing and primarily debugging, which unfortunately makes this solution more or less not doable. I am currently looking for a solution to this problem.
回答2:
I actually have a better workaround for this problem, and that is to use the Publish function in Visual Studio, and then create a super-simple Dockerfile inside the publish folder, and create the image from there.
Using NuGet packages, as I write in my first answer above, resolves the immediate problem with Docker build, but, it introduces some serious problems, like code browsing and debugging. Debugging code inside NuGet packages isnt possible, which makes this approach more or less useless.
Instead, I do the following:
Publish the app, using the built-in Visual Studio functionality, this is what I use:
Then, in the output folder, I place the following simple Dockerfile:
FROM mcr.microsoft.com/dotnet/core/runtime:3.1-buster-slim AS base WORKDIR /app COPY . . RUN chmod +x /app CMD ["dotnet", "/app/AlfaPortal.dll"]
And then the command
docker build --tag yourtag:whatever .
will create the image
This image works great on a Linux machine.
来源:https://stackoverflow.com/questions/62684061/docker-build-context-and-working-with-net-projects-and-submodules-in-git-cause