Docker:Dockfile制作容器详细介绍

目录

1、基于镜像【修改容器:  自定义容器】

2、基于Dockerfile

Dockerfile的语法格式

Dockerfile 指令和环境变量的应用

FROM 指令

MAINTANIER(depreacted)已经替换为LABEL

LABEL

COPY

ADD

WORKDIR

VOLUAM

EXPOSE

ENV

RUN

CMD

ENTRYPOINT

USER

HEALIHCHECK

SHELL

STOPSIGNAL [默认 15]

ARG [参数]

ONBUILD


有些镜像不能满足我们的生产环境的需要就需要自己来制作镜像;制作镜像有两种方式:

1、基于镜像【修改容器:  自定义容器】

缺点所有的配置都是写死的不能灵活配置【假设我们需要三个镜像:测试,开发,线上配置都是不相同,实现起来配置是很麻烦的,都需要重新制作】;

事实上docker在配置文件山解决方案是:

nginx这个镜像启动为容器后只做一件事情,配置一个虚拟主机,提供一个虚拟Server,它所服务主机名、家目录、监听的端口,文档根目录,在什么时候?由于配置的环境影响可能可不一样,当时它的配置文件格式是相同的,那么我们就可以走把配置文件生成类似于模板一样放在特定地方

Docker:Dockfile制作容器详细介绍

为了文件生成起来更加简单我们对内部增加接受变量,变量替换

server.conf   /etc/nginx/conf.d/
{
        server_name $NGX_SERVER_NAME;
        lister $NGX_IP:$NGINX_PORT;
        root $DOC_ROOT;

}

 在容器内部的主进程启动之前先启动别的程序,这个程序根据镜像中的文件,以及镜像启动时向容器传递的环境变量【参数】,这个程序把用户传进来的环境变量【参数】进行替换并保存在/etc/nginx/conf.d/ 下,保存完了由这个程序在启动主进程【由一个程序启动另一个程序,并替换当前进程:exec】;这种过程从某种意义来说更加复杂了,因为配置过程都是看不见的

 Docker:Dockfile制作容器详细介绍

 LInux的哲学思想用文本文件保存程序配置文件,用文本编辑器就可以做到配置所有的容器;在容器化的时候这种已经被颠覆了,不建议该配置文件,而是通过环境变量来配置文件

2、基于Dockerfile

Dockerfile是什么?其实是用来构建Docker镜像的源码【仅仅是一些文本指令】,调用一些命令生成一个image,所以从这个角度来说dockerfile就是一个纯文本文件里面包含了一些指令而已,在制作dockerfile中规定的所支持的命令【一二十个指令】堆叠起来

Dockerfile的语法格式

#:开头 注释
指令(大写:不区分大小写,但建议大写)+参数 一行一个指令
顺序执行指令,但是整个Dockerfile文件第一个非注释行,必须是From基于某个已存在的基础镜像来做

1、Dockerfile制作时:必须在某一个特定的目录,Dockerfile文件首字母必须大写;必须有Dockerflile文件;要打包镜像的文件打包好后必须放在该目录下;Dockrfile还支持隐藏文件【.dockeringore】在该文件中路径中,打包过程中都不包含该路径下的文件;

Dockerfile 指令和环境变量的应用

制作dockerfile文件命令是docker build;docker build制作的基础是基于底层镜像所提供给我们的命令

1、引用环境变量:$variable_name  或${variable_name}

2、引用环境变量:${variable: - word}:如果这个变量不存在或空,就引用是用word这个变量的值

3、引用环境变量:${variable: + word}:如果变量存在显示word,不存在显示空

FROM 指令

1、FROM指令是最重的一个且必须为Dockerfile文件开篇的第一个非注释行,用于为印象文件构建过程指定基准镜像,后续的指令运行于此基准镜像所提供的运行环境

2、事件中,基准镜像可以是任何可用镜像文件,默认情况下,docker build会在docker 主机上查找指定的镜像文件,在其不存在时,则会从Dockers Hub Registry上拉取所需的镜像文件【如果找不到指定的镜像文件,docker build会返回一个错误信息】

语法(Syntax)

  • FROM <repository> [:<tag>] 或 FROM <repository>@<digest>
  • <repositor>:指定作为base image 的名称
  • <tag>:base image的标签,为可选项,省略时默认为latest

MAINTANIER(depreacted)已经替换为LABEL

用于让Dockerfile制作者提供本人的详细信息

Dockerfile并不限制MAINTAINER指令可在出现的位置,但推荐将其放置于FROM指令之后

语法(Syntax)

  • MAINTAINER <author`s detail>
  • <author`s detail> 可是任何文本信息,但约定俗成地使用作者名称及邮件地址
  • MAINTAINER "amae <amae@wode.com>"

LABEL

语法(Syntax)

  • <key>=<value> <key>=<value> <key>=<value> <key>=<value>

COPY

用户从Docker主机复制文件至创建的新印象文件

语法(Syntax)

  • COPY <src>……<dest> 或["<src>","<src>",……"<dest>"]
  • <src>:要复制的源文件或目录,支持使用通配符
  • <dest>:目标路径,即正在创建的image的文件系统路径;建议为<dest>使用绝对路径,否则,COPY指定以WORKDIR为起始路径;
  • 注意:在路径中有空白字符时,通常使用第二种格式

文件复制准则

  • <src>必须时build上下文中的路径,不能是其父目录中的文件
  • 如果<src>,则其内部文件或子目录会被递归复制,但<src>目录自身不会复制
  • 如果指定了多个<src>,或在<src>中使用了通配符,则<src>必须时一个目录,且必须以/结尾
  • 如果<dest>事先不存在,它将会自动创建这包括其父目录路径

ADD

ADD指令类似于COPY指令,ADD支持使用tar文件和URL路径

语法(Syntax)

  • ADD <src> …… <dest>或ADD ["<src>","<src>" …… "<dest>"]

操作准则

  • 通COPY指令
  • 如果 <src> 为URL且 <dest> 不以 / 结尾,则<src> 指定的文件被下载并且被创建为<dest>;如果<dest> 以/ 结尾,则文件名URL指定的文件将被直接下载并保存为<dest>/<filename>
  • 如果<src>是一个本地系统上的压缩格式的tar文件,他将被展开为一个目录,其行为类似于"tar -x"命令;然而通过URL获取到的tar文件将不会自动展开
  • 如果<src>由多个,或期间或直接使用了通配符,则<dest>必须是一个以 / 结尾的目录路径;如果<dest> 不以 /结尾,则其被视作一个普通文件,<src> 的内容将被直接写入<dest>; 

WORKDIR

用于为Dockerfile中所有的RUN,CMD,ENTRYPOINT,COPY和ADD指定设定工作目录

语法(Syntax)

  • WORKDIR <dirpath>
  • 在Dockerfile文件中,WORKDIR指令可出现多次,其路径也可以为相对路径,不过,其实相对于此前一个WORKDIR指令指定的路径
  • 另外,WORKDIR也可调用由ENV指定定义的变量
  • 例如:
    • WORKDIR /var/log
    • WORKDIR $STATEPATH

VOLUAM

用于在image中创建一个挂载点目录,以挂载Docker host 上的卷或其他容器上的卷

语法(Syntax)

  • VOLUAM <mountpoint> 或 VOLUAM ["<mountpoint>"]
  • 如果挂载点目录路径下此前在文件存在,docker run命令会在卷挂载完成后将此前所有文件复制到新挂载的卷中

EXPOSE

用于为容器打开指定要监听的端口以实现与外部通信

语法(Syntax)

  • EXPOSE <port> [ /<protocol>] [<port>[/<protocol>]……]
  • <protocol> 用于指定传输层协议,可为TCP或UDP二者之一,默认是TCP协议
  • EXPOSE 11211/udp  11211/tcp

ENV

用于为镜像定义所需要的环境变量, 并可被Dockerfile文件中位于其后的其他指令(如:ENV,ADD,COPY等)所调用

调用格式为:$variable_name 或 ${variable_name}

语法(Syntax)

  • ENV <key><value> 或 ENV<key> == <value>
  • 第一种格式中,<key>之后所有的内容均会被视作其<value>的组成部分,因此一次只能设置一个变量
  • 第二种格式可用一次设置多个变量,每个变量为一个"<key>=<vaule>"的键值对,如果<vaule>中包含空格,可以用反斜线(\)进行转义,也可以通过对<vaule> 加引号进行标识;另外,反斜线也可用于徐行;
  • 定义多个变量时,建议使用第二个方式,以便于在同一层中完成所有功能

RUN

用于制动docker build过程中运行的程序,其可以是任何命令

语法(Syntax)

  • RUN <command> 或 RUN ["<executable>" , "<paraml>", "<param2>"]
  • 第一种格式中<command> 通常是一个shell命令,且以"/bin/sh -c" 来运行它,这意味着此进程在容器中的PID不为1,不能接受Unix信号,因此,当使用docker stop <container> 命令停止容器时,此进程接收不到SIGTERM信号
  • 第二种语法格式中的参数时一个json格式的数组,其中<exectable> 为要运行的命令,后面的<paramN> 为传递给命令的选项或参数,然而,此种格式指定的命令不会以 "/bin/sh -c" 来发起,因此常见的shell操作如变量替换以及通配符(?*等)替换将不会进行;不过,如果要运行的命令依赖于此shell的话,可以将其替换为下面的格式
    • RUN ["/bin/bash", "-c", "<exectable>", "<paraml>"]

CMD

类似于RUN指令,CMD指令也可用于运行任何命令或应用程序,不过,二者的运行时间点不同

  • RUN指令运行于应向文件构建过程中,而CMD指令运行于基于Dockerfile构建出的新的映像文件启动一个容器时
  • CMD指令的首要目的在于为启动的容器指定默认要运行的程序,且其运行结束后,容器也将终止;不过CMD指定的命令其可以被docker run的命令行选项所覆盖
  • 在Dockerfile中可以存在多个CMD指令,但仅最后一个会生效

语法(Syntax)

  • CMD <command> 或 CMD["<executable>","<paraml>","<param2>"] 或 CMD["<paraml>","<param2>"]
  • 前两种语法格式的意义通RUN
  • 第三种则用于为ENTRYPOINT指令提供默认参数

ENTRYPOINT

类似于CMD指令的功能,用于为容器指定默认运行程序,从而使得容器像是一个单独可执行程序

与CMD不同的是,由ENTRYPOINT启动的程序不会被Docker run命令行指定的参数所覆盖,而且,这些命令行参数会被当作参数传递给ENTRYPOINT 指定的程序【不过,docker run 命令的 -- entrypoint 选项的参数可以覆盖ENGTRYPOINT 指令指定的程序】

语法(Syntax)

  • ENTRYPOINT <command>
  • ENTRYPOINT ["<executable>", "<param1>", "<param2>"]
  • docker run 命令传入的命令参数会覆盖CMD指令的内容并且附加到ENTRYPOINT 命令最后为其参数使用
  • Dockerfile 文件种也可以存在多个ENTRYPOINT指令,但仅有最后一个会生效

USER

用于指定运行image时的或运行Dockerfile种任何RUN,CMD或ENTRYPOINT指令指定的程序时的用户或UID

默认情况下container的运行身份为root用户

语法(Syntax)

  • USER <UID> | <UserName>
  • 需要注意的是,<UID> 可以为任意数字,但实践中其必须是为/etc/passwd种某用户的有效UID,否则,docker run 命令将运行失败

HEALIHCHECK

检查主进程健康

语法(Syntax)

  • HEALTHCHECK [OPTIONS] CMD command
    • The OPTIONS that can appear befort CMD are:
    • -- interval=DURATION(default:30s)
    • -- timeout=DURATION (default: 30s)
    • --start-period=DURATION (default:0s)【等待主进程初始化配置时间】
    • --retries=N (default:3)【默认3次,都失败,就删除】
  • HEALHCHECK NONE
  • The command`s exit status indicates the health status of the container,The possibe values are:
    • 0:success -the container is healthy and ready for use
    • 1:unhealthy -the container is not woking correctly
    • 2:reserved -do not use the exit code
  • for example
    • HEALTHCHECK --interval=5m --timeout=3s \
    • CMD curl -f http://localhost || exit 1 【exit 1:退出码1】

SHELL

The Shell instruction allows the default shell used for the form of commands to be overridden

The default shell on Linux is ["/bin/sh", "-c"] , and on Windows is ["cmd", "/S", "/C"]

The SHELL instruction must be written in JSON form in a Dockfile 

  • Syntax: SHELL [ "exectable", "parameters"]
  • THE SHELL instruction cam appear multiple times
  • Each SHELL instruction overrides all previous SHELL instructions ,and affects all subsequent instructions

STOPSIGNAL [默认 15]

The STOPSIGNAL instruction sets the system call signal that will be sent to the container to exit

This signal can be a vaild unsigned unmber that matches a position in the kernel`s syscall tbale, for instance 9 or a signal name in the format SIGNAME for instance SIGKILL

Syntax: STOPSIGNAL signal

ARG [参数]

The ARG instruction defines a variable that users can pass at build-time to the builder with docker build command using the --build-arg <varname>=<value>  flag

if a user specifies a build argument that was not defined in the Dockerfile , the build outputs a warning

Syntax:ARG<name>=[=<default value>]

  • A Dockerfule may include one or one or more ARG instructions
  • An ARG instruction can optionally include a default value
    • ARG version=1.14
    • ARG user=zhang

ONBUILD

用于在Dockfile 种定义一个触发器

Dockerfile 用于build 映像文件,此映像文件亦可作为base image 被另一个Dockerfile用于FROM指令的参数,并以之构建新的映像文件

在后面的这个Dockfile种的FROM指令在build过程种被执行时,将会"触发"创建其base image的Dockfile 文件种的ONBUILD指令定义的触发器

Sytanx:

  • ONBUILD <INSTRUCTION>
  • 尽管任何指令都可以注册成为触发器指令,但ONBUILD不能自我嵌套,且不会触发FROM和MAINTAINER指令
  • 使用包含ONBUILD指令的Dockfile构建的镜像应该使用特殊的标签,例如:ruby:2.0-build
  • 在ONBUILD指令种使用ADD或COPY指令应格外小心,因为新构建过程的上下文在缺少指定的源文件时会失败

上一篇:C++ Adaptor 设计模式


下一篇:pip指令出现SyntaxError: invalid syntax解决方法