前言

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. 图解Go里面的互斥锁mutex了解编程语言核心实现源码

    1. 锁的基础概念 1.1 CAS与轮询 1.1.1 cas实现锁 在锁的实现中现在越来越多的采用CAS来进行,通过利用处理器的CAS指令来实现对给定变量的值交换来进行锁的获取 1.1.2 轮询锁 在 ...

  2. MySQL基础篇(03):系统和自定义函数总结,触发器使用详解

    本文源码:GitHub·点这里 || GitEE·点这里 一.系统封装函数 MySQL 有很多内置的函数,可以快速解决开发中的一些业务需求,大概包括流程控制函数,数值型函数.字符串型函数.日期时间函数 ...

  3. 从头学pytorch(十一):自定义层

    自定义layer https://www.cnblogs.com/sdu20112013/p/12132786.html一文里说了怎么写自定义的模型.本篇说怎么自定义层. 分两种: 不含模型参数的la ...

  4. 【题解】Killer Names($O(n\log n)$做法)

    [题解]Killer Names(\(O(n\log n)\)做法) HDU - 6143 感觉好久没做过这种直来直去的组合题,过来水一篇题解.还以为要写一个\(MTT\)或者三模数\(NTT\),想 ...

  5. C#反射与特性(二):探究反射

    目录 1,反射的使用概述 2,获取 Type 在上一章中,我们探究了 C# 引入程序集的各种方法,这一章节笔者将探究 C# 中使用反射的各种操作和代码实践. 1,反射的使用概述 1.1 什么是反射 & ...

  6. IHostingEnvironment VS IHostEnvironment - .NET Core 3.0中的废弃类型

    原文: https://andrewlock.net/ihostingenvironment-vs-ihost-environment-obsolete-types-in-net-core-3/ 作者 ...

  7. 基于Tesseract的OCR识别小程序

    一.背景 先说下开发背景,今年有次搬家找房子(2020了应该叫去年了),发现每天都要对着各种租房广告打很多电话.(当然网上也找了实地也找),每次基本都是对着墙面看电话号码然后拨打,次数一多就感觉非常麻 ...

  8. 「USACO 1.3」 Name That Number 解题报告

    \(注意 该篇题解为本人较早时期写的题解 所以会很傻 直接能用map 以string为下标偏偏要绕弯儿 有时间改一改QAQ\) [USACO1.2]Name That Number 题目描述 在威斯康 ...

  9. .gitignore 文件配置

    git 使用过程中,有许多文件或者文件夹是不希望更新到远程仓库了,因为他们比较占地方,这个时候我们可以利用 .gitignore 文件忽略文件. 按项目进行忽略 .gitignore 文件用于忽略文件 ...

  10. Java之Object类用法总结

    Object类概述: 1.Object类是所有Java类的根父类. 2.如果在类的声明中未使用extends关键字指明其父类, 则默认父类为java.lang.Object类. Object类主要结构 ...