Docker 实战:编写 Dockerfile

一、编译镜像

 

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到教程。

 

1. 编译镜像

    Dockerfile类似于Makfile,用户使用docker build就可以编译镜像,使用该命令可以设置编译镜像时使用的CPU数量、内存大小、文件路径等

语法:docker build [OPTIONS] PATH| URL| - 
常见选项: 
          -t 设置镜像的名称和TAG,格式为name:tag 
          -f Dockerfile的名称,默认为PATH/Dockerfile 
例子:docker build -f ~/php.Dockerfile . 
注意:PATH是编译镜像使用的工作目录,Docker Daemon在编译开始时,会扫描PATH中的所有文件,可以在编译目录中加入.dockerignore过滤不需要的文件

    Docker Daemon从Dockerfile中顺序读取指令,生成一个临时容器,在容器中执行指令,容器编译成功后会提交作为镜像层加入最终镜像,为了加快编译过程,Docker Daemon采用了缓存机制,如果在缓存中找到了需要的中间镜像则直接使用该镜像而不生成临时容器(编译时可以使用选项–no-cache选择不使用缓存)

2. dockerignore文件

    编译开始前,Docker Daemon会读取编译目录中的.dockerignore文件,忽略其中的文件和目录,在其中可以使用通配符(?代表一个字符,*代表零个或任意个字符),使用通配符时,总会出现那么几个例外,这时可以使用!+文件名,Docker Daemon会读取!后面的文件

*/temp* 忽略PATH路径下一级子目录中以temp开头的文件和目录,如PAHT/A/temp.txt
*/*/temp* 忽略PATH路径下二级子目录中以temp开头的文件和目录,如PATH/A/B/temp.txt
*.md
!README.md 忽略所有md文件,除了README.md

二、Dockerfile指令详解

    Dockerfile由多条指令组成,每条指令在编译镜像时执行相应的程序完成某些功能,由指令+参数组成,以逗号分隔,#作为注释起始符,虽说指令不区分大小写,但是一般指令使用大些,参数使用小写

这里写图片描述

指令:FROM 
功能描述:设置基础镜像 
语法:FROM < image>[:< tag> | @< digest>] 
提示:镜像都是从一个基础镜像(操作系统或其他镜像)生成,可以在一个Dockerfile中添加多条FROM指令,一次生成多个镜像 
注意:如果忽略tag选项,会使用latest镜像


指令:MAINTAINER 
功能描述:设置镜像作者 
语法:MAINTAINER < name>


指令:RUN 
功能描述: 
语法:RUN < command> 
          RUN [“executable”,”param1”,”param2”] 
提示:RUN指令会生成容器,在容器中执行脚本,容器使用当前镜像,脚本指令完成后,Docker Daemon会将该容器提交为一个中间镜像,供后面的指令使用 
补充:RUN指令第一种方式为shell方式,使用/bin/sh -c < command>运行脚本,可以在其中使用\将脚本分为多行 
          RUN指令第二种方式为exec方式,镜像中没有/bin/sh或者要使用其他shell时使用该方式,其不会调用shell命令 
例子:RUN source $HOME/.bashrc;\ 
          echo $HOME

          RUN [“/bin/bash”,”-c”,”echo hello”]

          RUN [“sh”,”-c”,”echo”,”$HOME”] 使用第二种方式调用shell读取环境变量


指令:CMD 
功能描述:设置容器的启动命令 
语法:CMD [“executable”,”param1”,”param2”] 
          CMD [“param1”,”param2”] 
          CMD < command> 
提示:CMD第一种、第三种方式和RUN类似,第二种方式为ENTRYPOINT参数方式,为entrypoint提供参数列表 
注意:Dockerfile中只能有一条CMD命令,如果写了多条则最后一条生效


指令:LABEL 
功能描述:设置镜像的标签 
延伸:镜像标签可以通过docker inspect查看 
格式:LABEL < key>=< value> < key>=< value> … 
提示:不同标签之间通过空格隔开 
注意:每条指令都会生成一个镜像层,Docker中镜像最多只能有127层,如果超出Docker Daemon就会报错,如LABEL ..=.. <假装这里有个换行> LABEL ..=..合在一起用空格分隔就可以减少镜像层数量,同样,可以使用连接符\将脚本分为多行 
          镜像会继承基础镜像中的标签,如果存在同名标签则会覆盖


指令:EXPOSE 
功能描述:设置镜像暴露端口,记录容器启动时监听哪些端口 
语法:EXPOSE < port> < port> … 
延伸:镜像暴露端口可以通过docker inspect查看 
提示:容器启动时,Docker Daemon会扫描镜像中暴露的端口,如果加入-P参数,Docker Daemon会把镜像中所有暴露端口导出,并为每个暴露端口分配一个随机的主机端口(暴露端口是容器监听端口,主机端口为外部访问容器的端口) 
注意:EXPOSE只设置暴露端口并不导出端口,只有启动容器时使用-P/-p才导出端口,这个时候才能通过外部访问容器提供的服务


指令:ENV 
功能描述:设置镜像中的环境变量 
语法:ENV < key>=< value>…|< key> < value> 
注意:环境变量在整个编译周期都有效,第一种方式可设置多个环境变量,第二种方式只设置一个环境变量 
提示:通过${变量名}或者 $变量名使用变量,使用方式${变量名}时可以用${变量名:-default} ${变量名:+cover}设定默认值或者覆盖值 
          ENV设置的变量值在整个编译过程中总是保持不变的


指令:ADD 
功能描述:复制文件到镜像中 
语法:ADD < src>… < dest>|[“< src>”,… “< dest>”] 
注意:当路径中有空格时,需要使用第二种方式 
          当src为文件或目录时,Docker Daemon会从编译目录寻找这些文件或目录,而dest为镜像中的绝对路径或者相对于WORKDIR的路径 
提示:src为目录时,复制目录中所有内容,包括文件系统的元数据,但不包括目录本身 
          src为压缩文件,并且压缩方式为gzip,bzip2或xz时,指令会将其解压为目录 
          如果src为文件,则复制文件和元数据 
          如果dest不存在,指令会自动创建dest和缺失的上级目录


指令:COPY 
功能描述:复制文件到镜像中 
语法:COPY < src>… < dest>|[“< src>”,… “< dest>”] 
提示:指令逻辑和ADD十分相似,同样Docker Daemon会从编译目录寻找文件或目录,dest为镜像中的绝对路径或者相对于WORKDIR的路径


指令:ENTRYPOINT 
功能描述:设置容器的入口程序 
语法:ENTRYPOINT [“executable”,”param1”,”param2”] 
          ENTRYPOINT command param1 param2(shell方式) 
提示:入口程序是容器启动时执行的程序,docker run中最后的命令将作为参数传递给入口程序 
          入口程序有两种格式:exec、shell,其中shell使用/bin/sh -c运行入口程序,此时入口程序不能接收信号量 
          当Dockerfile有多条ENTRYPOINT时只有最后的ENTRYPOINT指令生效 
          如果使用脚本作为入口程序,需要保证脚本的最后一个程序能够接收信号量,可以在脚本最后使用exec或gosu启动传入脚本的命令 
注意:通过shell方式启动入口程序时,会忽略CMD指令和docker run中的参数 
          为了保证容器能够接受docker stop发送的信号量,需要通过exec启动程序;如果没有加入exec命令,则在启动容器时容器会出现两个进程,并且使用docker stop命令容器无法正常退出(无法接受SIGTERM信号),超时后docker stop发送SIGKILL,强制停止容器 
例子:FROM ubuntu <换行> ENTRYPOINT exec top -b


指令:VOLUME 
功能描述:设置容器的挂载点 
语法:VOLUME [“/data”] 
          VOLUME /data1 /data2 
提示:启动容器时,Docker Daemon会新建挂载点,并用镜像中的数据初始化挂载点,可以将主机目录或数据卷容器挂载到这些挂载点


指令:USER 
功能描述:设置RUN CMD ENTRYPOINT的用户名或UID 
语法:USER < name>


指令:WORKDIR 
功能描述:设置RUN CMD ENTRYPOINT ADD COPY指令的工作目录 
语法:WORKDIR < Path> 
提示:如果工作目录不存在,则Docker Daemon会自动创建 
          Dockerfile中多个地方都可以调用WORKDIR,如果后面跟的是相对位置,则会跟在上条WORKDIR指定路径后(如WORKDIR /A   WORKDIR B   WORKDIR C,最终路径为/A/B/C)


指令:ARG 
功能描述:设置编译变量 
语法:ARG < name>[=< defaultValue>] 
注意:ARG从定义它的地方开始生效而不是调用的地方,在ARG之前调用编译变量总为空,在编译镜像时,可以通过docker build –build-arg < var>=< value>设置变量,如果var没有通过ARG定义则Daemon会报错 
          可以使用ENV或ARG设置RUN使用的变量,如果同名则ENV定义的值会覆盖ARG定义的值,与ENV不同,ARG的变量值在编译过程中是可变的,会对比使用编译缓存造成影响(ARG值不同则编译过程也不同) 
例子:ARG CONT_IMAG_VER <换行> RUN echo $CONT_IMG_VER 
          ARG CONT_IMAG_VER <换行> RUN echo hello 
          当编译时给ARG变量赋值hello,则两个Dockerfile可以使用相同的中间镜像,如果不为hello,则不能使用同一个中间镜像


指令:ONBUILD 
功能描述:设置自径想的编译钩子指令 
语法:ONBUILD [INSTRUCTION] 
提示:从该镜像生成子镜像,在子镜像的编译过程中,首先会执行父镜像中的ONBUILD指令,所有编译指令都可以成为钩子指令


指令:STOPSIGNAL 
功能描述:设置容器退出时,Docker Daemon向容器发送的信号量 
语法:STOPSIGNAL signal 
提示:信号量可以是数字或者信号量的名字,如9或者SIGKILL,信号量的数字说明在Linux系统管理中有简单介绍


补充:ONBUILD流程

  • 编译时,读取所有ONBUILD镜像并记录下来,在当前编译过程中不执行指令
  • 生成镜像时将所有ONBUILD指令记录在镜像的配置文件OnBuild关键字中
  • 子镜像在执行FROM指令时会读取基础镜像中的ONBUILD指令并顺序执行,如果执行过程中失败则编译中断;当所有ONBUILD执行成功后开始执行子镜像中的指令
  • 子镜像不会继承基础镜像中的ONBUILD指令

补充:CMD ENTRYPOINT和RUN的区别

    RUN指令是设置编译镜像时执行的脚本和程序,镜像编译完成后,RUN指令的生命周期结束

    容器启动时,可以通过CMD和ENTRYPOINT设置启动项,其中CMD叫做容器默认启动命令,如果在docker run命令末尾添加command,则会替换镜像中CMD设置的启动程序;ENRTYPOINT叫做入口程序,不能被docker run命令末尾的command替换,而是将command当作字符串,传递给ENTRYPOINT作为参数

FROM ubuntu
ENTRYPOINT ["ps"]//通过命令docker run --rm test启动容器,打印ps的输出
//通过命令docker run --rm test -ef启动容器,打印ps -ef的输出

    在docker run中,可以通过–entrypoint替换镜像中的入口程序,在Dockerfile中,应该至少有一条CMD或者ENTRYPOINT指令,如果同时定义了CMD和ENTRYPOINT则CMD会作为参数传递给ENTRYPOINT

FROM ubuntu
ENTRYPOINT ["ps"]
CMD ["-ef"]//通过命令docker run --rm test启动容器,打印ps -ef的输出

 

 转自:https://blog.csdn.net/qq_29999343/article/details/78318397

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/448819.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

dubbo-环境搭建,实现一个简单地dubbo实例(附github地址)

一、建立maven模块和provider、consumer、service子模块&#xff0c;其中service是开发接口的模块 建立一个maven模块&#xff0c;不选择样板&#xff0c;直接next知道完成&#xff0c;建立三个子模块,建立完后发现各个模块的java目录不是源目录 右键——>make Directory as…

AMD 5XXX 系列显卡的 peak bandwidth计算

在ATI Stream Computing Programming Guide中&#xff0c;例举了AMD 5系列显卡的参数信息。 我比较关注其中Peak bandwidths的计算&#xff0c;以便在opencl程序测试bandwidth利用率。 下面&#xff0c;我以5870为例&#xff0c;探讨一下如何计算得到这些结果&#xff1a; L1 c…

OpenCL memory object 之 Global memory (1)

这篇日志是学习AMD OpenCL文档时候的总结。 OpenCL用memory object在host和device之间传输数据&#xff0c;memory object由runtime&#xff08;运行库&#xff0c;driver的一部分&#xff09;来管理。 OpenCL中的内存对象包括buffer以及image&#xff0c;buffer是一维数据元素…

OpenCL memory object 之 Global memory (2)

当我们用clCreateBuffer, clCreateImage创建OpenCL memory object时候&#xff0c;我们需要输入一个flag参数&#xff0c;这个参数决定memory object的位置。 cl_mem clCreateBuffer (cl_context context, cl_mem_flags flags, size_t size, void *host_ptr, cl_int *errc…

数据结构进阶篇-跳表

大家想必都知道&#xff0c;数组和链表的搜索操作的时间复杂度都是O(N)的&#xff0c;在数据量大的时候是非常耗时的。对于数组来说&#xff0c;我们可以先排序&#xff0c;然后使用二分搜索&#xff0c;就能够将时间复杂度降低到O(logN)&#xff0c;但是有序数组的插入是一个O…

查看本机ssh公钥,生成公钥

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 查看ssh公钥方法&#xff1a; 1.通过命令窗口&#xff1a;打开你的git bash 窗口&#xff0c;进入.ssh目录&#xff1a;cd ~/.ssh&…

如何实现动态水球图 --》 echars结合echarts-liquidfill实现

1&#xff09;项目中作为项目依赖&#xff0c;安装到项目当中(注意必须要结合echars) npm install echarts vue-echarts --save npm install echarts-liquidfill --save 2&#xff09;在需要使用水晶球的组件里引入liquidFill.js import echarts-liquidfill/src/liquidFill.js;…

RabbitMQ 从入门到精通 (一)

目录 1. 初识RabbitMQ2. AMQP3.RabbitMQ的极速入门4. Exchange(交换机)详解4.1 Direct Exchange4.2 Topic Exchange4.3 Fanout Exchange5. Message 消息1. 初识RabbitMQ RabbitMQ 是一个开源的消息代理和队列服务器&#xff0c;用来通过普通协议在完全不同的应用之间共享数据&a…

接收并解析消息体传参、解析 json 参数

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 1.场景&#xff1a;postman 发送了一个 post 请求&#xff0c;如下&#xff1a; 2. 解析方式为用一个 vo 对象来接收 json。把 json 中的…

OpenCL memory object 之 传输优化

首先我们了解一些优化时候的术语及其定义&#xff1a; 1、deferred allocation&#xff08;延迟分配&#xff09;&#xff0c; 在第一次使用memory object传输数据时&#xff0c;runtime才对memory object真正分配空间。 这样减少了资源浪费&#xff0c;但第一次使用时要慢一些…

VBS使文本框的光标位于所有字符后

有时候在文本框里会显示一部分提示信息&#xff0c;用户在这些提示信息后面输入文本&#xff0c;但是将焦点设置于文本框后&#xff0c;光标总是在文本框的最前面&#xff0c; 用户输入的时候需要按"-->"键将光标移到最后才能输入&#xff0c;这样的操作很不爽。我…

AMD OpenCL 大学课程

AMD OpenCL大学课程是非常好的入门级OpenCL教程&#xff0c;通过看教程中的PPT&#xff0c;我们能够很快的了解OpenCL机制以及编程方法。下载地址&#xff1a;http://developer.amd.com/zones/OpenCLZone/universities/Pages/default.aspx 教程中的英文很简单&#xff0c;我相信…

47.QT-QChart之曲线图,饼状图,条形图使用

1.使用准备 在pro中, 添加QT charts 然后在界面头文件中添加头文件并声明命名空间,添加: #include <QtCharts> QT_CHARTS_USE_NAMESPACE 2.QChart之曲线图 绘制曲线图需要用到3个类 QSplineSeries: 用于创建有由一系列数据组成的曲线.类似的还有QPieSeries(饼图数据). Q…

Docker 部署应用、jar 工程 docker 方式部署

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 1. 把要部署的工程打成一个jar包。&#xff08;我的工程叫 gentle &#xff09; 打 jar 的方法&#xff1a;超简单方法&#xff1a; Int…

第二阶段冲刺(2)

1、整个项目预期的任务量 &#xff08;任务量 所有工作的预期时间&#xff09;和 目前已经花的时间 &#xff08;所有记录的 ‘已经花费的时间’&#xff09;&#xff0c;还剩余的时间&#xff08;所有工作的 ‘剩余时间’&#xff09; &#xff1b; 所有工作的预期时间&#…

华为路由器配置DHCP中继

DHCP(动态主机配置协议)理论知识&#xff1a;DHCP主要用来为客户机自动配置I P地址相关的网络参数&#xff0c;包括IP地址、子网掩码、默认网关、DNS服务器等。 DHCP 通信为广播的方式&#xff0c;因此当需要 DHCP 服务器为不同广播域&#xff08;路由或 VLAN 网段&#xff09;…

基于GPU的K-Means聚类算法

聚类是信息检索、数据挖掘中的一类重要技术&#xff0c;是分析数据并从中发现有用信息的一种有效手段。它将数据对象分组成为多个类或簇&#xff0c;使得在同一个簇中的对象之间具有较高的相似度&#xff0c;而不同簇中的对象差别很大。作为统计学的一个分支和一种无监督的学习…

GPU通用计算调研报告

摘要&#xff1a;NVIDIA公司在1999年发布GeForce256时首先提出GPU&#xff08;图形处理器&#xff09;的概念&#xff0c;随后大量复杂的应用需求促使整个产业蓬勃发展至今。GPU在这十多年的演变过程中&#xff0c;我们看到GPU从最初帮助CPU分担几何吞吐量&#xff0c;到Shader…

git 图形化工具 GitKraken 的使用 —— 分支的创建与合并

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 分支管理是Git工作流的重点 在之前的文章中通过GitKraken可以很清楚的看到&#xff0c;每一次commit&#xff0c;git把他们串成了一条线…

GitKraken - 简单教程

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 简单介绍&#xff1a;外观 GitKraken首页预览图 常用快捷键 模糊搜索&#xff1a;(cmd p) 在进行模糊搜索的时候会在当前页面弹出一个…