Dockerfile语法解析

Dockfile介绍

从上到下依次执行 每次执行一条指令就创建一个镜像层

第一条指令必须是FROM    表示需要构建的镜像是由哪个镜像为基础镜像   后续的指令运行于此基准镜像所提供的运行环境

可以设置 .dockeringore 指定不打包进镜像的文件列表

在docker build中执行的shell命令环境是由基础镜像所包含的命令集合

${ varriable:-default }  如果变量未设置值,则给变量赋一个默认值   ${ variable: +default } 如果已经给变量设置过值,则用default代替变量的值

COPY指令

从dockerfile的工作目录中 复制指定文件到目标镜像的文件系统中

COPY <src> ... <dest>

COPY ["<src>",... "<dest>"]

<dest>:目标路径,即正在创建的image的文件系统路径;建议为<dest>使用绝对路径   否则,COPY指定则以WORKDIR为其起始路径.

注意:  在路径中有空白字符时,通常使用第二种格式

复制规则:

src的路径不能是当前工作目录之上的目录或者文件 只能是工作目录中的文件或者子目录

如果<src>是目录,则其内部文件或子目录会被递归复制,但<src>目录自身不会被复制  相当于shell中的 cp  -r  /root/dir/*    /tmp

如果指定了多个<src>或在<src>中使用了通配符  则<dest>必须是一个目录,且必须以/结尾

如果<dest>事先不存在,它将会被自动创建,这包括其父目录路径

ADD指令

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

如果<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指定设定工作目录

在Dockerfile文件中,WORKDIR指令可出现多次,其路径也可以为相对路径,不过 ,其是相对此前一个WORKDIR指令指定的路径

另外 WORKDIR也可调用由ENV指定定义的变量

VOLUME指令

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

VOLUME <mountpoint> 或   VOLUME ["<mountpoint>"]

如果挂载点目录路径下此前在文件存在,  docker run命令会在卷挂载完成后将此前的所有文件复制到新挂载的卷中

不能指定宿主机上面的目录路径  只能创建docker manage volume

EXPOSE指令

用于为容器打开指定要监听的端口以实现与外部通信   动态绑定到宿主机的随机端口  不能指定宿主机上的端口

EXPOSE <port>[/<protocol>] [<port>[/<protocol>] ...]   EXPOSE指令可一次指定多个端口  EXPOSE 11211/udp 11211/tcp

EXPOSE 只是表示当前镜像在运行为容器的时候可以暴露指定的端口,但是需要在run的时候配合 -P 选项 否则即使在Dockerfile中

通过EXPOSE指定的端口在容器运行的时候默认还是不会被暴露的   EXPOSE 一定需要配合 -P 选项 才能发挥作用

ENV指令

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

ENV <key> <value>

ENV <key>=<value> ...

第二种格式可用一次设置多个变量,每个变量为一个"<key>=<value>"的 键值对.如果<value>中包含空格,可以以反斜线(\)进行转义,也可通过对<value>加引号进行标识.另外,反斜线也可用于续行

在docker run的时候可以通过 -e 选项直接覆盖Dockerfile文件中已经指定的ENV或者添加为容器新的ENV变量的

RUN指令

用于指定docker build过程中运行的程序      其可以是任何命令  但是需要基础镜像的shell环境的支持

可以出现多次RUN指令

RUN <command>       以shell的子进程运行

<command>通常是一个shell命令,且以“/bin/sh -c”来运行它, 这意味着此进程在容器中的PID不为1,不能接收Unix信号.因此,当使用 docker stop <container>命令停止容器时,此进程接收不到SIGTERM信号;能够接收信号的进程一般是进程号为1的进程.

RUN ["<executable>", "<param1>", "<param2>"]      直接由内核创建运行进程 可处理系统发送过来的信号 无法调用shell中的变量

参数是一个JSON格式的数组,其中<executable>为要运行的 命令,后面的<paramN>为传递给命令的选项或参数;然而,此种格式指定的命令不会以“/bin/sh -c”来发起,因此常见的shell操作如变量替换以及通配符(?,* 等)替换将不会进行;不过,如果要运行的命令依赖于此shell特性的话,可以将其替换为类似下面的格式

RUN ["/bin/bash", "-c", "<executable>", "<param1>"]

CMD指令

CMD指令的首要目的在于为启动的容器指定默认要运行的程序,且其运行结束后,容器也将终止. 不过CMD指定的命令其可以被docker run的命令行选项所覆盖

CMD命令的执行时间周期 就是容器的生命周期 CMD一旦执行完毕  容器就会立即停止  CMD指令只有最后一个指令生效

CMD指令一般不会单独使用  通常都需要配合 ENTRYPOINT指令来设置

CMD <command>

CMD [“<executable>”, “<param1>”, “<param2>”]

CMD ["<param1>","<param2>"]  为ENTRYPOINT指令提供默认参数

当执行docker run的时候可以在最后添加自定义命令来覆盖CMD中指定的命令

ENTRYPOINT指令

主要用来指定shell的  把shell作为容器中第一个启动进程 通过接收CMD命令 把命令作为参数启动指定的子进程

用来指定容器内核启动的第一个进程 只有PID为1的进程才能接收系统发送给容器的系统信号

由ENTRYPOINT启动的程序不会被docker run命 令行指定的参数所覆盖.而且,这些命令行参数会被当作参数传递给ENTRYPOINT指定指定的程序

不过,docker run命令的--entrypoint选项的参数可覆盖ENTRYPOINT指令指定的程序

docker run命令传入的命令参数会覆盖CMD指令的内容并且附加到 ENTRYPOINT命令最后做为其参数使用

一个容器只是为了运行单个程序

每个进程都应该是某个进程的子进程 除了init进程

在shell中启动的任何进程都是shell的子进程 意味着如果shell退出那么在shell中启动的进程都会被终止掉

     一个运行nginx的容器中nginx进程号必须为1 否则由于容器中的nginx进程无法接收系统信号而无法stop和kill掉正在运行的容器

exec 顶替shell进程PID为1 shell进程退出

USER指令

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

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

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

ONBUILD指令

用于在Dockerfile中定义一个触发器

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

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

HEALTHCHECK指令

docker引擎判定容器是否健康的机制是仅仅判定容器是否处于运行状态

判定运行的容器是否正常运行 并不能单一的检测容器是否正在运行 需要更加具体化 需要检测容器中的主进程是否能正常提供服务才行

需要借助外部命令检测 如检测nginx容器是否正常  可以使用命令请求主页 wget -O - -q a1f2903f6de3 获取返回结果 进行健康检查

ARG指令

使用方法和ENV相同 但是只能在docker build执行指令的时候生效 不能在docker run中生效 ENV在两个执行阶段都有效果

使用ARG指令可以用同一个Dockerfile 通过ARG的方式生成不同版本的镜像   相当于给docker build命令传递变量参数

Dockerfile实例

[[email protected] mynginx]# ls
Dockerfile  entrypoint.sh  index.html

[[email protected]-docker mynginx]# vi Dockerfile 

FROM nginx:1.14-alpine
LABEL maintainer="yxh"

RUN mkdir -p /data/web/html
ENV NGX_DOC_ROOT=‘/data/web/html/‘
ADD entrypoint.sh /bin
ADD index.html ${NGX_DOC_ROOT}

EXPOSE 80 8080
CMD ["/usr/sbin/nginx","-g","daemon off;"]
ENTRYPOINT ["/bin/entrypoint.sh"]

[[email protected]-docker mynginx]# vi entrypoint.sh 

#!/bin/sh

cat > /etc/nginx/conf.d/www.conf << EOF
server
{
   server_name $HOSTNAME;
   listen ${IP:-0.0.0.0}:${PORT:-80};
   root $NGX_DOC_ROOT;
}
EOF

exec "[email protected]"

######调试容器##########
[[email protected]-docker mynginx]# docker run --name nginx1 -it nginx:1.14-alpine

nginx1默认启动的不是/bin/sh 所以即使使用-it 选项也无法进入容器
[[email protected]-docker mynginx]# docker run --name nginx1 -it nginx:1.14-alpine /bin/sh
/ # ifconfig
如果要进入交互式容器需要在最后添加启动命令 /bin/sh来覆盖CMD命令
这样就可以进入容器
/ # ps aux
PID   USER     TIME   COMMAND
    1 root       0:00 /bin/sh
    6 root       0:00 ps aux

调试容器步骤 无论什么容器都可以采取这种方式
  docker run --name myweb1 --rm -it myweb:v0.1-1 /bin/sh
  docker exec -it  myweb1 /bin/sh 进入已经运行的容器 

/usr/sbin # netstat -tnl
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN

/data # wget -O - -q a1f2903f6de3
<h1> my nginx index page </h1>
/data #

有环境变量的最大好处在docker run的时候可以直接根据变量生成各种
应用程序的配置文件
定义应用程序的配置文件的时候就只需要调用变量名称即可
docker run -e "HOSTNAME=yxh" --name yxhweb myweb2:v1.1

/ # vi /etc/hosts
/ # wget -O - -q  yxh
<h1> my nginx index page </h1>

Dockerfile实例

原文地址:https://www.cnblogs.com/yxh168/p/9419235.html

时间: 2024-10-09 16:02:35

Dockerfile语法解析的相关文章

Atitit.sql&#160;ast&#160;表达式&#160;语法树&#160;语法&#160;解析原理与实现&#160;java&#160;php&#160;c#.net&#160;js&#160;python

Atitit.sql ast 表达式 语法树 语法 解析原理与实现 java php c#.net js python 1.1. Sql语法树 ast 如下图锁死1 2. SQL语句解析的思路和过程3 2.1. lexer作为一个工具,完成了对SQL字符串的切割,将语句转化成一个tokens数组.3 2.2. Parser完成了SQL解析的后序部分:使用一个lexer对象作为工具,切出tokens,然后解析语义,绑定相关的系统接口.3 2.3. 关系数据和XML数据库下其抽象语法树分别为: 如图

Mysql Join语法解析与性能分析详解

一.Join语法概述 join 用于多表中字段之间的联系,语法如下: ... FROM table1 INNER|LEFT|RIGHT JOIN table2 ON conditiona table1:左表:table2:右表. JOIN 按照功能大致分为如下三类: INNER JOIN(内连接,或等值连接):取得两个表中存在连接匹配关系的记录. LEFT JOIN(左连接):取得左表(table1)完全记录,即是右表(table2)并无对应匹配记录. RIGHT JOIN(右连接):与 LEF

工作中的那些坑(2)——语法解析器

工作项目里用到线性回归算法,用于计算账户的分值,表明某账户是否是有风险的账户.其中参数都配好了,代码里直接用逆波兰表达式解析即可.本来事情到这里已经结束,突然来了新的需求:账户算出来的分数较为无序,于是考虑用sigmoid函数将其映射到(0,1)区间内,在乘以系数使其显示更为直观.为了使整个表达式更将通用,要求做到同时能解析sigmoid函数,即:原来单纯解析常量.变量.运算符的逆波兰表达式已经不能直接解析新增的sigmoid函数(即表达式),另外对嵌套的情况也没做处理,所以需要重新设计一个更为

nsis安装包_示例脚本语法解析

以下是代码及解析,其中有底色的部分为脚本内容. 注释.!define.变量.!include.常量 ; Script generated by the HM NIS Edit Script Wizard. ; HM NIS Edit Wizard helper defines !define PRODUCT_NAME "signjing安装示例" !define PRODUCT_VERSION "0.0.0.1" !define PRODUCT_PUBLISHER

MYSQL 源代码 编译原理 AST和解析树 代码语法解析

MYSQL 源代码 编译原理 AST和解析树 代码语法解析 http://blog.csdn.net/wfp458113181wfp/article/details/17082355 使用AST树 分类:             antlr              2013-12-02 22:39     255人阅读     评论(0)     收藏     举报 目录(?)[+] 第五章使用AST树中间结果来计算表达式值 创建ASTS 第五章.使用AST树中间结果来计算表达式值 现在我们已

With语句以及@contextmanager的语法解析

with 语句以及@contextmanager的语法解析 ? with语句可以通过很简单的方式来替try/finally语句. with语句中EXPR部分必须是一个包含__enter__()和__exit__()方法的对象,也就是Context Manager.使用with语句的目的: 提供可靠的资源自动释放,在with代码执行前请求资源,代码运行结束后资源会释放. 简化代码,代码可读性以及逻辑的简明都会提高很多. 创造临时的上下文环境,例如做一个临时的网络请求并获取返回值作为上下文环境. 通

Android.mk语法解析

Android.mk文件相当于是从Makefile文件中截取的小片段,非常非常的小!可被系统解析一次或者多次!应该尽量少的声明 该文件的一个很重要的组成部分就是模块 1.    - a static library   静态库 2.    - a shared library   动态库 只需要将动态库安装/拷贝到你的应用程序包即可,静态库是用来生成动态库的 你可以定义一个或多个模块,而且同一source file你可以放到多个模块中 编译之前还有一些细节要注意,比如:不需要将头文件或者一些依赖

oceanbase中存储过程的实现(一)语法解析部分

原创性声明 本文出处为http://blog.csdn.net/zhujunxxxxx/article/details/39251491,版权归作者所有,如需转载请注明作者,出处! 技术背景 淘宝的开源数据库oceanbase 是一个支持海量数据的高性能分布式数据库系统,实现了数千亿条记录.数百TB数据上的跨行跨表事务,由淘宝核心系统研发部开发的. 但是现在oceanbase0.4版本是不支持很多功能的,其中包括存储过程. 开发方案 淘宝数据使用的是flex&bison来进行sql语句的解析的,

NLP | 自然语言处理 - 语法解析(Parsing, and Context-Free Grammars)

什么是语法解析? 在自然语言学习过程中,每个人一定都学过语法,例如句子可以用主语.谓语.宾语来表示.在自然语言的处理过程中,有许多应用场景都需要考虑句子的语法,因此研究语法解析变得非常重要. 语法解析有两个主要的问题,其一是句子语法在计算机中的表达与存储方法,以及语料数据集:其二是语法解析的算法. 对于第一个问题,我们可以用树状结构图来表示,如下图所示,S表示句子:NP.VP.PP是名词.动词.介词短语(短语级别):N.V.P分别是名词.动词.介词. 实际存储的时候上述的树可以表示为(S (NP