Docker学习笔记(三):Dockerfile及多步骤构建镜像

官方文档地址:https://docs.docker.com/engine/reference/builder/
Dockerfile是一个文本格式的配置文件,其内容包含众多指令,用户可以使用它快速的创建自定义镜像。

部分指令列表 指令 作用 备注
FROM   指定基础镜像   任何Dockerfile中的第一条指令都必须是FROM
一个文件中可以存在多个FROM指令。
 
LABEL   为镜像添加元数据标签信息。    
ARG   定义创建镜像过程中使用的变量,编译成功后不存在。   在运行docker build时,指定--builder-arg为变量赋值。  
ENV   设置环境变量   在镜像启动时也会存在。
docker run --env key=value 会覆盖同名变量
 
WORKDIR   指定工作目录   可以使用多个,建议使用绝对路径。  
VOLUME   创建数据卷挂载点   例如VOLUME ["/data/a","/data/b"]  
EXPOSE   声明镜像内服务监听的端口   只起声明作用,不会自动完成映射。  
USER   指定运行容器时的用户名或ID   后续RUN指令也会以这个用户身份运行。  
STOPSIGNAL   指定所创建镜像启动的容器接收退出的信号值    
COPY/ADD

COPY src dst / ADD src dst
其相同点是:作用都是复制内容到镜像中;dst不存在时会创建;路径支持正则。
不同点在于:

ADD的src可以是相对于Dockerfile的相对路径;也可以是一个URL;还可以是一个tar文件(自动解压)。

COPY的src只能是文件或者目录。

除了目的明确是要将一个URL或者tar文件作为src的情况下,其他情况推荐使用COPY。

CMD/ENTRYPOINT 命令格式

exec方式: ["executable","param1","param2"](JSON数组,所以一定要是双引号)

shell方式: command param1 param2

CMD与ENTRYPOINT两种方式都支持,但推荐使用exec方式。

作用

在任意一个Dockerfile下:

只有最后一条CMD才会被执行。用来指定容器启动时默认执行的命令及参数。但是会被docker run命令行参数覆盖。

只有最后一条ENTRYPOINT才会被执行。用来配置容器启动时的执行命令。并且会将docker run的命令行参数或者CMD的所有参数追加在ENTRYPOINT指令后作为参数。运行时可以被--entrypoint参数覆盖。

伪代码 finallyCommand = "" if exists(ENTRYPOINT) { finallyCommand = ENTRYPOINT if exists(dockerRunCommandParam){ // 情景一 finallyCommand += dockerRunCommandParam }elseif exists(CMD) { // 情景二。除了CMD指令本身,包括后面JSON数组所有 finallyCommand += CMDParams } // 情景三 }elseif exists(dockerRunCommandParam){ // 情景四 finallyCommand = dockerRunCommandParams }elseif exists(CMD){ // 情景五 finallyCommand = CMD }

总结起来一句话:有ENTRYPOINT,CMD和docker run指定的命令都作为参数追加到ENTRYPOINT的参数后;没有ENTRYPOINT,docker run指定了命令就执行,否则执行CMD(如果有的话)。

实操

Dockerfile内容、构建镜像

FROM alpine:latest ENTRYPOINT ["/bin/echo","entrypoint"] -> [feifei@ffmac.local] [~/work/docker] docker build -t test . // 情景三 -> [feifei@ffmac.local] [~/work/docker] docker run --rm test entrypoint // 情景一 -> [feifei@ffmac.local] [~/work/docker] docker run --rm test 12 34 entrypoint 12 34

Dockerfile添加CMD指令、构建镜像

FROM alpine:latest ENTRYPOINT ["/bin/echo","entrypoint"] CMD ["/bin/echo","cmd"] -> [feifei@ffmac.local] [~/work/docker] docker build -t test . // 情景二:CMD中的 "/bin/echo" 没有被当做命令执行,而是与"cmd"一起成为了ENTRYPOINT的参数。 -> [feifei@ffmac.local] [~/work/docker] docker run --rm test entrypoint /bin/echo cmd

Dockerfile删除ENTRYPOINT指令、构建镜像

FROM alpine:latest CMD ["/bin/echo","cmd"] -> [feifei@ffmac.local] [~/work/docker] docker build -t test . // 情景五 -> [feifei@ffmac.local] [~/work/docker] docker run --rm test cmd // 情景四 -> [feifei@ffmac.local] [~/work/docker] docker run --rm test echo 33 33 RUN

exec方式:RUN ["executable","param1","param2"]
shell方式:RUN command param1 param2
每条RUN指令将在当前镜像基础上执行指令,并且提交为新的镜像层。当命令较长时可以使用\来换行

ONBUILD

ONBUILD [INSTRUCTION]
作为父镜像被使用时自动执行的命令。对孙子镜像无效。可用于自动编译,检查等。
假如父镜像ParentImage的Dockerfile中有如下指令:

ONBUILD RUN mkdir /root/test

使用docker build基于ParentImage创建子镜像ChildImage的时候,会先执行ParentImage中的ONBUILD指令。等价于在ChildImage中添加了:

RUN mkdir /root/test HEALTHCHECK

健康检查
HEALTHCHECK [OPTIONS] CMD command :根据执行命令返回值判断,0是成功,1是不健康。
HEALTHCHECK NONE :禁止健康检查
OPTIONS参数如下:

--interval=DURATION (default: 30s) 多长时间检查一次

--timeout=DURATION (default: 30s) 检查一次的超时时间

--start-period=DURATION (default: 0s) 开始阶段时长,此阶段内第一次成功之前的失败不计入retries。

--retries=N (default: 3) 确定最终失败的重试次数

构建镜像 docker build

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpwgpx.html