我可以在没有副本的情况下从 docker 构建上下文运行脚本吗?

时间:2021-06-25 16:41:46

标签: docker dockerfile docker-container windows-container

我想通过安装几个程序在 windows docker 容器之上构建。文件总大小为 0.5 GB,我希望层数尽可能小。我希望我可以从构建上下文运行安装文件,然后在最后清除构建上下文,这样我就不会在我的容器层中嵌入 setup.exe 的源文件的不必要副本.但是,我还没有找到这样的例子。相反,我主要看到人们对临时构建文件夹运行 COPY 命令,运行他们的设置,然后删除该文件夹。那些文件不会仍然在容器层中,因为 COPY 命令在完成后会创建一个新层吗?

不知道容器能不能直接看到build-context。我希望有一些充满构建上下文文件的神奇文件夹,以便我可以使用它运行脚本,但没有找到任何东西。

似乎另一种方法是创建一个私有文件服务器并执行 RUN 可以从该私有服务器下载它们并解压缩它们,运行安装并删除它们(全部作为 1 个 docker 步骤) .我知道这将使需要重新运行构建的其他人更容易使用它,但我不相信我们需要重新运行它。它不太可能改变,因为容器将为遗留应用程序构建补丁。在面向公众的私有服务器上托管文件似乎有很多事情要做,如果有的话,每隔几年就会被调用一次。

这是我的两个选择吗?

  1. 制作一个容器,其中嵌入了不需要的源文件副本
  2. 在私人文件服务器上托管文件并下载/安装/删除它们

或者我是否错过了关于容器如何工作的另一个选项或要点?

3 个答案:

答案 0 :(得分:0)

我通常在一个步骤中进行下载或复制,然后在下一步中进行静默安装并删除安装程序。

# escape=`
FROM mcr.microsoft.com/dotnet/framework/wcf:4.8-windowsservercore-ltsc2016
SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"]
ADD https://download.visualstudio.microsoft.com/download/pr/6afa582f-fa26-4a73-8cb9-194321e85f8d/ecea51ead62beb7acc73ad9799511ffdb3083ad384fe04ec50e2cbecfb426482/VS_RemoteTools.exe VS_RemoteTools_x64.exe
RUN Start-Process .\\VS_RemoteTools_x64.exe -ArgumentList @('/install','/quiet','/norestart') -NoNewWindow -Wait; `
  Remove-Item -Path C:/VS_RemoteTools_x64.exe -Force;

否则,我认为您无法在构建自定义卷时安装它。

答案 1 :(得分:0)

这是一个很长的镜头,因为 Windows 在文件系统方面是一个棘手的事情,但你可以这样做:

  • 在您的 Dockerfile 中使用 COPY 命令,然后安装 RUN del ... 以删除安装文件
  • 打造您的形象docker build -t my-large-image:latest .
  • 运行您的映像 docker run --name my-large-container my-large-image:latest
  • 停止容器
  • 导出您的容器文件系统docker export my-large-container > my-large-container.tar
  • 将文件系统导入新映像 cat my-large-container.tar | docker import - my-small-image

警告是您需要运行一次容器,这可能不是您想要的。而且我还没有用 Windows 容器测试过,抱歉。

答案 2 :(得分:0)

我没有找到满意的答案。 Docker 似乎只是为现代时代设计的,并假设您将能够通过脚本和工具访问 API 和文件服务器来下载您需要的内容。我发现我最终采用的最简单的选择是将文件托管在私有文件服务器或服务(在我的例子中是 AWS S3)上。

我真的希望有一种方法可以让 docker 守护进程以某种方式托管文件,例如。如果它充当临时服务器,您可以通过 http 从中获取数据,而不需要 COPY 文件并创建一个层。唉,我没有发现这样的功能。

走这条路线使我的容器小了大约 1 GB。