Dockerfile的应用

Posted dennyt

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Dockerfile的应用相关的知识,希望对你有一定的参考价值。

  英语好的同学可以去docker官网看dockerfile的官方文档,很详细:Dockerfile reference

  一、为什么要用Dockerfile

  其实在搭建完环境后,docker有一个命令可以直接将容器做成镜像:docker commit [OPTIONS] CONTAINERID [REPOSITORY[:TAG]]

很简单,就一条命令直接完成。为什么还要用Dockerfile来做镜像?Dockerfile的出现是有原因的。先讲一下这两种制作镜像的方法的区别:

  a.docker commit : ①需要在docker容器内操作,很麻烦,效率低;②搭好环境直接将容器做成镜像后,其他人使用这个镜像的时候,不知道这个镜像是怎么做出来的,都安装了什么,后面环境的继续搭建和维护很困难,如果不写说明文档,那么这个镜像基本上就只有作者自己知道怎么用了;③这个命令一般都使用在基础镜像的制作和镜像的发布上。

  b.docker build  . (Dockerfile) : ① 仅需编辑Dockerfile文件,不用进入容器内就可以配置环境,可读性比较强;②后续的升级和维护相对简单,可以直接在Dockerfile中更改并增加特性;③一般在团队,或者个人环境搭建中。

  具体选择哪种制作方式来制作镜像需要结合实际情况选择。

  二、Dockerfile的使用

  Docker通过读取Dockerfile文件,可以自动创建镜像。在大多数情况下,最好将Dockerfile单独放到一个文件夹中,一般包括Dockerfile文件、构建镜像所需要的文件、.dockerignore文件(里面存放构建镜像不需要的额文件)。Docker Daemon将一步步执行你的指令,创建成功后,将会输出新的镜像的ID;在Docker守护进程运行Dockerfile中的指令之前,它会对Dockerfile进行初步验证,如果语法不正确,则返回一个错误。

  指定一个私有仓库和tag,以保存构建成功后的镜像,多个-t可以上传多个仓库: docker build -t XXX/xxx .  

  指定路径的Dockerfile制作镜像:docker build -f /path/to/a/Dockerfile .;

   三、Dokerfile的命令

  命令不区分大小写,大写只是为了区分命令和变量。命令行和注释符(#)不能在同一行

  1.#syntax= [remote image reference]

  指定解析器 ,只能在第一行,否则不生效,如:    

# syntax=docker/dockerfile
# syntax=docker/dockerfile:1.0
# syntax=docker.io/docker/dockerfile:1
# syntax=docker/dockerfile:1.0.0-experimental
# syntax=example.com/user/repo:tag@sha256:abcdef...

 

  2.#escape= (backslash) / #escape=` (backslash)

  指定转义符号 ,通常在将转义字符设置为‘在Windows上特别有用,其中是目录路径分隔符。

  

  3..dockerignore 文件: 

# comment
*/temp*
*/*/temp*
temp?

 

规则 功能
# comment
注释被忽略。
*/temp*
排除名称以temp开头的文件和目录在根目录的任何直接子目录中。例如,排除了普通文件/somedir/temporary.txt,以及/somedir/temp目录。
*/*/temp*
从根目录下两层的任何子目录中排除以temp开头的文件和目录。例如,/somedir/subdir/temporary.txt被排除在外。
temp?
排除根目录中名称为temp的单字符扩展名的文件和目录。例如,排除/tempa和/tempb。

 

 

 

 

 

 

  

  4. FROM [--platform=<platform>] <image> [AS <name>] / FROM [--platform=<platform>] <image>[:<tag>] [AS <name>] FROM [--platform=<platform>] <image>[@<digest>] [AS <name>] 

  FROM指令初始化一个新的基础镜像。因此,一个有效的Dockerfile必须以FROM指令开始。镜像可以是任何镜像,公共基础镜像pull下来很容易。

  

  5.ENV 

FROM busybox
ENV foo /bar
WORKDIR ${foo}   # WORKDIR /bar
ADD . $foo       # ADD . /bar
COPY $foo /quux # COPY $foo /quux

 

  6.RUN <command> (shell form, the command is run in a shell, which by default is /bin/sh -c on Linux or cmd /S /C on Windows)

        RUN ["executable", "param1", "param2"] (exec form)

  exec form和shell form不同,exec form不调用命令shell,这就意味着不会发生正常的shell处理,如RUN ["echo", "$HOME"]不会对$HOME执行变量替换。如果想要shell处理,那么要么使用shell form,要么直接执行shell,例如:exec form运行["sh", "-c", "echo $HOME"]。RUN命令适用于在 docker build 构建docker镜像时执行的命令。

  注意“”的转义:RUN ["c:\windows\system32\tasklist.exe"]

 

  7. CMD ["executable","param1","param2"] (exec form, this is the preferred form)

        CMD ["param1","param2"] (as default parameters to ENTRYPOINT)

     CMD command param1 param2 (shell form)

     CMD的主要用途是为执行容器提供默认值。这些缺省值可以包括可执行文件,也可以省略可执行文件,在这种情况下,您还必须指定一个ENTRYPOINT。如果希望容器每次都运行相同的可执行文件,那么应该考虑将ENTRYPOINT与CMD结合使用。Dockerfile中的CMD命令最终可以被在执行 docker run命令时添加的命令所覆盖。

 

  8.ENTRYPOINT ["executable", "param1", "param2"] (exec form, preferred)

     ENTRYPOINT command param1 param2 (shell form)

     使用ENYRYPOINT,可以在运行容器的时候执行该命令。在将容器用作可执行文件时,应该定义ENTRYPOINT。在一个Dockerfile中只有最后一个ENTRYPOINT指令是有效的。CMD应该用作定义ENTRYPOINT命令的默认参数或在容器中执行特别命令的方法,当运行带有可选参数的容器时,CMD将被覆盖。

  这里推荐要使用exec form的格式,官方上说是这样运行容器,退出是彻底退出,而使用shell form是被迫退出。

 

  9.VOLUME ["/var/log/"]

          VOLUME /var/log

          VOLUME /var/log /var/db 

     宿主主机的文件挂载到指定容器的文件中,如果不指定宿主主机文件,Docker将自动创建一个匿名的volume,并将其挂载到cotainer的/var/log目录,匿名vilume在host机器上的目录路径类似:/var/lib/docker/volumes/300c2264cd0acfe862507eedf156eb61c197720f69e7e9a053c87c2182b2e7d8/_data

 

  10.USER <user>[:<group>] or USER <UID>[:<GID>]

            用来设置在Dockerfile中要使用的宿主主机的用户名或者UID

 

  11.WORKDIR /path/to/workdir

  在Dockerfile中声明工作路径,此目录如果不存在就会被自动创建,即使这个目录不被使用,接下来的操作都是基于这个路径工作的。可以在 docker run命令中用 -w参数覆盖掉WORKDIR指令的设置。

   

  12.ARG <name>[=<default value>]

  构建镜像时将命令行的参数值传递到Dockerfile文件中,如下Dockerfile文件:

1 FROM busybox
2 USER ${user:-some_user}
3 ARG user
4 USER $user

  构建镜像命令:$ docker build --build-arg user=what_user .

  此时Dockerfile的文件中USER的值为what_user。

 

  13.SHELL ["executable", "parameters"]

  指定shell的环境,例如:

FROM microsoft/windowsservercore

# Executed as cmd /S /C echo default
RUN echo default

# Executed as cmd /S /C powershell -command Write-Host default
RUN powershell -command Write-Host default

# Executed as powershell -command Write-Host hello
SHELL ["powershell", "-command"]
RUN Write-Host hello

# Executed as cmd /S /C echo hello
SHELL ["cmd", "/S", "/C"]
RUN echo hello

 

  14.HEALTHCHECK [OPTIONS] CMD command (check container health by running a command inside the container)

     HEALTHCHECK NONE (disable any healthcheck inherited from the base image)

  健康检查,例如,每隔5分钟左右检查一次,使web服务器能够在3秒钟内为站点的主页提供服务:

HEALTHCHECK --interval=5m --timeout=3s   CMD curl -f http://localhost/ || exit 1

 

  15.ONBUILD [INSTRUCTION]

  ONBUILD在此次镜像制作时不发挥作用,当这次做成的镜像被其他镜像当成基础镜像,是就会触发ONBUILD命令,但是这种ONBUILD命令不会被继承。例如:

[...]
ONBUILD ADD . /app/src
ONBUILD RUN /usr/local/bin/python-build --dir /app/src
[...]

 

  16.COPY [--chown=<user>:<group>] <src>... <dest>

   COPY [--chown=<user>:<group>] ["<src>",... "<dest>"](this form is required for paths containing whitespace)

  拷贝宿主主机的文件到镜像中

 

  17.ADD [--chown=<user>:<group>] <src>... <dest>

   ADD [--chown=<user>:<group>] ["<src>",... "<dest>"] (this form is required for paths containing whitespace)

  向镜像中拷贝文件,源文件可以是url链接文件

 

  18.EXPOSE <port> [<port>/<protocol>...]

  声明向外暴露的网络端口

 

  19.MAINTAINER <name>

  维护者信息

 

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

  向镜像中添加元数据,其实就是添加镜像的相关信息,只是以键值对的形式创建。

 

以上是关于Dockerfile的应用的主要内容,如果未能解决你的问题,请参考以下文章

Dockerfile - npm:未找到

Dockerfile的应用

无需 Dockerfile 的镜像构建:BuildPack vs Dockerfile

如何使用 Swift 使用此代码片段为 iOS 应用程序初始化 SDK?

Docker应用三:Dockerfile使用介绍

优化 .net core 应用的 dockerfile