24条Dockerfile及指令最佳实践( 四 )


如果run命令后面有执行命令 , 那么后面的全部都会作为ENTRYPOINT的参数 。如果run后面没有额外的命令,但是定义了CMD , 那么CMD的全部内容就会作为ENTRYPOINT的参数,这同时是上面我们提到的CMD的第二种用法 。
所以说ENTRYPOINT不会被覆盖 。当然如果要在run里面覆盖,也是有办法的 , 使用--entrypoint参数即可 。
一般会用ENTRYPOINT的中括号形式作为Docker容器启动以后的默认执行命令,里面放的是不变的部分,可变部分比如命令参数可以使用CMD的形式提供默认版本 , 也就是run里面没有任何参数时使用的默认参数 。如果我们想用默认参数 , 就直接run,否则想用其他参数,就run里面加上参数 。
ADD COPY虽然ADD与COPY功能类似,但推荐使用COPY 。因为它比 ADD 更透明 。COPY只支持基本的文件拷贝功能 , 更加的可控 。而ADD具有更多特定,比如tar文件自动提取,支持URL 。通常需要提取tarball中的文件到容器的时候才会用到ADD 。
如果在Dockerfile中使用多个文件,每个文件应使用单独的COPY指令 。这样,只有出现文件变化的指令才会不使用缓存 。
为了控制镜像的大?。?不建议使用ADD指令获取URL文件 。正确的做法是在RUN指令中使用wget或curl来获取文件,并且在文件不需要的时候删除文件 。
RUN mkdir -p /usr/src/things&& curl -SL http://example.com/big.tar.gz| tar -xJC /usr/src/things&& make -C /usr/src/things allVOLUMEVOLUME指令用于声明容器中的目录将被持久化保存,即在容器中创建的目录将被挂载到宿主机或其他容器中,以便数据可以在容器之间共享 。
VOLUME指令应当暴露出数据库的存储位置,配置文件的存储以及容器中创建的文件或目录 。由于容器结束后并不保存任何更改 , 应该把所有数据通过VOLUME保存到host中 。
强烈建议使用VOLUME来管理镜像中的可变部分和用户可以改变的部分 。
USER如果服务不需要特权来运行,使用USER指令切换到非root用户 。使用RUN groupadd -r MySQL && useradd -r -g mysql mysql之后用USER mysql切换用户 。
要避免使用sudo来提升权限 , 因为它不可预期的TTY和信号转发行为可能造成的问题比它能解决的问题还多 。如果你真的需要和sudo类似的功能(例如 , 以root权限初始化某个守护进程,以非root权限执行它),你可以使用gosu 。我们可以去查看官方的一些镜像,很多都是使用的gosu 。
最后,不要反复地切换用户,减少不必要的layers 。
WORKDIR为了清晰性和可靠性,WORKDIR的路径应该始终使用绝对路径 。同时 , 使用WORKDIR来替代RUN cd ... && do-something这样难以维护的指令 。后者难以阅读、排错和维护 。

【24条Dockerfile及指令最佳实践】


推荐阅读