Docker 正在推动所有层而不是最后一层

Docker is pushing all layers instead of the last one

昨天我为我的应用推送了基础镜像层,其中包含 运行 my_app.

所需的环境

那个推送是巨大的,但它已经完成并在我的回购中。

目前我本地机器的镜像情况是这样的:

➜  docker images                          
REPOSITORY               TAG                 IMAGE ID       CREATED          SIZE
dr_prof_patrick/my_app   my_app_v0           7e4cb75b4735   22 minutes ago   5.36GB
dr_prof_patrick/my_app   my_app_base_image   b1cccd87e4f7   37 hours ago     5.35GB
python                   3.8                 67ec76d9f73b   8 days ago       909MB
python                   3                   f48ea80eae5a   8 days ago       917MB

我对图像进行了一些小改动,您可以在此处看到:

➜  docker history dr_prof_patrick/my_app:my_app_v0
IMAGE          CREATED          CREATED BY                                      SIZE      COMMENT
7e4cb75b4735   22 minutes ago   /bin/sh -c #(nop)  CMD ["python3" "main.py"]    0B        
55fe27affa9a   22 minutes ago   /bin/sh -c pip install -r requirements.txt      16.1kB    
3eba19411e42   22 minutes ago   /bin/sh -c #(nop) WORKDIR /my_app            0B        
54249235bcba   22 minutes ago   /bin/sh -c #(nop) COPY dir:7f9da91b4e3f9ed60…   6.03MB    
b1cccd87e4f7   37 hours ago     /bin/sh -c pip install -r requirements.txt      4.04GB    
<missing>      37 hours ago     /bin/sh -c #(nop) COPY file:8e879a6a889ff22f…   305B      
<missing>      37 hours ago     /bin/sh -c apt-get install ffmpeg libsm6 lib…   385MB     
<missing>      37 hours ago     /bin/sh -c apt-get update                       17.7MB    
<missing>      8 days ago       /bin/sh -c #(nop)  CMD ["python3"]              0B        
<missing>      8 days ago       /bin/sh -c set -ex;   wget -O get-pip.py "$P…   8.31MB    
<missing>      8 days ago       /bin/sh -c #(nop)  ENV PYTHON_GET_PIP_SHA256…   0B        

它尝试再次推送基础层,这需要大约 2 个小时。

➜  docker push dr_prof_patrick/my_app:my_app_v0    
The push refers to repository [docker.io/dr_prof_patrick/my_app]
548f7bc62c43: Layer already exists 
fa5433c54740: Layer already exists 
f09b381b1d57: Pushing  1.102MB/4.041GB
a0f39ee33d3d: Layer already exists 
a1e799af3370: Pushing  8.842MB/384.5MB
c93f6a714096: Pushing   1.77MB/17.7MB
e9df9d3bdd45: Layer already exists 
1271cc224a6b: Layer already exists 
740ef99eafe1: Pushing   5.42MB/48.56MB
b7b662b31e70: Pushing  6.628MB/18.47MB
6f5234c0aacd: Waiting 
8a5844586fdb: Waiting 
a4aba4e59b40: Waiting 
5499f2905579: Waiting 
a36ba9e322f7: Waiting 

我不知道我的工作流程如何阻止 docker 仅上传最新更改 - 任何帮助将不胜感激。

编辑

认为用于创建 my_app_v0 的 docker 文件可以提供帮助:

FROM dr_prof_patrick/my_app:my_app_base_image

COPY . /my_app

WORKDIR /my_app

RUN pip install -r requirements.txt

CMD ["python3", "main.py"]

docker push 将图像的所有层 (5 at the time by default) 推送到存储库中不等于图像的所有层(也称为未更改的层),而不是单个层最终在您的存储库中生成一个新图像。

你可以看到它好像 Docker 在本地和远程图像之间做了一个差异,并且只推送了这两者之间的差异,这最终将成为一个新图像 - 等于你拥有的图像在您的机器中,但“更少的工作”就可以达到预期的结果,因为它不需要按字面意思推动所有层。

在你的情况下,自从 4 Gb 层发生变化(因为你现在复制的内容不同)后,它花费了很多时间,使得 Docker 将你的图像大小推到很大一部分.

Link 对于 docker push 文档,如果需要:https://docs.docker.com/engine/reference/commandline/push/

一旦上下文发生变化,

Docker 会使 COPY 层失效——无论接下来的步骤实际依赖什么。在最后可能的时刻复制文件——在您的情况下,先复制 requirements.txt,然后再复制其余的。像这样:

FROM dr_prof_patrick/my_app:my_app_base_image

WORKDIR /my_app

COPY requirements.txt .

RUN pip install -r requirements.txt

COPY . .

CMD ["python3", "main.py"]

也看看你的.dockerignore,不要复制无用的文件。我看到的最佳策略是使用 .dockerignore 作为白名单,而不是黑名单,首先忽略所有内容,然后取消忽略您需要的文件:

*
!requirements.txt