为docker图像构建上下文非常大

Cry*_*tal 104 docker

我在我的主机上创建了几个不同的目录,因为我试图了解Docker只是为了保持我的dockerfiles有条理.我刚刚运行的我的Dockerfile看起来像这样:

FROM crystal/centos
MAINTAINER crystal

ADD ./rpms/test.rpm ./rpms/ 
RUN yum -y --nogpgcheck localinstall /rpms/test.rpm 
Run Code Online (Sandbox Code Playgroud)

我的实际转速仅为1 GB.但是当我尝试这样做时sudo docker build -t="crystal/test" .,我会将构建上下文发送到Docker守护程序3.5 GB.当你继续构建Docker镜像时,还有其他我不知道的东西吗?当我在主机上的其他目录中构建更多图像时,我的内存是否在累积?

Tho*_*zco 196

Docker客户端将整个"构建上下文"发送到Docker守护程序.该构建上下文(默认情况下)是整个目录Dockerfile(因此,整个rpms树).

您可以设置.dockerignore文件以使Docker忽略某些文件.您可能想要试验它.

或者,您可以将rpms文件夹的一个目录级别移动到您的目录级别上Dockerfile,并将唯一的符号链接移动test.rpmDockerfile目录中.

  • `.dockerignore`对我很有用!10倍 (5认同)
  • 不要忘记将.git文件夹添加到.dockerignore文件中(假设您使用的是git) (5认同)
  • 是的,默认包含`.git`文件夹 - 这肯定让我感到震惊. (5认同)
  • “构建上下文”到底是什么?我尝试使用 docker build RUN 命令查找这些文件,但我没有在 docker 文件系统内的 Dockerfile 文件夹中看到这些文件(在构建期间)。有人能给我一个简单的示例吗?构建上下文有何用处? (4认同)
  • 不幸的是,在这种情况下似乎无法进行符号链接,因为`ADD`命令在构建期间不遵循sym链接.请参阅:https://github.com/docker/docker/issues/1676 (3认同)
  • 救命!Rails开发人员:确保将`tmp` log添加到`.dockerignore` +其他自定义目录中 (3认同)

And*_*kyy 26

更新2019

从Docker v18.06开始,可以使用名为Build Kit的新映像生成器。

它与Docker预先捆绑在一起,无需安装任何东西。它与Dockerfile语法向后兼容,无需更改Dockerfile

旧版Docker Build与新Docker BuildKit

这是一个在生成目录中使用大量未使用的文件生成映像的示例:

旧版Docker构建:

$ time docker image build --no-cache .
Sending build context to Docker daemon  4.315GB
[...]
Successfully built c9ec5d33e12e

real    0m51.035s
user    0m7.189s
sys 0m10.712s
Run Code Online (Sandbox Code Playgroud)

新的Docker BuildKit:

$ time DOCKER_BUILDKIT=1 docker image build --no-cache .
[+] Building 0.1s (5/5) FINISHED                                                
 => [internal] load build definition from Dockerfile                       0.0s
 => => transferring dockerfile: 37B                                        0.0s
 => [internal] load .dockerignore                                          0.0s
 => => transferring context: 2B                                            0.0s
[...]
 => => writing image sha256:ba5bca3a525ac97573b2e1d3cb936ad50cf8129eedfa9  0.0s

real    0m0.166s
user    0m0.034s
sys 0m0.026s
Run Code Online (Sandbox Code Playgroud)

唯一的变化是DOCKER_BUILDKIT=1环境变量,时间差异巨大。

.dockerignore 文件

请注意,该.dockerignore文件仍然有效。一些Dockerfile类似的命令COPY . .仍会考虑.dockerignore规则。但是DockerfileBuildKit不再将构建目录中的辅助文件(未在中引用)复制为“构建上下文”。

  • 需要注意的是,Windows 容器目前不支持 DOCKER_BUILDKIT。(仅限 Linux,在限制下列出:https://docs.docker.com/develop/develop-images/build_enhancements/) (2认同)
  • 这似乎不诚实;buildkit 仍然首先发送构建上下文。通过打开该选项,构建上下文到底是如何从 4.3GB 变为 ??B 和 0 的?因为那不是我的经验;我传输了相同的上下文大小: ```=> [internal] load build context => => moving context: 924.39MB 86.3s``` 你只需 `[...]` 应该显示 4.3 GB 的行至少在第一次运行时。当然,第二次它不会重新传输上下文,而这正是我们所需要的。 (2认同)
  • @dlamblin 请参阅答案的“.dockerignore”部分:BuildKit 不再复制构建目录中的辅助文件(Dockerfile 中未引用)。通常情况就是这样,但您的体验可能会有所不同;) (2认同)

sam*_*ric 20

解决由不充分的.dockerignore排除引起的大型上下文问题的一个选项是使用以下命令:

rg -uuu --ignore-file .dockerignore --files --sort path .

其中使用了这个工具: https: //github.com/BurntSushi/ripgrep

效果非常好。

  • 谢谢你。我基于您的答案,添加了每个文件的大小并按降序排序: `rg -uuu --ignore-file .dockerignore --files --sort path 。| xargs ls -lh | xargs ls -lh | awk '{print $5,$9}' | 排序-hrk 1 | 头-n 20` (7认同)

Ema*_*mad 14

我通过将我的Dockerfile和docker-compose.yml移动到子文件夹来修复它,它运行得很好.显然,docker将当前文件夹发送到守护进程,我的文件夹是9演出.

  • 此方法提供了禁止的路径:如果正在复制父目录中的文件,则在构建上下文错误之外,对此有什么解决方案? (3认同)

Fre*_*ler 5

在我的情况下,当我使用错误的-f参数执行时- 没有 Dockerfile 所在目录的路径

docker build --no-cache -t nginx5 -f /home/DF/Dockerfile /home/DF/ - 对

docker build --no-cache -t nginx5 -f /home/DF/Dockerfile - 错误的


Luí*_*hin 5

如果您有.dockerignore文件并且构建上下文仍然很大,则可以使用The Silver Searcher检查正在发送到docker构建上下文的内容

ag --path-to-ignore .dockerignore --files-with-matches
Run Code Online (Sandbox Code Playgroud)

请注意,某些**模式可能无法正常工作。

有关其他评论,请参见此Github问题:https : //github.com/moby/moby/issues/16056


Ber*_*poh 5

对于,在根项目目录中NodeJS Application添加一个文件,并在该文件中添加以下内容.dockerignore.dockerignore

node_modules
dist
Run Code Online (Sandbox Code Playgroud)