一般指南和建议
1、使用.dockerignore文件
早多数情况下,最好把dockerfile放在一个空的目录中,然后在该目录中添加所需要的文件,为了提高构建的性能,可以通过添加.dockerignore来排除一些文件
怎么创建一个.dockerignore文件,可以参考该文档.dockerignore
2、避免安装不必要文件包
3、每个容器都应该只实现一个功能
4、最小化层
5、对多行参数进行排序
RUN apt-get update && apt-get install -y \
bzr \
cvs \
git \
mercurial \
subversion
6、构建缓存
dockerfile结构
1、FROM
使用官方库作为基础镜像,建议使用debian镜像,因为他是非常严格控制和保持镜像最小,而且它又是完整的发行版。
2、LABLE
可以通过添加lable的方式来根据项目组织镜像,记录许可信息,以帮助自动化。设置镜像的元数据信息
LABEL指令拥有为镜像添加一些描述的元数据。LABEL是一系列的键值对,它的格式如下:对于每个label,用LABLE标志开始一行,并添加一个或多个键值对,例如:
# Set one or more individual labels
LABEL com.example.version="0.0.1-beta"
LABEL vendor="ACME Incorporated"
LABEL com.example.release-date="2015-02-12"
LABEL com.example.version.is-production=""
# Set multiple labels on one line
LABEL com.example.version="0.0.1-beta" com.example.release-date="2015-02-12"
# Set multiple labels at once, using line-continuation characters to break long lines
LABEL vendor=ACME\ Incorporated \
com.example.is-beta= \
com.example.is-production="" \
com.example.version="0.0.1-beta" \
com.example.release-date="2015-02-12"
通过docker inspect命令,可以查看镜像中的标签信息。
3、RUN
为了使得镜像文件更加易读,易于理解和更可维护性,可以在使用反斜杠分隔的多行上拆分或复杂的RUN语句,始终将软件包更新和安装命令结合在同一个语句中。最好将不同命令使用&&结合在同一个命令中
RUN apt-get update && apt-get install -y \
aufs-tools \
automake \
build-essential \
curl \
dpkg-sig \
libcap-dev \
libsqlite3-dev \
mercurial \
reprepro \
ruby1.9.1 \
ruby1.9.1-dev \
s3cmd=1.1.* \
&& rm -rf /var/lib/apt/lists/*
4、CMD
CMD指令应该伴随其他参数被用来运行镜像中的软件容器,CMD大都这样使用 CMD [“executable”, “param1”, “param2”…],cmd即容器在跑起来时执行的命令
5、EXPOSE
将容器中的某端口暴露出来。
6、ENV
为了使新的软件能够更加便利的运行,我们能够使用ENV指令来更新PATH的环境变量,例如定义ENV PATH /usr/local/nginx/bin:$PATH 之后才可以确保CMD [“nginx”]的正常运行
最后ENV还可以设置通用的版本号以防版本波动
ENV PG_MAJOR 9.3
ENV PG_VERSION 9.3.4
RUN curl -SL http://example.com/postgres-$PG_VERSION.tar.xz | tar -xJC /usr/src/postgress && …
ENV PATH /usr/local/postgres-$PG_MAJOR/bin:$PATH
7、ADD or COPY
尽管ADD和COPY在功能上相似,但一般来说,COPY是优选的。那是因为它比ADD更透明。 COPY仅支持将本地文件基本复制到容器中,而ADD具有一些功能(如仅限本地的tar提取和远程URL支持),这些功能并不是很明显。因此,ADD的最佳用途是将本地tar文件自动提取到图像中,如ADD rootfs.tar.xz /中所示。
如果您有多个使用上下文中不同文件的Dockerfile步骤,请单独复制它们,而不是一次复制它们。这将确保每个步骤的构建缓存仅在特定需要的文件更改时失效(强制重新执行该步骤)。
COPY requirements.txt /tmp/
RUN pip install --requirement /tmp/requirements.txt
COPY . /tmp/
与放置COPY相比,RUN步骤的缓存失效次数更少。 / tmp /之前。
由于图像大小很重要,因此强烈建议不要使用ADD从远程URL中提取包。你应该使用curl或wget代替。这样,您可以删除提取后不再需要的文件,也不必在图像中添加其他图层。例如,你应该避免做以下事情:
ADD http://example.com/big.tar.xz /usr/src/things/
RUN tar -xJf /usr/src/things/big.tar.xz -C /usr/src/things
RUN make -C /usr/src/things all
你应该这样
RUN mkdir -p /usr/src/things \
&& curl -SL http://example.com/big.tar.xz \
| tar -xJC /usr/src/things \
&& make -C /usr/src/things all
8、ENTRYPOINT
ENTRYPOINT的最佳用途是设置镜像的主命令,允许该镜像像该命令一样运行(然后使用CMD作为默认标志)。
ENTRYPOINT指令也可以与辅助脚本结合使用,使其能够以与上述命令类似的方式运行,即使启动该工具可能需要多个步骤。ENTRYPOINT是个命令入口,可以在容器运行的时候传入参数,
9、VOLUME
VOLUME指令应用于公开由docker容器创建的任何数据库存储区域,配置存储或文件/文件夹。强烈建议您将VOLUME用于镜像的任何可变和/或用户可维修部分。
10、USER
您应该避免安装或使用sudo,因为它具有不可预测的TTY和信号转发行为,可能导致比它解决的问题更多的问题。如果你绝对需要类似于sudo的功能(例如,以root身份初始化守护进程但是以非root运行它),你可以使用“gosu”。
11、WORKDIR
指定工作目录,为了清晰和可靠,您应该始终使用WORKDIR的绝对路径。此外,你应该使用WORKDIR而不是像RUN cd那样激增指令… && do-something,这些指令难以阅读,故障排除和维护。
12、ONBUILD
在当前Dockerfile构建完成后执行ONBUILD命令。 ONBUILD在从当前图像派生的任何子图像中执行。将ONBUILD命令视为父Dockerfile为子Dockerfile提供的指令。
13、MAINTAINER
设置该镜像的作者相关信息