概述
docker file根据file当中的指令创建出一个新的容器,跟ansible中的role大致一样。
构建docker file时,必须有一个工作目录,而且这个目录中不要存在任何文件,除了docker file。docker file文件的名字必须叫docker file。
docker file中的每一条指令都会重新生成一个新的镜像层。
docker file由众多的指令组成,它的格式虽说不分大小写,但是约定俗成都使用大写。
FROM指令
使用哪个镜像,在新版中,它可以不放在第一条,但是老版本中,它必须放在头一条
语法:FROM <repository>[<tag>]
<repository>:指定镜像名称
tag:镜像标签
示例:
FROM centos:7
LABEL指令
用于给镜像打标签
语法:LABEL < key>=< value> < key>=< value> …
各个标签之间用空格隔开
COPY
用于从docker主机复制文件致创建的新映像文件
语法:COPY <src>…<dest>
src:要复制的源文件或目录
dest:目标路径,即正在创建image的文件路径系统,建议使用绝对路径,否则,copy指定则以WORKDIR为其起始路径。
注意:
src必须是build上下文中的路径,不能是父目录中的文件
如果src是目录,则内部的文件或子文件都会地柜复制,但是src目录本身不会复制
如果指定了多个src,或在src中使用了通配符,则dest必须是一个目录,且必须以/结尾
如果dest不存在,它会自动创建,这包括其父目录。
示例:
[root@localhost docker]# cat work_dir/Dockerfile
FROM busybox
COPY index.html /tmp/
COPY test1 /data/test1/
COPY a* /tmp/
ADD指令
ADD类似于COPY命令,但是支持tar文件和URL路径文件
语法: ADD <src> … <dest> 或ADD ["<src>",… “<dest>”]
如果src是url路径。dest不以/结尾,则src指定的文件将被直接下载并且改名为dest,如果dest以/结尾,则文件下载到dest目录下
如果src是一个tar文件,它将会直接解压成一个目录,但是通过URL制定下载的不会解压。
示例:
ADD nginx-1.19.0.tar.gz
/tmp/
ADD http://nginx.org/download/nginx-1.18.0.tar.gz
/tmp/
#ADD指令不支持https认证,如果想使用https下载,建议使用RUN指令
WORKDIR
用于为Dockerfile中所有的RUN,CMD,ENTRYPOINT ,COPY 和ADD指定工作目录
语法:WORKDIR <dirpath>
在dockerfile中WORKDIR指令可以出现多个,可以使用相对路径,但是相对路径是相对于上一个WORKDIR来说的。
示例:
WORKDIR /data/ydong
ADD nginx-1.19.0.tar.gz ./
WORKDIR html
# 它的父目录是/data/ydong,容器进入后的工作目录再/data/ydong/html
ADD index.html ./
VOLUME
用于在image中创建一个挂载点目录,以挂载docker hosts上的卷或者其它容器上的卷
语法:VOLUME <mountpoint> 或 VOLUME ["<mountpoint>"]
如果挂载点目录路径下有文件存在,那么在挂载之后,docker会将原有的文件先复制一份出来到新挂载点里,然后在隐藏原来目录路径下的文件。
示例:
VOLUME /ydong/test
#如果需要放在宿主机上挂载的话,运行时仍然需要-v选项指明宿主机上的目录路径
EXPOSE
用于为容器打开指定要监听的端口以实现与外部通信
语法: EXPOSE <port>[/<protocol>] [<port>[/<protocol>] …]
可以指定多个端口,如:EXPOSR 3306/tcp 61/udp
此种方式需要在命令行中使用-P选项,这种方式只能实现动态端口。
示例:
EXPOSE 80
ENV
用于镜像定义所需的环境变量,并可以在dockerfile调用是,是在build阶段中使用的。
调用变量的时候使用$variable_name 或者 ${variable_name}
语法: ENV <key> <value> 或 ENV <key>=<value>
使用第一种方法时,key只对应一个变量
第二种方法,可以一次设定多个变量,每个变量为key=value键值对,如果 中包含空格,可以以反斜线 ()进行转义,也可通过对 加引号进行标识;另外,反斜线也可用于续行
ENV docroot /ydong/data
ARG
在命令行中传递参数,然后替换dockerfile中的变量。 用法和env相似,是在docker新版当中才能使用。
示例:
ARG docroot=/ydong/data
RUN
用于指定docker build 过程中运行的程序,其可以是命令,但是必须是镜像中所支持的命令
语法: RUN <command> 或 RUN ["<executable>", “<param1>”, “<param2>”]
第一种格式中,命令通常是一个shell命令,并且以/bin/bash -c运行,这意味着此进程在容器的PID号不为1,不能接受UNIX信号,比如你如果要stop一个container的话,此进程是接受不到SIGTERM信号的
第二种语法格式中的参数是一个 JSON 格式的数组,其中 <executable>为要运行的命令,后面的 <paramN>为传递给命令的选项或参数;然而,此种格式指定的命令不会以为传递给命令的选项或参数;然而,此种格式指定的命令不会以“ /bin/sh -c” 来发起,因此常见的 shell 操作如变量替换以及通配符 (?,*等) ) 替换将不会进行;不过,如果要运行的命令依赖于此 shell特性的话,可以将其替换为类似下面的格式。特性的话,可以将其替换为类似下面的格式。
RUN ["/bin/bash", “-c”, “<executable>”, “<param1>”]
示例:
RUN
"/bin/bash" , "-c" , "touch a.txt"
CMD
和RUN命令类似,CMD指令也可用于运行任何命令或应用程序。RUN命令是在build镜像时运行的,而CMD是镜像文件运行成一个容器之后执行的。
CMD指令的首要目的在于为启动的容器指定默认要运行的程序,且其运行结束后,容器也将终止;不过, CMD 指定的命令其可以被 docker run 的命令行选项所覆盖
在 Dockerfile 中可以存在多个 CMD 指令,但仅最后一个会生效
语法:
CMD <command>
CMD [ “ <executable> ”, “<param1> ”, “ <param2> ”]
CMD ["<param1>","<param2>"]
前两种同RUN格式一样,最后一种格式是为ENTRYPOINT指令提供参数
示例:
CMD echo 123
#此种方式是以shell的子进程来运行,echo为shell的子进程。
CMD ["httpd" ,"-DGROUND"]
#此种方式是httpd为单独的进程来运行,如果要使用bash来解析的话,
可使用 CMD ["sh","-c" ,"httpd" ,"-DGROUND"]。
建议使用此种方式
使用第二种的方式是因为docker容器是以进程ID来判断存活的,PID为1的进程退出,则容器退出。 如果使用第一种方式的话,shell进程为PID1,服务的退出并不会影响容器的活动。
ENTRYPOINT
类似CMD指令的功能,用于容器指定默认运行程序,从而使得容器像是一个单独的可执行程序指令的功能
与 CMD 不同的是,由 ENTRYPOINT 启动的程序不会被 docker run命令行指定的参数所覆盖,而且,这些命令行参数会被当作参数传递给 ENTRYPOINT 指定指定的程序
docker run 命令的 --entrypoint 选项的参数可覆盖 ENTRYPOINT 指令指定的程序
语法:
ENTRYPOINT <command>
ENTRYPOINT ["<executable>", “<param1>”, “<param2>”]
示例:
CMD ["123"]
ENTRYPONIT ["echo"]
#这种方式会导致CMD当做ENTRYPOINT的参数来使用
ENTRYPOINT一般使用于脚本,CMD则当做它的参数传递。
示例:
[root@ydong amp]# cat Dockerfile
FROM centos:7
ARG doc_root="/var/www/html"
WORKDIR ${doc_root}
VOLUME /data/web/html
RUN yum install -y httpd
php php-mysql &&
yum install -y net-tools
&&
yum clean all
ADD app.sh /bin/
ADD index.html /data/web/html
CMD ["httpd","-DFOREGROUND"]
ENTRYPOINT ["/bin/app.sh"]
#此处ENTRYPOINT用来提供脚本,脚本内引用CMD传入的参数。
EXPOSE 80
HEALTHCHECK
docker容器的健康监测
语法:
HEALTHCHECK [options] CMD command
HEALTHCHECK NONE(禁用从基础镜像继承的任何健康检查)
OPTIONS参数
– interval:从容器运行开始计时interval(秒,分,时)进程第一次健康监测,此后每隔interval来进行一次健康监测。 默认值:30s
–start-period=DURATION:启动时间, 默认 0s, 如果指定这个参数, 则必须大于 0s ;–start-period 为需要启动的容器提供了初始化的时间段, 在这个时间段内如果检查失败, 则不会记录失败次数。 如果在启动时间内成功执行了健康检查, 则容器将被视为已经启动, 如果在启动时间内再次出现检查失败, 则会记录失败次数。
timeout:超时时长,设定超时多久为失败状态。默认值:30s
retries:重试次数,在重试指定的次数后,如果还是失败,则认为容器为unhealth状态 默认值:3
CMD后面可以接正常shell命令或exec数组
命令的退出状态可以显示出容器的状态,有以下数值
0:success,容器健康并且随时可用
1:unhealthy,容器不健康,无法工作
2:reserved,保留,不要使用此代码退出
示例:
[root@localhost docker_workfile]# cat Dockerfile
FROM centos:7
LABEL maintainer="ydong.com"
RUN yum install -y epel-release.noarch &&
yum install -y nginx
&&
yum install -y net-tools &&
yum install -y iproute &&
yum clean all
ADD index.html /data/web/html/
ADD app.conf /etc/nginx/conf.d/
ADD check.sh /tmp/
HEALTHCHECK --interval=3s --timeout=3s --retries=3 --start-period=2s CMD
/bin/bash /tmp/check.sh
#此处利用脚本来监测80端口是否启动,
[root@localhost docker_workfile]# cat check.sh
#!/bin/bash
ss -tnl | grep 80
if [ $? == 0 ]
then
exit 0
else
exit 1
fi
运行容器,第一次出现health:starting状态
[root@localhost docker_workfile]# docker ps -a
CONTAINER ID
IMAGE
COMMAND
CREATED
STATUS
PORTS
NAMES
5de15ae4cde7
nginx:v0.7
"nginx -g 'daemon of…"
9 seconds ago
Up 9 seconds (health: starting)
如果没有问题,则会变成health状态
[root@localhost docker_workfile]# docker ps -a
CONTAINER ID
IMAGE
COMMAND
CREATED
STATUS
PORTS
NAMES
cbb7e009a636
nginx:v0.7
"nginx -g 'daemon of…"
About a minute ago
Up About a minute (healthy)
web1
我们现在关掉nginx进程,看容器是否会出现unhealthy状态
[root@dfcc19c2bdaa /]# nginx
-s stop
[root@localhost docker_workfile]# docker ps -a
CONTAINER ID
IMAGE
COMMAND
CREATED
STATUS
PORTS
NAMES
dfcc19c2bdaa
nginx:v0.8
"/bin/bash"
About a minute ago
Up About a minute (unhealthy)
web1
最后
以上就是耍酷皮皮虾为你收集整理的docker file的全部内容,希望文章能够帮你解决docker file所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复