热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Docker实战-编写Dockerfile

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

一、编译镜像

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 [: | @]
提示:镜像都是从一个基础镜像(操作系统或其他镜像)生成,可以在一个Dockerfile中添加多条FROM指令,一次生成多个镜像
注意:如果忽略tag选项,会使用latest镜像


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


指令:RUN
功能描述:
语法:RUN
          RUN [“executable”,”param1”,”param2”]
提示:RUN指令会生成容器,在容器中执行脚本,容器使用当前镜像,脚本指令完成后,Docker Daemon会将该容器提交为一个中间镜像,供后面的指令使用
补充:RUN指令第一种方式为shell方式,使用/bin/sh -c 运行脚本,可以在其中使用\将脚本分为多行
          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
提示:CMD第一种、第三种方式和RUN类似,第二种方式为ENTRYPOINT参数方式,为entrypoint提供参数列表
注意:Dockerfile中只能有一条CMD命令,如果写了多条则最后一条生效


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


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


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


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


指令:COPY
功能描述:复制文件到镜像中
语法:COPY |[“”,… “”]
提示:指令逻辑和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


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


指令:ARG
功能描述:设置编译变量
语法:ARG [=]
注意:ARG从定义它的地方开始生效而不是调用的地方,在ARG之前调用编译变量总为空,在编译镜像时,可以通过docker build –build-arg =设置变量,如果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的输出

推荐阅读
  • 深入理解 .NET 中的中间件
    中间件是插入到应用程序请求处理管道中的组件,用于处理传入的HTTP请求和响应。它在ASP.NET Core中扮演着至关重要的角色,能够灵活地扩展和自定义应用程序的行为。 ... [详细]
  • MySQL PMM:MyISAM 和 Aria 存储引擎的性能优化
    本文探讨了 MyISAM 和 Aria 存储引擎在 MySQL 中的关键性能指标,包括密钥缓冲区效率、页面缓存读写性能以及事务日志同步策略。通过优化这些参数,可以显著提升数据库的整体性能。 ... [详细]
  • 深入解析Spring启动过程
    本文详细介绍了Spring框架的启动流程,帮助开发者理解其内部机制。通过具体示例和代码片段,解释了Bean定义、工厂类、读取器以及条件评估等关键概念,使读者能够更全面地掌握Spring的初始化过程。 ... [详细]
  • 精选多款高效实用软件及工具推荐
    本文介绍并推荐多款高效实用的软件和工具,涵盖系统优化、网络加速、多媒体处理等多个领域,并提供安全可靠的下载途径。 ... [详细]
  • PHP 过滤器详解
    本文深入探讨了 PHP 中的过滤器机制,包括常见的 $_SERVER 变量、filter_has_var() 函数、filter_id() 函数、filter_input() 函数及其数组形式、filter_list() 函数以及 filter_var() 和其数组形式。同时,详细介绍了各种过滤器的用途和用法。 ... [详细]
  • Struts与Spring框架的集成指南
    本文详细介绍了如何将Struts和Spring两个流行的Java Web开发框架进行整合,涵盖从环境配置到代码实现的具体步骤。 ... [详细]
  • 本文详细介绍如何在Linux系统中配置SSH密钥对,以实现从一台主机到另一台主机的无密码登录。内容涵盖密钥对生成、公钥分发及权限设置等关键步骤。 ... [详细]
  • 探讨了如何解决Ajax请求响应时间过长的问题。本文分析了一个从服务器获取少量数据的Ajax请求,尽管服务器已经对JSON响应进行了缓存,但实际响应时间仍然不稳定。 ... [详细]
  • 深入解析Redis内存对象模型
    本文详细介绍了Redis内存对象模型的关键知识点,包括内存统计、内存分配、数据存储细节及优化策略。通过实际案例和专业分析,帮助读者全面理解Redis内存管理机制。 ... [详细]
  • 在成功安装和测试MySQL及Apache之后,接下来的步骤是安装PHP。为了确保安全性和配置的一致性,建议在安装PHP前先停止MySQL和Apache服务,并将MySQL集成到PHP中。 ... [详细]
  • 本文探讨了使用C#在SQL Server和Access数据库中批量插入多条数据的性能差异。通过具体代码示例,详细分析了两种数据库的执行效率,并提供了优化建议。 ... [详细]
  • Kubernetes 持久化存储与数据卷详解
    本文深入探讨 Kubernetes 中持久化存储的使用场景、PV/PVC/StorageClass 的基本操作及其实现原理,旨在帮助读者理解如何高效管理容器化应用的数据持久化需求。 ... [详细]
  • 在创建新的Android项目时,您可能会遇到aapt错误,提示无法打开libstdc++.so.6共享对象文件。本文将探讨该问题的原因及解决方案。 ... [详细]
  • 本文详细介绍了如何在PHP中使用serialize()和unserialize()函数,以及它们在数据传输和存储中的应用。 ... [详细]
  • 在使用STM32Cube进行定时器配置时,有时会遇到延时不准的问题。本文探讨了可能导致延时不准确的原因,并提供了解决方法和预防措施。 ... [详细]
author-avatar
儒雅的活在当下
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有