目录
MAINTANIER(depreacted)已经替换为LABEL
有些镜像不能满足我们的生产环境的需要就需要自己来制作镜像;制作镜像有两种方式:
1、基于镜像【修改容器: 自定义容器】
缺点所有的配置都是写死的不能灵活配置【假设我们需要三个镜像:测试,开发,线上配置都是不相同,实现起来配置是很麻烦的,都需要重新制作】;
事实上docker在配置文件山解决方案是:
nginx这个镜像启动为容器后只做一件事情,配置一个虚拟主机,提供一个虚拟Server,它所服务主机名、家目录、监听的端口,文档根目录,在什么时候?由于配置的环境影响可能可不一样,当时它的配置文件格式是相同的,那么我们就可以走把配置文件生成类似于模板一样放在特定地方
为了文件生成起来更加简单我们对内部增加接受变量,变量替换
server.conf /etc/nginx/conf.d/
{
server_name $NGX_SERVER_NAME;
lister $NGX_IP:$NGINX_PORT;
root $DOC_ROOT;
}
在容器内部的主进程启动之前先启动别的程序,这个程序根据镜像中的文件,以及镜像启动时向容器传递的环境变量【参数】,这个程序把用户传进来的环境变量【参数】进行替换并保存在/etc/nginx/conf.d/ 下,保存完了由这个程序在启动主进程【由一个程序启动另一个程序,并替换当前进程:exec】;这种过程从某种意义来说更加复杂了,因为配置过程都是看不见的
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指令应格外小心,因为新构建过程的上下文在缺少指定的源文件时会失败