如何避免Dockerfile中的大型二进制文件caching失效(Python_Onbuild)

我正在我的dockfile中下载1.6 GB二进制压缩文件,然后使用gunzip将其解压缩,从而导致存储3.6 GB文件。 我不想让它一直重复,因为它需要很长的时间。 它是一个静态文件,所以不应该每次使用Jenkins / docker将更改部署到服务器时下载。 但是,每次下载,我都会进行更改,然后运行Jenkins来部署它们。

这是我的docker文件:

FROM python:2.7.13-onbuild RUN mkdir -p /usr/src/app WORKDIR /usr/src/app ARG DEBIAN_FRONTEND=noninteractive RUN apt-get update && apt-get install --assume-yes apt-utils RUN apt-get update && apt-get install -y curl RUN apt-get update && apt-get install -y unzip RUN curl -o - https://s3.amazonaws.com/dl4j-distribution/GoogleNews-vectors-negative300.bin.gz \ | gunzip > /usr/src/app/GoogleNews-vectors-negative300.bin 

更新:我改变了dockfile为一个简单的如下所示:

 FROM python:2.7.13-onbuild RUN mkdir -p /usr/src/app WORKDIR /usr/src/app RUN echo "Test Cache" CMD /usr/local/bin/gunicorn -t 240 -k gevent -w 1 -b 0.0.0.0:8000 --reload src.wsgi:app 

现在,如果我不改变代码或任何其他文件,这工作正常,所以命令回声"test cache"不重复。 但是,只要我对源文件夹中的任何文件进行了任何更改,就会重复执行以下步骤后的所有命令,我认为它们将复制源代码为docker目录。 这个阶段不应该发生,因为这意味着一旦我做出任何提交,我的所有命令都会重复。

这里是输出,当我没有做任何改变的代码,并再次运行构build:

 Sending build context to Docker daemon 239.1kB Step 1/6 : FROM python:2.7.13-onbuild # Executing 3 build triggers... Step 1/1 : COPY requirements.txt /usr/src/app/ ---> Using cache Step 1/1 : RUN pip install --no-cache-dir -r requirements.txt ---> Using cache Step 1/1 : COPY . /usr/src/app ---> Using cache ---> 1911c6dc9fce Step 2/6 : RUN mkdir -p /usr/src/app ---> Using cache ---> 4019b029d05c Step 3/6 : WORKDIR /usr/src/app ---> Using cache ---> 1a99833e908c Step 4/6 : RUN echo "Test Cache" ---> Using cache ---> 488a62aa1b09 

以下是对一个源文件进行单一更改的输出,您可以看到echo“test cache”重复出现。

 Sending build context to Docker daemon 239.1kB Step 1/6 : FROM python:2.7.13-onbuild # Executing 3 build triggers... Step 1/1 : COPY requirements.txt /usr/src/app/ ---> Using cache Step 1/1 : RUN pip install --no-cache-dir -r requirements.txt ---> Using cache Step 1/1 : COPY . /usr/src/app ---> 6fd1003e246a Removing intermediate container f25a4d2910cf Step 2/6 : RUN mkdir -p /usr/src/app ---> Running in ff324f381875 ---> 3694086a2b6a Removing intermediate container ff324f381875 Step 3/6 : WORKDIR /usr/src/app ---> 5f23ab9a15df Removing intermediate container 0b0d796f97d0 Step 4/6 : RUN echo "Test Cache" ---> Running in 296d2f141015 Test Cache ---> f90c7708d9eb 

我所有的命令都在重复,因为我使用python:2.7.13-onbuild作为基础镜像。 它的docker文件看起来像这样:

 FROM python:2.7 RUN mkdir -p /usr/src/app WORKDIR /usr/src/app ONBUILD COPY requirements.txt /usr/src/app/ ONBUILD RUN pip install --no-cache-dir -r requirements.txt ONBUILD COPY . /usr/src/app 

正如我使用这个作为基础的形象,复制命令执行之前,我的泊坞窗文件中的所有命令和这个复制命令改变上下文每次我做任何改变的源代码。

我被build议直接使用Python:2.7作为基本的图像,所以我有更多的控制这个复制操作。 我的新docker文件如下,最后复制命令解决了问题。

 FROM python:2.7 RUN mkdir -p /usr/src/app WORKDIR /usr/src/app ARG DEBIAN_FRONTEND=noninteractive RUN apt-get update && apt-get install --assume-yes apt-utils RUN apt-get update && apt-get install -y curl RUN apt-get update && apt-get install -y unzip RUN curl -o - https://s3.amazonaws.com/dl4j-distribution/GoogleNews-vectors-negative300.bin.gz \ | gunzip > /usr/src/app/GoogleNews-vectors-negative300.bin COPY requirements.txt /usr/src/app/ RUN pip install --no-cache-dir -r requirements.txt COPY . /usr/src/app 

根据这个文档 ,通常不鼓励使用Python_onbuild图像。

这个解释受到了另一个问题在同一问题上的答案的启发: 在dockerfiles中将哪个Pythonvariables用作基础映像?

问题来自于上下文文件的元数据在每个构build中发生更改,因为您正在Jenkinspipe道中运行该元数据。 因此,docker build命令不能使用它的caching。

你可以尝试做的是把这个大文件放在Jenkins机器上,然后在Dockerfile中引用本地文件。 这样您就不必在每次构build时重新下载它。

使用RUN apt-get update && apt-get install -y确保您的Dockerfile安装最新的软件包版本,而无需进一步的编码或手动干预。 这种技术被称为“caching破坏”。 您也可以通过指定软件包版本来实现caching清除。

您的安装说明按照“dockerfiles的最佳实践”中的说明来清除caching 。 任何不是高速caching的指令都将导致所有其他指令再次执行。

确保你的指令不会失效,除非有必要,并把所有不会使caching无效的指令尽可能地放在你的dockerfile中。 在你的情况下把curl更高的docker文件,你应该没问题。

希望有所帮助。

—-更新

既然你更新了这个问题,我会更新我的答案。

  • caching未命中后的每个操作都将在构build期间执行。 将导致caching未命中的操作尽可能放在dockerfile中。
  • 复制文件到你的容器将导致caching未命中,如果他们改变

WORKDIR /usr/src/app操作是导致该问题的原因,因为它复制了该文件夹中的所有文件。 尽可能低地移动该操作,并重复其他操作导致问题。