Docker:实战操作--Dockerfile

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lzx_victory/article/details/80979944

Dockerfile可以用来自动构建镜像,极大方便了环境构建,如果熟悉前端的同学可以把它抽象为webpack,fis构建工具.那么Dockerfile只是一个配置文件里边包含了许多已经定义好的执行指令.

Docker build

构建命令如下:

sudo docker build -t test -f /test/Dockerfile /test/

指令的格式

#comment
INSTRUCTION arguments

.dockerignore

屏蔽规则:
*匹配任意字符, !包含该文件

例子:屏蔽md文件但是不屏蔽LICENCE.md

./*.md
!LICENCE.md 

指令集合

第一个必须的指令FROM

FROM 作为第一个必须的指令,需要指明构建的基础镜像.

FROM image
#或者
FROM image:tag

CMD,RUN与ENTRYPOINT指令

RUN

RUN 指令将会执行任意的命令在当前镜像之上会构建新的一层,并提交构建结果.

每次执行RUN命令都会生成一个提交,因此尽量确保RUN指令可以合并的尽量进行合并.

格式如下:

RUN ["executable", "param1", "param2"] #exec模式(首推的)
RUN <command> #shell模式:command可以直接是/bin/bash XX 

示例:

FROM ubuntu
RUN echo "This is a test." 
RUN ["/bin/bash", "echo ", "This is test"]

CMD

CMD主要是未执行的容器运行时提供一个默认运行的命令.可以配合ENTRYPOINT指令,为其提供参数.

格式

CMD ["executable","param1","param2"] #EXECFORM
CMD ["param1","param2"] #为ENTRYPOINT提供参数
CMD command param1 param2 #(shell模式)

示例:

FROM ubuntu
CMD echo "This is a test." 
CMD ["/bin/bash", "echo ", "This is test"]

ENTRyPOINT

在容器运行时提供命令
格式:

ENTRYPOINT command param1 param2
ENTRYPOINT ["executable", "param1", "param2"]

示例:

FROM ubuntu
CMD echo "This is a test." 
CMD ["This is test"]

注意事项

  • 在shell模式下解析需要注意$HOST变量的替换.例如:CMD [ "echo", "$HOME" ]不会被正确解析,但是CMD [ "sh", "-c", "echo", "$HOME" ] 这样就会正确解析变量,加入sh会正确处理.
  • CMD与ENTRYPOINT一起使用时,必须为exec模式

三者之间的差别

  • CMD:在容器运行时执行,并且可以为ENTRYPOINT提供参数,只可以执行一次,如果Dockerfile多次出现CMD会执行最后一个CMD指令.当命令行出现参数时,只有CMD命令会被替换掉.例:CMD echo "Hello world",命令行执行docker run -it <image> /bin/bash.

  • RUN:在构建时执行,可以多次执行但每次会构建一个镜像层,构建太多的层会影响效率.

  • ENTRYPOINT:官方文档说是为了配置docker容器,其实也是运行一个命令,但是不会被命令行当中的参数替换.如果需要构建容器后必须执行这条命令且不会被覆盖,那么可以使用ENTRPOINT.

LABEL

可以用LABEL指令添加为镜像源信息.没添加一个LABEL会为镜像添加一个新的层,因此不推荐使用太多LABEL.

LABEL <key>=<value> <key>=<value> <key>=<value> ...

ENV

ENV定义一些系统级别的变量,需要注意这个是持久存储的.

格式

ENV <key>=<value> ...

MAINTAINER

MAINtAINER指定镜像的维护的作者.

MAINTAINER CoderLiu 

EXPOSE

这个命令只是制定了那个端口会被容器监听,不会指定主机的端口映射,以及哪个端口被暴露到主机

格式:

EXPOSE <port> [<port>...]

ADD与COPY

ADD和COPY指令都可以讲当前构建的环境当中的目录或文件COPY到镜像当中去.
Dockerfile最佳实践文章指出:推荐使用COPY命令,它得执行可能更符合预期.

格式分别如下:

COPY <src>... <dest>
COPY ["<src>",... "<dest>"]

ADD <src>... <dest>
ADD ["<src>",... "<dest>"]

示例:

ADD ~/www/test/* /test
COPY ["/test*", "/test/"]

ADD与COPY差别

  • ADD支持src为URL
  • ADD 操作<src>如果是tar包,会被自动解压到src目录当中.

VOLUME

指定容器的挂载点可以直接挂载到容器的目录当中.

格式:

VOLUME ["/data"]

USER

USER指令设置运行镜像时的用户并且会让RUN,CMD与ENTRYPOINT执行都会使用该用户.

格式

USER test

WORKDIR

WORKDIR可以用于切换当前工作目录,RUN, CMD, ENTRYPOINT, COPY, ADD会根据这个命令操作的最终目录下,执行操作.
WORKDIR可以进行多次切换目录的操作.

格式:

WORKDIR /path/to/dir
WORKDIR /test
RUN pwd #输出/test

ONBUILD

ONBUILD指令是为了提供一个更好的构建方式,使用ONBUILD修饰的指令在构建基础镜像时不会被执行,但是在构建子镜像时候才会被执行,也就是在子镜像FROM引用父镜像后才会被执行.

格式

ONBUILD INSTRUCTION

示例:
基础镜像名称为testbase:

FROM ubuntu
ONBUILD COPY . /usr/src/app
ONBUILD RUN /usr/src/app/mybuild.sh

子镜像:

FROM testbase
#这时候ONBUILD才会被执行

构建注意事项

  • 构建镜像时,最好在一个空的目录或者只包含了必须文件,构建目录下需要包含Dockerfile文件.构建完成吼我们可以将镜像推送到Docker Hub.
  • 构建时需要注意当前构建的上下文,可以在运行docker build时用-f指定构建的Dockerfile以及构建的上下文的目录.-t指定构建的tag.
  • 构建时留意缓存,例如RUN apt-get updateRUN apt-get update && apt-install -y nginx 有很大差别,第一个apt-get update的执行结果会被缓存,第二个apt-get update不会生成新的缓存(RUN会单独生成一个镜像层).一般情况下推荐使用第二个RUN指令.
  • ADD与COPY操作的源文件会checksum,校验文件是否被修改,如果和缓存当中一致那么会使用缓存,否则会重新执行指令但是和atime,或者mtime没有关系.这与RUN的缓存机制不一样,只要RUN运行命令没有改变那么就可以读取缓存,不会根据命令结果进行校验.
  • 尽量在一个容器只运行一个进程,保持容器的横向扩展.依赖的容器可以通过网络连接起来.

猜你喜欢

转载自blog.csdn.net/lzx_victory/article/details/80979944