docker (3) dockerfile 指令

dockerfile 是建立docker镜像的文本,可使用docker build -t name . 命令建立对应的docker镜像。docker在建立镜像的过程当中会首先建立容器,而后根据每个命令,构建容器的每一层,最终构建整个镜像的文件。镜像文件使用的时候,也是将每层分别overlay到下层之上。docker

1. ADD 与COPY命令

Dockerfile中的COPY指令和ADD指令,将主机上的资源复制或添加到容器镜像中,每一行命令都构建容器镜像的一层。shell

COPY指令和ADD指令的区别:ubuntu

  1. ADD命令支持从远程URL获取资源并复制到镜像中,COPY指令只能从执行docker build所在的主机上读取资源并复制到镜像中。
  1. ADD命令能够将整个tar包,拷贝到镜像文件中,并进行解压缩。
    知足同等功能的状况下,推荐使用COPY指令。ADD指令更擅长读取本地tar文件并解压缩。

COPY指令

COPY指令可以将构建命令所在的主机本地的文件或目录,复制到镜像文件系统。
exec格式用法(推荐):
COPY [" ",... " "],推荐,特别适合路径中带有空格的状况
shell格式用法:
COPY ...
数组

ADD指令

exec格式用法(推荐):
ADD [" ",... " "],特别适合路径中带有空格的状况
shell格式用法:
ADD ...
说明,对于从远程URL获取资源的状况,因为ADD指令不支持认证,若是从远程获取资源须要认证,则只能使用RUN wget或RUN curl替代。
另外,若是源路径的资源发生变化,则该ADD指令将使Docker Cache失效,Dockerfile中后续的全部指令都不能使用缓存。所以尽可能将ADD指令放在Dockerfile的后面。
缓存

注意事项:

  1. 原路径
    源路径能够有多个
    源路径是相对于执行build的相对路径
    源路径若是是本地路径,必须是build上下文中的路径
    源路径若是是一个目录,则该目录下的全部内容都将被加入到容器,可是该目录自己不会
  2. 目标路径
    目标路径必须是绝对路径,或相对于WORKDIR的相对路径
    目标路径若是不存在,则会建立相应的完整路径
    目标路径若是不是一个文件,则必须使用/结束
    路径中可使用通配符

读取URL远程资源

当要读取URL远程资源的时候,并不推荐使用ADD指令,而是使用RUN指令,在RUN指令中执行wget或curl命令。tomcat

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

CMD与ENTRYPOINT

CMD指令能够指定容器启动时要执行的命令,但它能够被docker run命令的参数覆盖掉。
ENTRYPOINT 指令和CMD相似,它也可用户指定容器启动时要执行的命令。dockerfile中能够有多条cmd命令,但只是最后一条有效。
若是dockerfile中也有CMD指令,CMD中的参数会被附加到ENTRYPOINT 指令的后面。
若是这时docker run命令带了参数,这个参数会覆盖掉CMD指令的参数,并也会附加到ENTRYPOINT 指令的后面。
这样当容器启动后,会执行ENTRYPOINT 指令的参数部分。能够看出,相对来讲ENTRYPOINT指令优先级更高。
CMD命令的参数格式,通常写成 字符串数组的方式,如上面的例子。如:服务器

CMD  ["echo","hello world"]

虽然也可写成CMD echo hello word 方式,但这样docker会在指定的命令前加 /bin/sh -c 执行,有时有可能会出问题。 因此推荐采用数据结构的方式来存放命令。数据结构

#test
FROM ubuntu
MAINTAINER hello
RUN echo hello1 > test1.txt
RUN echo hello2 > /test2.txt
EXPOSE 80
ENTRYPOINT ["echo"]
CMD ["defaultvalue"]

当运行 docker run image 输出的内容是 defaultvalue,能够看出CMD指令的参数得确是被添加到ENTRYPOINT指令的后面,而后被执行。
当运行docker run myimage hello world 输出的内容是 hello world ,能够看出docker run命令的参数得确是被添加到ENTRYPOINT指令的后面,而后被执行,这时CMD指令被覆盖了。
另外咱们能够在docker run命令中经过 --entrypoint 覆盖dockerfile文件中的ENTRYPOINT设置,如:运维

docker run --entrypoint="echo" myimage good  结果输出good

注意,无论是哪一种方式,建立容器后,经过 dokcer ps查看容器信息时,COMMOND列会显示最终生效的启动命令。curl

EXPOSE  命令

EXPOSE port [port2,port3,...],例如EXPOSE 80这条指令告诉Docker服务器暴露80端口,供容器外部链接使用。
在启动容器的使用使用-P,Docker会自动分配一个端口和转发指定的端口,使用-p能够具体指定使用哪一个本地的端口来映射对外开放的端口。
EXPOSE命令只是声明了容器应该打开的端口,并无实际上将它打开!
若是不用-p或者-P中指定要映射的端口,容器不会映射端口出去。不能在Dockerfile里面进行端口映射,只能在容器启动的时候或者在docker-compose文件中使用ports来指定将要映射的端口。

EXPOSE命令的做用

  1. 写在Dockerfile中进行声明,能让运维人员或者后来者知道咱们开启了容器的哪些端口。
  2. 当咱们声明了EXPOSE端口以后,咱们使用-P命令进行随机映射的时候,是会对这个端口进行映射的。
    好比说咱们如今对一个tomcat容器进行EXPOSE 9999声明,那么咱们进行-P随机映射的时候是会对9999端口进行映射的。

WORKDIR命令

格式: WORKDIR /path 为RUN CMD ENTRYPOINT指定配置工做目录,可使用多个WORKDIR指令,若后续指令用得是相对路径,则会基于以前的命令指定路径。 当最后指定workdir时,容器启动时运行在指定的workdir下。 好比,cmd 指定的指令要访问,同目录下的配置文件,就须要指定workdir,把相应的工做目录切换到workdir下。

相关文章
相关标签/搜索