编写Dockerfiles的优秀实践
避免运行apt-get升级和distl -upgrade,因为来自父镜像的许多"基本"包无法在非特权容器中升级。如果父镜像中包含的包过期了,请联系它的维护人员。如果您知道有一个特定的包foo需要更新,那么使用apt-get install -y foo自动更新。 始终将RUN apt-get update与apt-get install组合在同一个RUN语句中。例如:
在RUN语句中单独使用apt-get update会导致缓存问题,随后的apt-get安装指令会失败。例如,假设您有一个Dockerfile:
当构建完镜像后,所有的层都已经被缓存了,假设之后你修改了apt-get install 增加了其他的包:
Docker将初始指令和修改后的指令视为相同的,并重用前面步骤中的缓存。因此,apt-get更新不会执行,因为构建使用缓存的版本。由于apt-get更新没有运行,您的构建可能会得到一个过时版本的curl和nginx包。 使用RUN apt-get update && apt-get install -y确保您的Dockerfile安装最新的包版本,而无需进一步编码或手动干预。这种技术称为"缓存破坏"。还可以通过指定包版本来实现缓存崩溃。这就是所谓的版本固定,例如:
版本固定强制构建以检索特定版本,而不管缓存中的内容是什么。这种技术还可以减少由于所需包中的意外更改而导致的故障。 下面是一个格式良好的运行指令,演示了所有apt-get 的优秀实践。
s3cmd指定了一个新的版本。如果之前的镜像安装的是一个旧的版本。apt-get update 会导致缓存失效,从而安装新的版本。 在这样的条件下,当你清除apt缓存并且移除/var/lib/apt/lists 目录,来减小文件尺寸。当RUN 声明以apt-get update开始,在执行apt-get install的时候,缓存依然会被刷新。 注: Debian和ubuntu的官方镜像会自动运行apt-get clecn命令。所以不需要显示调用。 使用管道 有些运行命令依赖于使用管道字符(|)将一个命令的输出管道到另一个命令的能力,如下例所示:
Docker使用/bin/sh -c解释器执行这些命令,解释器只计算管道中最后一个操作的退出代码来确定是否成功。在上面的示例中,只要wc -l命令成功,即使wget命令失败,这个构建步骤就会成功并生成一个新映像。 如果您希望命令在管道中的任何阶段由于错误而失败,请预先设置-o pipefail &&,以确保意外错误防止构建意外成功。例如:
注: 不是所有的shell都支持 –o pipfail 选项 在基于debian的镜像上使用dash shell的情况下,可以考虑使用exec形式的RUN显式地选择一个支持pipefail选项的shell。例如:
CMD CMD指令应该用于运行镜像所包含的软件,以及任何参数。CMD几乎总是以CMD["executable"、"param1"、"param2"…]的形式使用。因此,如果镜像是用于服务的,比如Apache和Rails,您将运行类似CMD ["apache2","-DFOREGROUND "]的东西。实际上,对于任何基于服务的镜像,都推荐使用这种形式的指令。 在大多数其他情况下,应该为CMD提供一个交互式shell,如bash、python和perl。例如,CMD ["perl"、"-de0"], CMD ("python"),或CMD ("php","-a")。使用这种形式意味着,当您执行像docker run - python这样的东西时,您将被放入一个可用的shell中,准备就绪。CMD应该很少与ENTRYPOINT一起以CMD ["param", "param"]的方式使用,除非您和您的预期用户已经非常熟悉ENTRYPOINT的工作方式。 EXPOSE EXPOSE指令指示容器监听连接的端口。因此,您应该为您的应用程序使用公共的、传统的端口。例如,包含Apache web服务器的镜像使用 80端口,而包含MongoDB的映像将使用 27017 端口,以此类推。 对于外部访问,用户可以使用一个标志执行docker run,该标志指示如何将指定的端口映射到他们选择的端口。对于容器链接,Docker为从接收容器返回到源容器的路径提供了环境变量(即MYSQL_PORT_3306_TCP)。 ENV 为了使新软件更容易运行,可以使用ENV更新容器安装的软件的PATH环境变量。例如,ENV PATH /usr/local/nginx/bin:$PATH确保CMD ["nginx"]正常工作。 ENV指令对于提供特定于您希望封装的服务的所需环境变量也很有用,比如Postgres的PGDATA。 (编辑:晋中站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |