Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。
ARG
设置参数,该参数值可以从--build-arg <varname>=<value>接收值
在FROM之前的ARG参数只能在FROM语句中生效,若在FROM之后想继续使用ARG,需要再次设置
|----------------------------------------------------------------------|
| Bash Usage: ARG <name>[=<default value>] 例:ARG version="1.0.0" |
FROM
指定基础镜像,FROM必须为Dockerfile非注释行的第一行
|-------------------------------------------------------------------------------------------------|
| Bash Usage: FROM <image> FROM <image>:<tag> FROM <image>@<digest> 例:FROM ubuntu:14.04 |
LABEL
设置镜像标签
|----------------------------------------------------------------------------------------------------------------|
| Bash Usage: LABEL <key>=<value> <key>=<value> <key>=<value> ... 例:LABEL maintainer="demo@demo.com" |
ENV
设置环境变量
建议:不论用那种书写方式,实际使用中一行只能写一个环境变量,方便阅读
注意:在使用docker run命令添加参数--env时,若有相同的环境变量,以run命令为准
|--------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Bash Usage: ENV <key> <value> ENV <key>=<value> ... ENV <key> <value>此方法一次只能设置一个 ENV <key>=<value> ... 该方法一次可以设置多个环境变量 例:ENV JAVA_HOME=/home/jdk-8 |
ADD
添加文件,复制宿主机文件、目录或者远程文件URLS添加到容器指定路径中,不推荐添加远程URL
支持tar包自动解压
|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Bash Usage: ADD [--chown=<user>:<group>] <src>... <dest> ADD [--chown=<user>:<group>] ["<src>",... "<dest>"] 例:ADD ${WORKSPACE}/target /usr/local/tomcat/webapps/ROOT 例:ADD http://example.com/big.tar.xz /usr/src/things/ |
COPY
添加文件,用法同ADD,只是不同的是不能复制远程文件URLS
不支持tar包自动解压,如果不添加tar文件,推荐使用COPY
|--------------------------------------------------------------------------------------------------------------------------------------|
| Bash Usage: COPY [--chown=<user>:<group>] <src>... <dest> COPY [--chown=<user>:<group>] ["<src>",... "<dest>"] |
USER
指定运行容器的用户名或UID,后续的RUN、CMD、ENTRYPOINT也会使用指定用户
|------------------------------------------------------------------------------|
| Bash Usage: USER <user>[:<group>] USER <UID>[:<GID>] 例:USER root |
WORKDIR
工作目录,进入容器后,以WORKDIR为当前路径,为后续的RUN、CMD、ENTRYPOINT指令配置工作目录,可以使用多个WORKDIR指令,后续命令如果参数是相对路径,则会基于之前命令指定的路径
|-----------------------------------------------------------------|
| Bash Usage: WORKDIR /a WORKDIR b WORKDIR c 例:最终WORKDIR路径是/a/b/c |
EXPOSE
说明容器暴露的端口,默认协议是tcp,若是udp协议需要在后面 添加udp,如80/udp。
同时在docker run时使用-p或者-P映射端口。
|-------------------------------------------------------------------------------------------------------|
| Bash Usage: EXPOSE <port> [<port>/<protocol>...] 例:EXPOSE 8080,表明容器在运行时提供8080端口,在启动该容器时需端口映射。 |
VOLUME
设置挂载点,将容器内的路径挂载到宿主机,该挂载方式是将容器内的路径挂载到docker数据路径下
|----------------------------------------------|
| Bash Usage: VOLUME <url> 例:VOLUME /var/log |
RUN
执行命令并创建新的镜像层,通常用于更新或安装软件
|-----------------------------------------------------------------------------------------------|
| Bash Usage: RUN <command> RUN ["executable", "param1", "param2"] 例:RUN yum -y install git |
CMD
设置容器启动后默认执行的命令,CMD命令会被docker run的参数覆盖。
CMD指令在dockerfile中只能用一次,如果有多条,则只有最后一条生效。
|---------------------------------------------------------------------------------------------------------------------------|
| Bash Usage: CMD <command> CMD ["executable","param1","param2"] 例:CMD systemclt start docker.service //启动容器时启动docker服务 |
ENTRYPOINT
和CMD一样,设置容器启动后默认执行的命令,该命令不会被docker run覆盖,会始终执行
每个dockerfile只能有一个ENTRYPOINT,如果有多个,只能最后一个生效
|------------------------------------------------------------------------------------------------------------------------------------------------|
| Bash Usage: ENTRYPOINT <command> ENTRYPOINT ["executable", "param1", "param2"] 例:ENTRYPOINT /usr/local/apache-tomcat-8.5.33/bin/startup.sh |
ONBUILD
当所创建的镜像作为其它镜像的Base镜像时,会继承ONBUILD的操作指令,例如本镜像有ONBUILD指令,则基于此镜像构建的新镜像也会自动支持ONBUILD指令内容, 即:
ADD ./app/src
RUN /usr/local/bin/python-build --dir /app/src
|----------------------------------------------------------------------------------------------------|
| Bash [...] ONBUILD ADD . /app/src ONBUILD RUN /usr/local/bin/python-build --dir /app/src [...] |
DEMO示例
|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Bash FROM cr.kylinos.cn/kylin/kylin-server-init:v10sp3-2403 ADD kylin_x86_64.repo /etc/yum.repos.d/kylin_x86_64.repo RUN chmod 0644 /etc/yum.repos.d/kylin_x86_64.repo RUN yum install -y cronie crontabs ADD crontab-file /etc/cron.d/user-cron ADD date.sh /home RUN chmod 0644 /etc/cron.d/user-cron && crontab /etc/cron.d/user-cron RUN chmod +x /home/date.sh RUN touch /var/log/date.log ENTRYPOINT ["/sbin/init"] |
最佳实践
- 使用.dockerignore文件
为了在docker build过程中上传更加高效,可以使用.dockerignore文件来排除构建镜像时不需要的文件或目录,比如除非.Git目录需要被用到,否则应该添加到.dockerignore文件中,可以节省很多时间。
- 避免安装不必要的软件包
为了降低复杂性、依赖性,应避免安装额外的或不必要的包,例如不需要在数据库镜像中安装一个文本编辑器。
- 每个容器只跑一个进程
尽量让一个容器只跑一个进程,解耦应用到多个容器使其更易横向扩展和重用。
- 最小化层
因为每执行一个指令,都会有一次镜像的提交,镜像是分层的结构,对于dockerfile需要找到可读性和最小化层之间的平衡。
多行参数排序
如果可以,通过字母顺序来排序,可以避免安装包的重复且更容易更新列表,可读性更强,添加一个空行使用 \ 换行
|-------------------------------------------------------------------------------------------------|
| Bash RUN apt-get update && apt-get install -y \ bzr \ cvs \ git \ mercurial \ subversion |