有没有更优雅的方法可以使用Docker COPY将特定文件复制到工作目录?

stu*_*ike 7 docker .net-core dockerfile

尝试使用microsoft / dotnet:2.1-aspnetcore-runtime创建一个容器。.net核心解决方案文件在解决方案下嵌套了多个项目,每个项目都有自己的.csproj文件。我正在尝试为子项目创建更优雅的COPY指令

此处提供的示例https://github.com/dotnet/dotnet-docker/tree/master/samples/aspnetapp具有仅包含一个.csproj的解决方案文件,因此可以创建Dockerfile:

COPY *.sln .
COPY aspnetapp/*.csproj ./aspnetapp/
RUN dotnet restore
Run Code Online (Sandbox Code Playgroud)

它是这样工作的

COPY my_solution_folder/*.sln .
COPY my_solution_folder/project/*.csproj my_solution_folder/
COPY my_solution_folder/subproject_one/*.csproj subproject_one/
COPY my_solution_folder/subproject_two/*.csproj subproject_two/
COPY my_solution_folder/subproject_three/*.csproj subproject_three/
Run Code Online (Sandbox Code Playgroud)

用于以下解决方案的文件夹结构:

my_solution_folder\my_solution.sln
my_solution_folder\project\my_solution.csproj
my_solution_folder\subproject_one\subproject_one.csproj
my_solution_folder\subproject_two\subproject_two.csproj
my_solution_folder\subproject_three\subproject_three.csproj
Run Code Online (Sandbox Code Playgroud)

但这不是(随机猜测)

COPY my_solution_folder/*/*.csproj working_dir_folder/*/
Run Code Online (Sandbox Code Playgroud)

有没有更优雅的解决方案?

Von*_*onC 7

考虑到COPY不能很好地支持通配符(moby问题15858),您可以:

  • 您可以尝试在不想复制的文件夹中添加.dockerignore文件(同时排除您想要的文件夹):这很麻烦
  • 或者,如下所示,对所需的所有文件夹进行压缩

这是一个示例,适合您的情况:

find .. -name '*.csproj' -o -name 'Finomial.InternalServicesCore.sln' -o -name 'nuget.config' \
  | sort | tar cf dotnet-restore.tar -T - 2> /dev/null
Run Code Online (Sandbox Code Playgroud)

使用Dockerfile包括:

ADD docker/dotnet-restore.tar ./
Run Code Online (Sandbox Code Playgroud)

这个想法是:归档文件将通过自动扩展ADD


OPsturmstrike提到的意见优化ASP.NET核心应用程式在泊坞窗-避免手动拷贝csproj文件(第二部分) ”由安德鲁锁“袜子”

替代解决方案实际上使用了我先前不使用的通配符技术,但是对您的项目结构有一些假设,采用了两阶段方法,并且进行了一些巧妙的bash工作来解决通配符的局限性。

我们将平面显示csproj文件,然后将它们移回到嵌套在src子文件夹中的正确位置。

# Copy the main source project files
COPY src/*/*.csproj ./  
RUN for file in $(ls *.csproj); do mkdir -p src/${file%.*}/ && mv $file src/${file%.*}/; done
Run Code Online (Sandbox Code Playgroud)

L01nl 在评论中建议 一种不需要压缩的替代方法:“ 在Docker中优化ASP.NET Core应用-避免手动复制csproj文件 ”,来自Andrew Lock“ Sock”

FROM microsoft/aspnetcore-build:2.0.6-2.1.101 AS builder
WORKDIR /sln

COPY ./*.sln ./NuGet.config  ./

# Copy the main source project files
COPY src/*/*.csproj ./
RUN for file in $(ls *.csproj); do mkdir -p src/${file%.*}/ && mv $file src/${file%.*}/; done

# Copy the test project files
COPY test/*/*.csproj ./
RUN for file in $(ls *.csproj); do mkdir -p test/${file%.*}/ && mv $file test/${file%.*}/; done

RUN dotnet restore

# Remainder of build process
Run Code Online (Sandbox Code Playgroud)

该解决方案比我以前基于tar的工作要干净得多,因为它不需要任何外部脚本,只需标准的docker COPYRUN命令。
通过首先csprojsrc目录中的各个文件之间进行复制,然后将它们移至正确的位置,然后在测试项目文件之间进行复制,可以解决通配符问题。

  • 添加不需要压缩的替代方法 [此处](https://andrewlock.net/optimising-asp-net-core-apps-in-docker-avoiding-manually-copying-csproj-files-part- 2/) 作者:安德鲁·洛克 (2认同)
  • 不幸的是,使用 BuildKit 时替代解决方案似乎不起作用:( (它没有找到任何 csproj 文件) (2认同)