dockerfile简述

做用

Dockerfile的内容是一坨能够执行的代码(或者说是指令)(docker的DSL),这些代码使得建立镜像的操做能够复用以及自动化。git

指令格式

Dockerfile的指令格式很简单:
INSTRUCTION argumentsgithub

指令是不区分大小写的,可是约定为所有大写。
Dockerfile中指令的书写顺序就是它们的执行顺序。docker

指令

FROM

Dockerfile必须以FROM指令开始,FROM指令指定了基础镜像是什么。也就是基于哪一个镜像来制做本身的镜像。
FROM <image name>
image name的格式通常为"image:tag"shell

MAINTAINER

指定镜像的做者信息:
MAINTAINER <author name>segmentfault

RUN

在shell或者exec的环境下执行的命令。RUN指令会在新建立的镜像上添加新的层面,接下来提交的结果用在Dockerfile的下一条指令中。
RUN <command>学习

ADD和COPY

复制文件指令。
ADD <source> <destination>
source能够是URL或者是启动配置上下文中的一个文件。
将文件拷贝到container的文件系统对应的路径
全部拷贝到container中的文件和文件夹权限为0755,uid和gid为0
若是文件是可识别的压缩格式,则docker会帮忙解压缩。
ui

  • 若是要ADD本地文件,则本地文件必须在 docker build ,指定的 目录下
  • 若是要ADD远程文件,则远程文件必须在 docker build ,指定的 目录下。好比:
    docker build github.com/creack/docker-firefox
    docker-firefox目录下必须有Dockerfile和要ADD的文件。

COPY指令功能相似,可是COPY不容许source是URL,同时也不会进行解压。this

CMD和ENTRYPOINT

提供了容器默认的执行命令。 Dockerfile只容许使用一次CMD/ENTRYPOINT指令。 使用多个CMD/ENTRYPOINT会抵消以前全部的指令,只有最后一个指令生效。 CMD有三种形式:.net

CMD ["executable","param1","param2"] (exec form, this is the preferred form)
CMD command param1 param2 (shell form)
CMD ["param1","param2"] (as default parameters to ENTRYPOINT)

区别:
第二种方式会以"/bin/sh -c"形式调用。第三种方式是为ENTRYPOINT指定参数,也就是使用第三种形式时,要有一个ENTRYPOINT指令。firefox

若是在执行docker run时提供了command,且command和CMD中相同(参数能够不一样),则会执行command,不执行CMD中的命令(实际含义就是把CMD中传递param覆盖了)。

ENTRYPOINT(An ENTRYPOINT allows you to configure a container that will run as an executable)有两种格式:

ENTRYPOINT ["executable", "param1","param2"] (exec form)
ENTRYPOINT command param1 param2 (shell form)

区别:
第二种(shell form)会屏蔽掉docker run时后面加的命令和CMD里的参数;第一种会把docker run后面的参数或CMD里的参数追加给ENTRYPOINT,docker run后面的参数会覆盖掉CMD里的参数。

例如:

...
ENTRYPOINT ["echo", "param1"]

执行
docker run -it test param2
显示param1 param2
若是是shell form形式,docker run提供的参数就无效。

二者区别

ENTRYPOINT和CMD的不一样点在于执行docker run时参数传递方式,CMD指定的命令能够被docker run传递的命令覆盖,例如,若是用CMD指定:

...
CMD ["echo"]

而后运行
docker run CONTAINER_NAME echo foo
那么CMD里指定的echo会被新指定的echo覆盖,因此最终至关于运行echo foo,因此最终打印出的结果就是:
foo
而ENTRYPOINT会把容器名后面的全部内容都当成参数传递给其指定的命令(不会对命令覆盖),好比:

...
ENTRYPOINT ["echo"]

而后运行
docker run CONTAINER_NAME echo foo
则CONTAINER_NAME后面的echo foo都做为参数传递给ENTRYPOING里指定的echo命令了,因此至关于执行了
echo "echo foo"
最终打印出的结果就是:
echo foo
另外,在Dockerfile中,ENTRYPOINT指定的参数比运行docker run时指定的参数更靠前,好比:

...
ENTRYPOINT ["echo", "foo"]

执行
docker run CONTAINER_NAME bar
至关于执行了:
echo foo bar
打印出的结果就是:
foo bar

EXPOSE

指定容器在运行时监听的端口。
EXPOSE <port> [<port>...]
该指令会将容器中的端口映射成宿主机器中的某个端口。当你须要访问容器的时候,能够不使用容器的IP地址而是使用宿主机器的IP地址和映射后的端口。要完成整个操做须要两个步骤:

  • 首先在Dockerfile使用EXPOSE设置须要映射的容器端口;
  • 而后在运行容器的时候指定-p选项加上EXPOSE设置的端口,这样EXPOSE设置的端口号会被随机映射成宿主机器中的一个端口号。也能够指定须要映射到宿主机器的那个端口,这时要确保宿主机器上的端口号没有被使用。
    EXPOSE指令能够一次设置多个端口号,相应的运行容器的时候,能够配套的屡次使用-p选项。

WORKDIR

切换目录用,能够屡次切换(至关于cd命令),对RUN,CMD,ENTRYPOINT生效。
WORKDIR /path/to/workdir

ENV

设置环境变量。
ENV <key> <value>
若是不指定value,表示清除key环境变量。

USER

使用哪一个用户跑container:
USER <uid>

VOLUME

受权访问从容器内到主机上的目录。语法以下:
VOLUME ["/data"]

参考文档

Dockerfile reference
Docker入门教程(三)Dockerfile
Docker Dockerfile详解
Docker学习笔记(3)-- 如何使用Dockerfile构建镜像
Dockerfile里指定执行命令用ENTRYPOING和用CMD有何不一样?
What is the difference between the COPY and ADD commands in a Dockerfile?

相关文章
相关标签/搜索