如何将项目添加到.dockerignore?

时间:2014-08-25 17:08:53

标签: puppet docker

我无法找到.dockerignore文件应该是什么样子的许多示例。

使用puppet在docker容器上安装一些软件包会导致映像从600MB扩展到3GB。我尝试使用.dockerignore文件将大小保持为最小值

$ cat Dockerfile  
FROM centos:centos6

#Work around selinux problem on cent images
RUN yum install -y --enablerepo=centosplus libselinux-devel

RUN yum install -y wget git tar openssh-server; yum -y clean all

Add Puppetfile / 
RUN librarian-puppet install
RUN puppet apply --modulepath=/modules -e "class { 'buildslave': jenkins_slave => true,}"
RUN librarian-puppet clean

如果我运行docker images --tree我可以看到图像瞬间增长几GB

$ docker images --tree
                ├─e289570b5555 Virtual Size: 387.7 MB
                │ └─a7646acf90d0 Virtual Size: 442.5 MB
                │   └─d7bc6e1fbe43 Virtual Size: 442.5 MB
                │     └─772e6b204e3b Virtual Size: 627.5 MB
                │       └─599a7b5226f4 Virtual Size: 627.5 MB
                │         └─9fbffccda8bd Virtual Size: 2.943 GB
                │           └─ee46af013f6b Virtual Size: 2.943 GB
                │             └─3e4fe065fd07 Virtual Size: 2.943 GB
                │               └─de9ec3eba39e Virtual Size: 2.943 GB
                │                 └─31cba2716a12 Virtual Size: 2.943 GB
                │                   └─52cbc742d3c4 Virtual Size: 2.943 GB
                │                     └─9a857380258c Virtual Size: 2.943 GB
                │                       └─c6d87a343807 Virtual Size: 2.964 GB
                │                         └─f664124e0080 Virtual Size: 2.964 GB
                │                           └─e6cc212038b9 Virtual Size: 2.964 GB Tags: foo/jenkins-centos6-buildslave:latest

我认为图像变得如此之大的原因是因为librarian-puppet将一个木偶模块克隆到/modules,这会破坏构建缓存

我已经尝试了以下.dockerignore文件而没有运气。

$ cat .dockerignore
/modules
/modules/
/modules/*

这是.dockerignore文件的正确语法吗? 有没有其他方法可以防止这些容器变得如此之大?

其他信息:

http://kartar.net/2013/12/building-puppet-apps-inside-docker/
http://danielmartins.ninja/posts/a-week-of-docker.html

8 个答案:

答案 0 :(得分:28)

.dockerignore是为了防止在执行docker build时将文件添加到发送到docker守护程序的初始构建上下文中,它不会创建排除文件的全局规则在Dockerfile生成的所有图像中。

重要的是要注意每个RUN语句将生成一个新图像,该图像的父图像是由其上方的Dockerfile语句生成的图像。尝试将RUN语句折叠为单个语句以缩小图像大小:

RUN librarian-puppet install &&\
 puppet apply --modulepath=/modules -e "class { 'buildslave': jenkins_slave => true,}" &&\
 librarian-puppet clean

答案 1 :(得分:19)

.dockerignore的格式应该等于.gitignore的格式。查看sample file和泊坞窗documentation

该文件应该是由换行符分隔的排除模式列表(相对于.dockerignore文件的路径)。

所以你应该尝试以下.dockerignore

modules/*

开头的/可能是错误的,因为它只对文件的根目录有效(但不适用于子目录,所以可能没有/的递归版本做得更好)。

答案 2 :(得分:8)

既不:

@ECHO Off
SETLOCAL enabledelayedexpansion
SET "sourcedir=U:\sourcedir"
SET "destdir=U:\destdir"
FOR /f "delims=" %%a IN (
 'dir /b /a-d "%sourcedir%\????-*-????-??-*.txt" '
 ) DO (
 SET "filename=%%a"
 CALL :newname !filename:-= !

 IF DEFINED newdir (
  ECHO MD "!newdir!" 2>NUL
  ECHO MOVE "%sourcedir%\%%a" "%destdir%\!newdir!\"
 )
)

GOTO :EOF

:newname
IF "%5" neq "" shift&GOTO newname
SET "newdir=%1-%2"
IF "%newdir:~4,1%" equ "-" IF "%newdir:~7%" equ "" IF "%newdir:~6,1%" neq "" GOTO :EOF
SET "newdir="
GOTO :eof

,也不

modules/*

对我不起作用,docker一直用不必要的文件污染图像,直到我这样设置:

modules

也适用于:

**/modules

答案 3 :(得分:3)

一种不同的方式,创建一个较小的图像,是run librarian-puppet in the host,而不是Docker,所以你不要以图书馆员,红宝石,宝石,...安装在图像中。

我以jenkins slave using Puppet的622MB图片和image without Puppet的480MB图片结束。

答案 4 :(得分:2)

http://docs.docker.com/articles/dockerfile_best-practices/

在我看来,你的方法是倒退的(同意@csanchez),你应该从木偶生成你的docker容器,而不是在容器中运行puppet ......

此外,您应该&&安装/应用/清除线路...每个docker命令创建一个增量映像...如果有临时/资源文件属于centos {{1} }命令,你也应该这样做。

yum

真的建议在容器中避免使用SELINUX,它不会在容器内提供任何。更不用说,根据你想要创造的东西,比起centos6有更小的起点。我相信ubuntu较小,debian:喘不过小,甚至是高山的小起点。

值得注意的是,如果您使用支持虚拟挂载的文件系统,您的文件大小可以为多个实例重复使用相同的基本映像,因此它不会增长更多

答案 5 :(得分:1)

.dockerignore文件类似于.gitignore语法。以下是一些示例规则:

# Ignore a file or directory in the context root named "modules"
modules

# Ignore any files or directories within the subdirectory named "modules" 
# in the context root
modules/*

# Ignore any files or directories in the context root beginning with "modules"
modules*

# Ignore any files or directories one level down from the context root named
# "modules"
*/modules

# Ignore any files or directories at any level, including the context root, 
# named modules
**/modules

# Ignore every file in the entire build context (see next rule for how this 
# could be used)
*

# Re-include the file or directory named "src" that may have been previously
# excluded. Note that you cannot re-include files in subdirectories that have 
# been previously excluded at a higher level
!src

请注意,“构建上下文”是您在构建命令末尾传递的目录,通常为.,以指示当前目录。该目录从Docker客户端打包,不包括您用.dockerignore忽略的所有文件,并发送到docker守护程序执行构建。即使守护程序与客户端位于同一主机上,构建也只能在此上下文中工作,而不能直接在文件夹中工作。

只有一个.dockerignore用于构建,它必须在构建上下文的根目录中。如果它位于您的主目录中(假设您是从子目录构建的),它将不起作用,并且它也不会从构建上下文的子目录运行。

要测试当前构建上下文中的内容并验证.dockerignore文件的行为,可以复制/粘贴以下内容(假设您没有名为test-context的图像,它将被覆盖,然后删除):

# create an image that includes the entire build context
docker build -t test-context -f - . <<EOF
FROM busybox
COPY . /context
WORKDIR /context
CMD find .
EOF

# run the image which executes the find command
docker container run --rm test-context

# cleanup the built image
docker image rm test-context

答案 6 :(得分:0)

优化容器图片大小是 .dockerignore 背后的主要目标,因为它的目的与 .gitignore 相似,因为它可以减少延迟和响应时间,同时提供服务。对于Puppet,SaltStack或Ansible等部署自动化来说确实如此。由于较大的映像大小和较低的网络带宽,为服务执行部署定义的时间戳可能会失败。因此.dockerignore有助于使图像的大小尽可能小。

您可以将它放入我们在docker build命令末尾指定的构建上下文目录。该文件遵循文件和目录的glob模式,以从最终构建映像中排除这些模式。

假设我有一个目录。 img / 进入我的构建环境,我想在构建图像时将其排除,我只需将以下行添加到.dockerignore文件中,

.img

并且,如果我想要排除所有文件开头。然后简单地添加一行,

.*

(注意:不要混淆Unix glob模式与正则表达式不同)

此外,我还会从构建环境中排除更多我的文件,

.*
docs
my-stack.dab
docker-compose.overrride.yml
test*
*.md
!README.md

此处, *。md 行排除所有降价文件(我的项目中有很多降价文件)。但是,我想要包含 README.md 而不包含其他降价文件。作为上面的最后一行,我们在中添加了README.md,或者在排除所有其他markdown文件时将其排除。

因此,借助 .dockerignore ,我们可以减少构建图像的开销,并利用它来缩小图像尺寸。

答案 7 :(得分:0)

我认为,针对您的用例的最佳解决方案是在docker文件中使用Multi-stage build。您的Dockerfile必须位于一个空目录中,并且您在一次性容器中运行puppet。

从上面的链接:

  

对于多阶段构建,您可以在自己的数据库中使用多个FROM语句   Dockerfile。每个FROM指令可以使用不同的基数,并且每个   他们中的一个开始了构建的新阶段。您可以有选择地复制   从一个阶段到另一个阶段的文物,留下了一切   不需要最后一张图片。