加入收藏 | 设为首页 | 会员中心 | 我要投稿 核心网 (https://www.hxwgxz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 建站 > 正文

编写Dockerfiles的优秀实践

发布时间:2019-09-17 23:26:17 所属栏目:建站 来源:架构师之路
导读:本文档介绍了构建高效镜像的优秀实践和方法。 Docker通过从Dockerfile(按顺序包含构建给定镜像所需的所有命令的文本文件)读取命令来自动构建镜像。Dockerfile遵循特定的格式和一组命令,您可以在Dockerfile reference中找到这些命令。 Docker镜像由只读层
副标题[/!--empirenews.page--]

本文档介绍了构建高效镜像的优秀实践和方法。

编写Dockerfiles的优秀实践

Docker通过从Dockerfile(按顺序包含构建给定镜像所需的所有命令的文本文件)读取命令来自动构建镜像。Dockerfile遵循特定的格式和一组命令,您可以在Dockerfile reference中找到这些命令。

Docker镜像由只读层组成,每个只读层表示Dockerfile指令。这些层被堆叠起来,每一层都是前一层变化的增量。考虑一下这个Dockerfile:

  1. FROM ubuntu:18.04 
  2. COPY . /app 
  3. RUN make /app 
  4. CMD python /app/app.py 

每一个指令会创建一个层:

  • FROM从docker image ubuntu:18.04 创建层 。
  • COPY从Docker 客户端添加文件到当前目录。
  • RUN使用make 命令构建应用。
  • CMD指定在容器里运行的命令。

当您运行一个镜像并生成一个容器时,您将在底层之上添加一个新的可写层("容器层")。对正在运行的容器所做的所有更改,例如写入新文件、修改现有文件和删除文件,都被写入这个可写容器层。

通用概览和建议

创建临时容器

Dockerfile定义的镜像应该生成尽可能"短暂"的容器。所谓"临时性",是指容器可以停止和销毁,然后用绝对最小的设置和配置重新构建和替换。

理解构建上下文

当您发出docker构建命令时,当前工作目录称为构建上下文。默认情况下, Dockerfile在当前目录,但是您可以使用file标志(-f)指定一个不同的位置。无论Dockerfile实际位于何处,当前目录中文件和目录的所有递归内容都作为构建上下文发送到Docker守护进程。

构建上下文:

为构建上下文创建一个目录并将cd放入其中。将"hello"写入一个名为hello的文本文件中,并创建一个运行cat的Dockerfile。从构建上下文中构建镜像(.):

  1. mkdir myproject && cd myproject 
  2. echo "hello" > hello 
  3. echo -e "FROM busyboxnCOPY /hello /nRUN cat /hello" > Dockerfile 
  4. docker build -t helloapp:v1 . 

将Dockerfile和hello移到单独的目录中,并构建镜像的第二个版本(不依赖于上一个构建的缓存)。使用-f指向Dockerfile并指定构建上下文的目录:

  1. mkdir -p dockerfiles context 
  2. mv Dockerfile dockerfiles && mv hello context 
  3. docker build --no-cache -t helloapp:v2 -f dockerfiles/Dockerfile context 

无意中包含了构建镜像所不需要的文件,会导致构建上下文和镜像大小变大。这可以增加构建镜像的时间、拖放镜像的时间和容器运行时大小。要查看构建上下文的大小,请在构建Dockerfile时查看类似这样的消息:

  1. Sending build context to Docker daemon 187.8MB 

通过stdin使用Dockerfile 管道

Docker能够通过使用本地或远程构建上下文通过stdin管道传输Dockerfile来构建镜像。通过stdin管道传输Dockerfile对于执行一次性构建非常有用,不需要将Dockerfile写入磁盘,或者在生成Dockerfile的情况下,不应该在生成后保存Dockerfile。

为了方便起见,本节中的示例使用here文档【http://tldp.org/LDP/abs/html/here-docs.html】,但是可以使用在stdin上提供Dockerfile的任何方法。

例如: 下面的命令是等价的:

  1. echo -e 'FROM busyboxnRUN echo "hello world"' | docker build - 
  2. docker build -<<EOF 
  3. FROM busybox 
  4. RUN echo "hello world" 
  5. EOF 

您可以用您喜欢的方法或者最适合您用例的方法来替代这些例子。

使用STDIN中的DOCKERFILE构建镜像,而不发送构建上下文

使用此语法可以从stdin中用Dockerfile构建映像,而不需要发送额外的文件作为构建上下文。连字符(-)占据路径的位置,指示Docker从stdin而不是目录中读取构建上下文(其中只包含Dockerfile):

  1. docker build [OPTIONS] – 

下面的示例使用通过stdin传递的Dockerfile构建一个镜像。没有文件作为构建上下文发送到守护进程。

  1. docker build -t myimage:latest -<<EOF 
  2. FROM busybox 
  3. RUN echo "hello world" 
  4. EOF 

在Dockerfile不需要将文件复制到镜像中的情况下,省略构建上下文是非常有用的,并且可以提高构建速度,因为没有文件被发送到守护进程。

注意:如果使用这种语法,尝试构建使用COPY或ADD的Dockerfile将会失败。下面的例子说明了这一点:

  1. # create a directory to work in 
  2. mkdir example 
  3. cd example 
  4. # create an example file 
  5. touch somefile.txt 
  6. docker build -t myimage:latest -<<EOF 
  7. FROM busybox 
  8. COPY somefile.txt . 
  9. RUN cat /somefile.txt 
  10. EOF 
  11. # observe that the build fails 
  12. ... 
  13. Step 2/3 : COPY somefile.txt . 
  14. COPY failed: stat /var/lib/docker/tmp/docker-builder249218248/somefile.txt: no such file or directory 

使用STDIN中的DOCKERFILE从本地构建上下文构建

(编辑:核心网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读