前言

Docker可以通过读取Dockerfile中的指令来自动构建图像。Dockerfile是一个文本文档,包含用户可以在命令行上调用的所有命令来组装一个图像。使用docker构建用户可以创建一个自动构建,该构建可以连续执行多个命令行指令。

构建方法

# 这里的"."代表了目录结构上下文
docker build . # -f可以指定Dockerfile文件路劲,但是后面一定要用".",并且你当前的位置一定要在文件所要上传的目录位置
docker build -f /path/Dockerfile . # -t 指定构建后的镜像名称
docker build -t host-1 -f /path/Dockerfile . # --no-cache表示构建过程中的所产生的缓存不做保留
docker build --no-cache .

构建由Docker守护进程运行,而不是由CLI运行。构建流程要做的第一件事是将整个上下文(递归地)发送给守护进程。在大多数情况下,最好从一个空目录作为上下文开始,并将Dockerfile保存在该目录中。只添加构建Dockerfile所需的文件。要在构建上下文中使用文件,Dockerfile引用一条指令中指定的文件,例如一条复制指令。要提高构建的性能,可以通过在上下文目录中添加.dockerignore文件来排除文件和目录。有关如何创建.dockerignore文件的信息,请参阅此页上的文档。传统上,Dockerfile称为Dockerfile,位于上下文的根目录中。在docker build中使用-f标志指向文件系统中任何位置的Dockerfile。

指令详解

Dockerfile中的指令都会产生一个镜像层,哪怕你只是一个很小的声明也会产生一个镜像层。

ARG

ARG是docker.17版本之后出现的功能,是用来声明dockerfile所使用的变量,语法如下:

ARG <name>[=<default value>]

示例如下:

ARG VERSION=latest
FROM busybox:$VERSION
ARG VERSION
RUN echo $VERSION > image_version # 或者 FROM busybox
ARG user1=someuser
ARG buildno=1

注意:ARG变量定义从Dockerfile中定义它的行开始生效,而不是从命令行或其他地方使用参数开始。使用ENV指令定义的环境变量总是覆盖同名的ARG指令。

FROM

FROM指令初始化一个新的构建阶段,并为后续指令设置基本映像。因此,一个有效的Dockerfile必须从FROM指令开始。图像可以是任何有效的图像—从公共存储库中提取图像尤其容易。语法如下:

FROM <image> [AS <name>]
FROM <image>[:<tag>] [AS <name>]
FROM <image>[@<digest>] [AS <name>]

注意:FROM指令中有一个特殊镜像"scratch",表示使用空镜像,不依赖任何底层。

RUN

RUN指令将在当前映像之上的新层中执行任何命令并提交结果。生成的提交映像将用于Dockerfile中的下一步。RUN指令支持两种格式,样式如下:

RUN <command>
RUN ["executable", "param1", "param2"] 示例1
RUN /bin/bash -c 'source $HOME/.bashrc; \
echo $HOME' 示例2
RUN ["/bin/bash", "-c", "echo hello"]

注意:如果使用exec执行的这种方式,括号内的参数一定要用双引号括起来

CMD

CMD一般用于镜像构建之后预定默认运行的指令,类似于操作系统的开机自启动,因为容器中没有开机与关机这一说,所以只能设定预定运行程序;注意CMD是默认运行指令,言外之意它与其他指令冲突的时候,它不会运行。尤其是ENTRYPOINT;语法格式如下:

CMD ["executable","param1","param2"]
CMD ["param1","param2"]
CMD command param1 param2

需要注意:当镜像运行的时候,用户手动指定了程序,则CMD里面的内容会自动失效;若Dockerfile中有ENTRYPOINT指令,则CMD会将后面的内容当成参数传递到ENTRYPOINT指令中,就是上面的第二种使用方式。

详情请参考:https://blog.csdn.net/u010900754/article/details/78526443

LABEL

LABEL主要用来设置一些描述信息的标签,语法格式如下:

LABEL <key>=<value> <key>=<value> <key>=<value> ...

示例如下:

LABEL "com.example.vendor"="ACME Incorporated"
LABEL com.example.label-with-value="foo"
LABEL version="1.0"
LABEL description="This text illustrates \
that label-values can span multiple lines." LABEL multi.label1="value1" multi.label2="value2" other="value3" LABEL multi.label1="value1" \
multi.label2="value2" \
other="value3"

EXPOSE

  • EXPOSE指令通知Docker容器在运行时监听指定的网络端口。您可以指定端口监听TCP还是UDP,如果没有指定协议,则默认为TCP。
  • EXPOSE指令实际上并不发布端口。它作为构建映像的人员和运行容器的人员之间的一种文档类型,用于发布关于哪些端口的信息。要在运行容器时实际发布端口,请使用docker run上的-p标志发布和映射一个或多个端口,或者使用-p标志发布所有公开的端口并将它们映射到高阶端口。
  • EXPOSE默认情况下假定TCP。你也可以指定UDP:
# 语法
EXPOSE <port> [<port>/<protocol>...] # 示例
EXPOSE 80/udp
EXPOSE 80/udp

ENV

设定容器运行时的环境变量,语法如下:

ENV <key> <value>
ENV <key>=<value>

示例如下:

ENV myName="John Doe" myDog=Rex\ The\ Dog \
myCat=fluffy ENV myName John Doe
ENV myDog Rex The Dog
ENV myCat fluffy

ADD

ADD指令从复制新的文件、目录或远程文件url,并将它们添加到路径的映像文件系统中。可以指定多个资源,但是如果它们是文件或目录,它们的路径将被解释为相对于构建上下文的源。语法如下:

ADD [--chown=<user>:<group>] <src>... <dest>
ADD [--chown=<user>:<group>] ["<src>",... "<dest>"]

示例

ADD ["http://pic37.nipic.com/20140113/8800276_184927469000_2.png","/opt"]

注意:ADD添加文件到指定目录并解压,还可支持URL,但是URL仅支持web协议,不支持其他协议,例如:ftp传输协议

COPY

COPY指令从复制新的文件,并将它们添加到路径的映像文件系统中;COPY不会自动解压,不支持URL。语法如下:

COPY [--chown=<user>:<group>] <src>... <dest>
COPY [--chown=<user>:<group>] ["<src>",... "<dest>"]

ENTRYPOINT

ENTRYPOINT指定容器运行后必须运行的内容,ENTRYPOINT必须指定运行入口,同CMD类似,多条ENTRYPOINT只有最下面那条能够执行,语法如下:

ENTRYPOINT ["executable", "param1", "param2"]
ENTRYPOINT command param1 param2

注意:ENTRYPOINT的内容也是可以在docker run的时候进行覆盖,只需要使用--entrypoint选项即可

示例如下:

FROM debian:stable
RUN apt-get update && apt-get install -y --force-yes apache2
EXPOSE 80 443
VOLUME ["/var/www", "/var/log/apache2", "/etc/apache2"]
ENTRYPOINT ["/usr/sbin/apache2ctl", "-D", "FOREGROUND"] # 或者
FROM ubuntu
ENTRYPOINT exec top -b

VOLUME

VOLUME 指令可以在镜像中创建挂载点,将镜像中的内容挂载到本地,这样只要通过该镜像创建的容器都有了挂载点。但是通过 VOLUME 指令创建的挂载点,无法指定主机上对应的目录,是自动生成的。语法如下:

VOLUME ["/data"]

示例如下:

FROM ubuntu
RUN mkdir /myvol
RUN echo "hello world" > /myvol/greeting
VOLUME /myvol

USER

设定容器运行时的用户与用户组,当没有指定USER指令时,默认采用管理员用户,语法如下:

USER <user>[:<group>] or
USER <UID>[:<GID>]

WORKDIR

指定当前工作的工作目录,docker官方推荐使用的指令,不建议使用"RUN cd"这样的方式来进行目录的切换,语法如下:

WORKDIR /path/to/workdir

示例如下:

WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd

ONBUILD

  当我们在一个Dockerfile文件中加上ONBUILD指令,该指令对利用该Dockerfile构建镜像(比如为A镜像)不会产生实质性影响。但是当我们编写一个新的Dockerfile文件来基于A镜像构建一个镜像(比如为B镜像)时,这时构造A镜像的Dockerfile文件中的ONBUILD指令就生效了,在构建B镜像的过程中,首先会执行ONBUILD指令指定的指令,然后才会执行其它指令。需要注意的是,如果是再利用B镜像构造新的镜像时,那个ONBUILD指令就无效了,也就是说只能再构建子镜像中执行,对孙子镜像构建无效。其实想想是合理的,因为在构建子镜像中已经执行了,如果孙子镜像构建还要执行,相当于重复执行,这就有问题了。 语法如下:

ONBUILD [INSTRUCTION]

示例如下:

# 第一个Dockerfile
FROM ubuntu
MAINTAINER hello
ONBUILD RUN mkdir mydir # 第二个Dockerfile
FROM imagea
MAINTAINER hello1

STOPSIGNAL

设置容器优雅的退出进程与程序,这样可以保持数据的安全性与用户体验。语法如下:

STOPSIGNAL signal

示例:

STOPSIGNAL sigkill

信号参考大全:https://www.cnblogs.com/guge-94/p/11019605.html

信号退出原理:https://www.jb51.net/article/96617.htm

HEALTHCHECK

对容器运行的指定内容做健康检查,语法如下:

HEALTHCHECK [OPTIONS] CMD command
HEALTHCHECK NONE

选项讲解如下:

--interval=DURATION (default: 30s)
--timeout=DURATION (default: 30s)
--start-period=DURATION (default: 0s)
--retries=N (default: 3)
  1. interval:间隔(s秒、m分钟、h小时),从容器运行起来开始计时interval秒(或者分钟小时)进行第一次健康检查,随后每间隔interval秒进行一次健康检查;还有一种特例请看timeout解析。
  2. timeout:执行command需要时间,比如curl 一个地址,如果超过timeout秒则认为超时是错误的状态,此时每次健康检查的时间是timeout+interval秒
  3. retries:连续检查retries次,如果结果都是失败状态,则认为这个容器是unhealth的

示例如下:

HEALTHCHECK --interval=5m --timeout=3s CMD curl -f http://localhost/ || exit 1

参考地址:https://blog.csdn.net/tech_salon/article/details/77255915

SHELL

用于指定执行程序所使用的解释器,一般主要应用与Windows场景,因为linux一般都是用bash,语法如下:

SHELL ["executable", "parameters"]

示例如下:

FROM microsoft/windowsservercore

# Executed as cmd /S /C echo default
RUN echo default # Executed as cmd /S /C powershell -command Write-Host default
RUN powershell -command Write-Host default # Executed as powershell -command Write-Host hello
SHELL ["powershell", "-command"]
RUN Write-Host hello # Executed as cmd /S /C echo hello
SHELL ["cmd", "/S", "/C"]
RUN echo hello

Docker基础内容之镜像构建的更多相关文章

  1. Docker基础内容之镜像

    概念 镜像是一个包含程序运行必要依赖环境和代码的只读文件,它采用分层的文件系统,将每一次改变以读写层的形式增加到原来的只读文件上.镜像是容器运行的基石. 下图展示的是Docker镜像的系统结构.其中, ...

  2. docker基础内容讲解

    一.初识docker 1.1 LXC介绍 LXC为LinuX Container的简写.Linux Container容器是一种内核虚拟化技术,可以提供轻量级的虚拟化,以便隔离进程和资源,而且不需要提 ...

  3. Docker基础修炼2--Docker镜像原理及常用命令

    通过前文的讲解对Docker有了基本认识之后,我们开始进入实战操作,本文先演示Docker三要素之镜像原理和相关命令. 本文的演示环境仍然沿用上一篇文章在本地Centos7中安装的环境,如果你本地没有 ...

  4. Docker基础内容之命令大全

    run(未补全) 说明:创建一个新的容器并运行一个命令 语法如下: docker run [OPTIONS] IMAGE [COMMAND] [ARG...] 选项说明: -a stdin: 指定标准 ...

  5. docker的安装及基础操作与镜像构建

    仓库配置及安装启动 [root@localhost ~]# yum install -y yum-utils device-mapper-persistent-data lvm2 [root@loca ...

  6. Docker基础内容之数据持久化

    数据卷的特性 数据卷是一个可供一个或多个容器使用的特殊目录,它绕过 UFS 数据卷可以在容器之间共享和重用,相当于将一个分区挂载到多个目录下面 数据卷内容的修改会立马生效 数据卷的更新,不会影响镜像: ...

  7. Docker基础内容之仓库

    前言 Docker提供了开放的中央仓库dockerhub,同时也允许我们使用registry搭建本地私有仓库.搭建私有仓库有如下的优点: 节省网络带宽,提升Docker部署速度,不用每个镜像从Dock ...

  8. Docker基础内容之网络基础

    网络命名空间基本原理 单机版多容器实例网络交互原理 在宿主机上面打开两张网卡eth0与eth1,打通两张网卡的链路 在test1上面启动一个veth网卡,创建一个namespace:并桥接到eth0上 ...

  9. Docker基础内容之容器

    前言 容器是独立运行的一个或一组应用以及它们的运行态环境. 相关命令 启动容器相关命令 docker run 运行一个ubuntu14.04版本的容器,如果这个镜像本地不存在则会去默认仓库中下载 do ...

随机推荐

  1. EasyUI清空combotree下拉框图标

    代码: //清空combotree下拉框图标 $(".tree-icon,.tree-file").removeClass("tree-icon tree-file&qu ...

  2. 0016 CSS 背景:background

    目标 理解 背景的作用 css背景图片和插入图片的区别 应用 通过css背景属性,给页面元素添加背景样式 能设置不同的背景图片位置 [插入图片,不用设置img元素的父元素.自身元素大小,即可见,但是背 ...

  3. python获取网页信息的三种方法

    import urllib.request import http.cookiejar url = 'http://www.baidu.com/' # 方法一 print('方法一') req_one ...

  4. Mysql 最全查询语句

    基本查询语句及语法: select distinct from where group by having limit 一.单表查询 前期表与数据准备: # 创建一张部门表 create table ...

  5. QTableWiget的简单使用

    QTableWidget是QT程序中常用的显示数据表格的空间,很类似于VC.C#中的DataGrid.说到QTableWidget,就必须讲一下它跟QTabelView的区别了.QTableWidge ...

  6. CSS3(4)---动画(animation)

    CSS3(4)---动画(animation) 之前有写过过渡:CSS3(2)--- 过渡(transition) 个人理解两者不同点在于 过渡 只能指定属性的 开始值 与 结束值,然后在这两个属性值 ...

  7. js中this指向问题(call,apply,bind)

    call.apply.bind的作用是改变函数运行时this的指向. 如果你传的 context 就 null 或者 undefined,那么 window 对象就是默认的 context(严格模式下 ...

  8. Python for Data Analysis 学习心得(三) - 文件读写和数据预处理

    一.Pandas文件读写 pandas很核心的一个功能就是数据读取.导入,pandas支援大部分主流的数据储存格式,并在导入的时候可以做筛选.预处理.在读取数据时的选项有超过50个参数,可见panda ...

  9. 【Think In Java笔记】第1章 对象导论

    1. 对象导论 OOP 面向对象编程 C.Basic等语言所在的抽象仍要求在解决问题时基于计算机的解决,而不是基于所解决问题的结构来考虑. 要建立起问题空间的元素和解空间的对象之间一一映射的关系 万物 ...

  10. iOS多线程编程原理及实践

    摘要:iOS开发中,开发者不仅要做好iOS的内存管理,而且如果你的iOS涉及多线程,那你也必须了解iOS编程中对多线程的限制,iOS主线程的堆栈大小为1M,其它线程均为512KB,且这个限制开发者是无 ...