Dockerfile文件详解

avatar 2020年6月26日23:49:47 4 4,956 次浏览

首先,我们要了解dockerfile是做什么用的,为什么要学会使用dockerfile?Dockerfile中会使用到那些命令,在写dockerfile的时候需要注意哪些细节等等。如果不了解不要紧,下面带你慢慢学习dockerfile的使用和编写。

Dockerfile是一个加快镜像构建的一个文件,我们可以根据Dockerfile文件构建出我们自己定义的镜像

Dockerfile基本结构,一般分为:基础镜像,维护者信息,镜像操作指令和容器启动时执行指令,"#"为dockerfile中的注释。在dockerfile文件中我们需要了解几个常用的基本命令,分别是FROM、MAINTAINER、RUN、CMD、EXPOSE、ENV、ADD、COPY、ENTRYPOINT、VOLUME、USER、WORKDIR、ONBUILD等13个指令。

FROM系统基础

FROM是Dockerfile的第一个命令,这个命令关系到生成的镜像是什么版本,什么系统等等,看一下FROM命令涉及到的一下选项:

FROM <image>			 #系统,可以是centos也可以是ubuntu
FROM <image>:<tag>		 #系统:版本,默认不加版本就会选择的是最新版本

这里需要注意两个不能同时使用,比如写了两个FROM,一个指定的系统,一个指定的是系统:版本,这样重复了。我们可以根据自己的需求写一个基础的镜像系统以及版本:

FROM centos:7.2.1511

这是使用的Centos系统的7.2.1511版本,后面会把所有的Dockerfile命令总结一遍之后,我们使用我们创建好的Dockerfile命令构建一个自己的镜像。

MAINTAINER 维护者信息

MAINTAINER是用来描述dockerfile编辑作者的信息,或者内容大致信息,便于读者学习。例如:

MAINTAINER wolf27w@gmail.com
MAINTAINER this is docker

RUN 基础镜像命令

RUMN命令是我们在FROM的基础系统中需要做的一下操作,例如创建一个目录,或者下载安装一个工具等等,都需要使用RUN来完成,看下面的格式:

RUN linux命令

我们如果想在镜像中创建一个目录,或者安装一个nginx可以使用RUN,每执行一次就会在docker上新建一层,过多会导致镜像膨胀过大,所以可以使用&&进行连接,不过前提是执行的时候不出错。例如:

FROM centos
RUN mkdir /usr/local/python3
RUN mkdir /usr/local/python3/DevOps
RUN yum -y install gcc
可缩简为
RUN mkdir /usr/local/python3 \
    && mkdir /usr/local/python3/DevOps \
    && yum -y install gcc

这种创建文件是系统原本就有的命令,yum安装gcc不需要依赖其他的东西,所以这样的执行结果是没有问题的,build的镜像也不会出错。

ADD/COPY复制

从本地向制作的镜像中复制文件,ADD可以使用url,也可以复制tar文件,并会自动解压到目标路径中,COPY不能访问网络资源,也不会自动解压。

ADD <src>... <dest>
ADD ["<src>",... "<dest>"] 用于支持包含空格的路径
COPY [--chown=<user>:<group>] <源路径1>...  <目标路径>
COPY [--chown=<user>:<group>] ["<源路径1>",...  "<目标路径>"]

一般建议使用COPY复制,不过也要根据自己的环境,如果有tar文件可以使用ADD,不需要解压的可以使用COPY。

CMD命令

CMD命令是根据镜像创建的容器启动时,需要执行的命令,这个命令是在容器创建之后。一般用于执行项目,可以写到一个sh文件中,执行sh文件。格式如下:

CMD ["executable","param1","param2"] (执行可执行文件,优先)
CMD ["param1","param2"] (设置了ENTRYPOINT,则直接调用ENTRYPOINT添加参数)
CMD command param1 param2 (执行shell内部命令)

后面直接跟执行的语句,CMD和RUN的区别一个是在容器启动之前一个是容器启动之后。如果有多个CDM命令只执行最后一个。

ENTRYPOINT

ENTRYPOINT是容器启动后执行的命令,不会被docker run提供的参数覆盖,只能有一个ENTRYPOINT。但是如果docker run时使用了--entrypoint选项,此选项的参数可当作要运行的程序覆盖ENTRYPOINT。例如

FROM nginx
ENTRYPOINT ["nginx", "-c"] # 定参
CMD ["/etc/nginx/nginx.conf"] # 变参

如果不传参运行docker run nginx:test,在容器中会默认会启动nginx -c /etc/nginx/nginx.conf,如果传参运行

docker run  nginx:test -c /etc/nginx/new.conf

会把CMD中定义的参数覆盖掉,在容器中会执行的会是

nginx -c /etc/nginx/new.conf

ENTRYPOINT搭配CMD使用时一般时使用CMD给ENTRYPOINT传参。

ENV环境变量

ENV是给创建好的容器设置环境变量,设置好的环境变量可以被RUN使用。格式如下:

ENV <key> <value>  #<key>之后的所有内容均会被视为其<value>的组成部分,因此,一次只能设置一个变量
ENV <key>=<value> ...  #可以设置多个变量,每个变量为一个"<key>=<value>"的键值对,如果<key>中包含空格,可以使用\来进行转义,也可以通过""来进行标示;另外,反斜线也可以用于续行

ARG 环境变量

ARG和ENV都是设置环境变量,两者的区别是,ARG是对Dockerfile内有效,也就是在docker build的过程中有效,ENV是针对构建好容器的变量。格式:

ARG <参数名>[=<默认值>]

VOLUME挂载路径

VOLUME是定义匿名数据卷,在启动容器是忘记挂在数据卷,会自动挂载到匿名卷中,作用是避免数据丢失,或着因容器重启导致数据流失会使容器慢慢变大。格式:

VOLUME ["<路径1>", "<路径2>"...]
VOLUME <路径>

在容器启动时可以使用-v参数修改挂载点。

EXPOSE 端口

EXPOSE申明的仅仅是端口,在镜像服务中使用随机端口做映射,也就是docker run -P时,会自动随机映射EXPOSE的端口,格式:

EXPOSE <端口1> [<端口2>...]

WORKDIR 工作目录

只工作目录,用于WORKDIR指定的工作目录,会在构建镜像的每一层中都存在,WORKDIR的工作目录必须是创建好的,docker build构建镜像过程中,每一个RUN命令都是新建的一层,只有通过WORKDIR创建的目录才会一直存在。格式:

WORKDIR <工作目录路径>

USER 用户和组

用于指定后续执行命令的用户和用户组,这边只是切换后续命令执行的用户,用户名和用户组必须提前创建好。格式:

USER <用户名>[:<用户组>]

HEALTHCHECK 监控服务状态

HEALTHCHECK用来指定或指定来监控docker容器服务的运行状态,格式:

HEALTHCHECK [选项] CMD <命令>:设置检查容器健康状况的命令
HEALTHCHECK NONE:如果基础镜像有健康检查指令,使用这行可以屏蔽掉其健康检查指令

HEALTHCHECK [选项] CMD <命令> : 这边 CMD 后面跟随的命令使用,可以参考 CMD 的用法。

ONBUILD 延迟构建

ONBUILD用来延迟构建命令的执行,简单的说,就是在dockerfile里用ONBUILD指定的命令,在本次构建镜像的过程中不会执行(假设镜像为 test-build)。当有新的 Dockerfile 使用了之前构建的镜像 FROM test-build ,这是执行新镜像的 Dockerfile 构建时候,会执行 test-build 的 Dockerfile 里的 ONBUILD 指定的命令。格式:

ONBUILD <其它指令>

以上是dockerfile的所有命令,如有其他问题后期会补充回来,暂时就先写这么多吧。

avatar

发表评论取消回复

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

目前评论:4   其中:访客  2   博主  2

    • avatar sss 4

      不错

        • avatar 吴老二 Admin

          @sss 谢谢

        • avatar ss 4

          不错

            • avatar 吴老二 Admin

              @ss 谢谢