码迷,mamicode.com
首页 > 其他好文 > 详细

Dockerfile常用指令

时间:2021-06-28 20:12:04      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:运行命令   指定   wget   ash   from   用户   参数   data   进程   

1、镜像构建过程

包含Dockerfile目录的所有内容称为上下文,上下文通过docker build命令传入到Docker daemon后,便开始按照Dockerfile中的内容一层层构造镜像。

为了提高镜像构建的速度,Docker daemon会缓存构建过程中的中间镜像。当从一个已在缓存中的基础镜像开始构建新镜像时,会将Dockerfile中的下一条指令和基础镜像的所有子镜像做比较,如果有一个子镜像是由相同指令生成的,则命中缓存,直接使用该镜像(COPY/ADD指令还会比较文件内容),一旦缓存失效,则后续的指令都将生成新的镜像,不在使用缓存。

2、Dockerfile指令

ENV

为镜像创建出来的容器声明环境变量,还可以被dockerfile后面的指令使用。

ENV <key> <value>
ENV <key=value>

FROM

为后面的指令提供基础镜像,一个Dockerfile可以有多个FROM指令,这样会构建多个镜像。在每个镜像构建完成后,Docker命令行界面会输出该镜像的ID。

FROM <image>:<tag>

COPY

复制文件或目录添加到新镜像中。

COPY <src> <dest>

可以有多个,但必须是上下文根目录的相对路径,可以使用通配符。

可以是文件或目录(/结尾),但必须是目标镜像中的绝对路径或者相对于WORKDIR的相对路径。

ADD

和COPY一样,但可以是一个只想网络文件的URL

还可以只想本地的压缩归档文件,该文件复制到容器中时会被解压提取

RUN

在前一条命令创建的镜像基础上创建一个容器,并在容器中运行命令,命令结束后commit容器为新镜像,该镜像被Dockerfile中的下一条指令使用。

RUN <command> (shell格式)
RUN ["executable","param1","param2"] (exec格式,推荐)

shell格式,命令通过/bin/sh -c运行。

exec格式,命令直接运行,参数会被当成JSON数组被Docker解析,所以必须使用双引号,因为exec不会在shell中执行,所以环境变量的参数不会被替换。例如当执行 CMD ["echo","$HOME"]时候,$HOME不会做变量的替换,可以改写为 CMD ["sh","-c","echo","$HOME"]。

CMD

提供容器运行时的默认值,默认值可以是一条指令,可以是一些参数。

CMD <command> (shell格式)
CMD ["executable","param1","param2"] (exec格式,推荐)
CMD ["param1","param2"] (为ENTRYPOINT指令提供参数)

一个Dockerfile中可以有多条CMD指令,但只有最后一条有效。

CMD vs RUN

RUN指令在构建镜像时执行命令,并生成新的镜像;CMD指令在构建镜像时并不执行命令,而是在容器启动时默认将CMD指令作为第一条执行的命令。

如果用户在命令行界面运行docker run命令时指定了命令参数,则会覆盖CMD指令中的命令。

ENTRYPOINT

和CMD类似,让容器在每次启动时候执行相同的命令。

ENTRYPOINT <command> (shell格式)
ENTRYPOINT ["executable","param1","param2"] (exec格式,推荐)

一个Dockerfile中可以有多条ENTRYPOINT指令,但只有最后一条有效。

使用shell格式,ENTRYPOINT会忽略任何CMD指令和docker run命令参数,并且会运行在/bin/sh -c中,意味着该指令进程为/bin/sh -c的子进程,进程在容器中的PID不是1,且不能接受UNIX信号。即当使用docker stop 命令时,命令进程接收不到SIGTERM信号。

exec格式,docker run传入的参数会覆盖CMD指令的内容,但不会覆盖ENTRYPOINT

ONBUILD

添加一个将来执行的触发器指令到镜像中

3、实践心得

  • 使用标签

    docker build -t="image:v1"
    
  • 谨慎选择基础镜像

    尽量选择官方镜像,linux镜像大小关系:busybox < debian < centos < ubuntu

    构建镜像只安装使用必须的包。

    FORM指令应该包含参数tag

  • 充分利用缓存

    Docker daemon会顺序执行Dockerfile中的指令,为了有效利用缓存,尽量将所有Dockerfile文件中相同的部分都放到前面,不同的部分放到后面

  • 正确使用ADD和COPY指令

    首选COPY。

    当在Dockerfile中的不同部分需要用到不同文件时,不要一次性地将这些文件都添加到镜像中去,而是在需要时候逐个添加,这样也有利于充分利用缓存

    考虑镜像大小问题,使用ADD获取远程URL压缩包不是推荐做法,应该使用RUN wget或RUN curl代替。

  • RUN指令

    为了Dockerfile易读,使用比较长的RUN指令时可以使用\分隔多行。

    不要在一行中单独使用RUN apt-get update。当软件源更新后,会引起缓存问题,导致RUN apt-get install失败。应该改为:RUN apt-get updata && apt-get install。

    提交镜像是廉价的,不要害怕镜像的层数过多,因此,不要将所有命令写在一个RUN指令中。

  • 不要在Dockerfile中做端口映射

    使用EXPOSE指令会破坏Docker的可移植性

参考链接:

《Docker容器与容器云》

Dockerfile常用指令

标签:运行命令   指定   wget   ash   from   用户   参数   data   进程   

原文地址:https://www.cnblogs.com/yrxing/p/14941709.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!