1. https://blog.whsir.com/post-5327.html

Dockerfile其实就是一个文本文件,这个文本文件名称叫Dockerfile,里面包含了一些指令(可以理解成多个指令集合成了一个脚本来构建docker镜像),然后通过docker build来构建这个Dockerfile(docker build可以理解成一个打包的命令)。

Dockerfile用法

docker build命令根据Dockerfile上下文来构建新的docker镜像,构建上下文指当前Dockerfile所在路径或URL(URL是GIT仓库位置),构建的上下文会被递归处理,所以构建指定的目录还包括子目录,URL还包括了子模块。

$ docker build .
Sending build context to Docker daemon 6.51 MB
...

构建是通过守护进程执行而不是CLI运行的,构建过程第一件事就是将整个上下文(递归)发送到守护进程,大多数情况下,最好以一个空目录作为上下文,然后将Dockerfile文件放在该目录下,仅添加构建Dockerfile所需的文件。

注意:不要使用/根目录,会导致硬盘所有内容发送到守护进程。

为了提高性能,可以通过.dockerignore文件来排除不需要的文件和目录。

Dockerfile一般位于构建上下文的根目录下,也可以使用-f指定该文件的位置。

 
1
$ docker build -f /path/to/a/Dockerfile .

通过docker build构建时,也可以用-t指定镜像的仓库和标签

 
1
$ docker build -t shykes/myapp .

如果在多个仓库,或使用多个标签时,可以使用多个-t

 
1
$ docker build -t shykes/myapp:1.0.2 -t shykes/myapp:latest .

在Docker守护进程执行Dockerfile中的指令前,会对Dockerfile进行初步验证,如果语法不正确,则返回错误

 
1
2
3
$ docker build -t test/myapp .
Sending build context to Docker daemon 2.048 kB
Error response from daemon: Unknown instruction: RUNCMD

Docker守护进程会逐行的执行Dockerfile中的指令,并且会在每一步提交生成一个新镜像,最终输出新镜像的ID,生成完毕后,Docker守护进程将自动清理发送的上下文。

注意Dockerfile每条指令都是独立运行的,并会创建一个新镜像,因此RUN cd /tmp不会对下一条指令产生任何影响。

Docker会重用已生成的中间镜像(缓存),以加速docker build的构建过程。

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ docker build -t svendowideit/ambassador .
Sending build context to Docker daemon 15.36 kB
Step 1/4 : FROM alpine:3.2
---> 31f630c65071
Step 2/4 : MAINTAINER SvenDowideit@home.org.au
---> Using cache
---> 2a1c91448f5f
Step 3/4 : RUN apk update &&      apk add socat &&        rm -r /var/cache/
---> Using cache
---> 21ed6e7fbb73
Step 4/4 : CMD env | grep _TCP= | (sed 's/.*_PORT_\([0-9]*\)_TCP=tcp:\/\/\(.*\):\(.*\)/socat -t 100000000 TCP4-LISTEN:\1,fork,reuseaddr TCP4:\2:\3 \&/' && echo wait) | sh
---> Using cache
---> 7ea8aef582cc
Successfully built 7ea8aef582cc

构建缓存仅用于本地缓存的镜像,如果不想使用本地缓存的镜像来构建,则可以使用--cache-from选项指定它,指定后不再,使用本地的缓存镜像链,而是从其他镜像仓库中下载。

Dockerfile文件格式

 
1
2
# Comment
INSTRUCTION arguments

#注释信息
指令+参数

Dockerfile指令不区分大小写,但是为了更易区分,约定建议使用大写。

Docker会依次执行Dockefile中的指令,第一条指令必须以“FROM”开始,FROM指令用于指定一个基础镜像。

行首以#号开头的作为注释,在其他地方使用#号都会被视为参数,例:

 
1
2
# Comment
RUN echo 'we are running some # of cool things'

Dockerfile中的指令

FROM

 
1
2
3
FROM [--platform=<platform>] <image> [AS <name>]
FROM [--platform=<platform>] <image>[:<tag>] [AS <name>]
FROM [--platform=<platform>] <image>[@<digest>] [AS <name>]

FROM指令初始化一个新的构建,并为后面的指令提供基础镜像,编写一个有效的Dockerfile文件,开篇的第一个非注释行必须从FROM指令开始。

FROM可以在Dockerfile中出现多次,即创建多个镜像。如果忽略tag标签,默认使用latest。

例:FROM busybox:latest

LABEL

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

指定元数据,一条LABEL可以指定一条或多条元数据,指定多条元数据时通过空格分隔。

例:指定镜像版本和作者
LABEL version="1.0" maintainer="whsir <wh@whsir.com>"

COPY

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

将宿主机工作目录中的文件复制到目标镜像中,在路径中有空白字符时,通常使用第二种格式。

--chown仅在linux用于构建Linux容器的Dockerfiles上受支持,而在Windows容器上不起作用。

<src>表示要复制的源文件或目录,必须是上下文根目录的相对路径,支持通配符。如果<src>是目录,则其内部的子目录会被递归一并复制,但<src>目录本身不会被复制。

<dest>表示目标路径,必须是目标镜像中的绝对路径或相对于WORKDIR的相对路径,如果指定了多个<src>或使用了通配符,则<dest>必须是一个目录,且必须需要以/结尾。如果<dest>不存在,则路径中不存在的目录会被创建。

COPY指令类似于ADD,区别在于它不支持自动解压,也不能使用URL路径。

ADD

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

ADD指令类似于COPY,都支持复制本地文件到镜像的功能,但是ADD还支持自动解压,可以使用URL路径。

--chown仅在linux用于构建Linux容器的Dockerfiles上受支持,而在Windows容器上不起作用。

如果<src>为URL且<dest>不以/结尾,则<src>指定的文件将被下载并直接被创建为<dest>。如果<dest>以/结尾,则文件名URL指定的文件将被直接下载并保存为<dest>/<filename>。

如果<src>指向本地压缩格式的tar文件,该文件在复制到容器中时会被自动解压,但是通过URL获取的tar文件将不会被自动解压。

WORKDIR

 
1
WORKDIR /path/to/workdir

用于Dockerfile中所有RUN、CMD、ENTRYPOINT、COPY、ADD指定工作目录。

WORKDIR指令可以在Dockerfile中多次使用,也可以解析先前设定的环境变量ENV。

例:
ENV DIRPATH /path
WORKDIR /usr/local/$DIRPATH/
COPY index.html ./
等同于
ENV DIRPATH /path
COPY index.html /usr/local/$DIRPATH/

VOLUME

 
1
VOLUME ["/data"]

在镜像中创建一个新的挂载点目录,用于挂载docker主机上的卷或其它容器上的卷。

EXPOSE

 
1
EXPOSE <port> [<port>/<protocol>...]

容器运行时监听的网络端口(容器中暴露的端口),可以指定监听TCP还是UDP,如果未指定,默认监听TCP。

无论EXPOSE设置的端口是什么,都可以在容器运行时,使用-p选项覆盖。

例:指定多个端口
EXPOSE 80/tcp 80/udp

ENV

 
1
2
ENV <key> <value>
ENV <key>=<value> ...

用于为镜像所创建的容器定义环境变量,ENV声明的环境变量会被后续ADD、COPY等指令调用。

Dockerfile中通过ENV定义的环境变量,也会在启动容器后,直接在容器中使用,但是在容器启动时,使用-e选项会覆盖此环境变量。

如果<value>中包含空格,可以使用\反斜线进行转义,也可以对<value>加引号。

因为每多写一行,在构建Dockerfile时就会增加一层,所以定义多个变量时,建议使用第二种方式。

例:定义多个变量

 
1
2
ENV MY_NAME=“whsir” \
MY_CAT=tom

RUN

 
1
2
RUN <command>
RUN ["executable", "param1", "param2"]

指定docker build时运行的命令。

第一种shell方式,linux使用“/bin/sh -c”来运行,Windows使用cmd /S /C

第二种exec方式,不会调用命令shell,不会使用变量替换,如果要运行的命令依赖此shell特性的话,可以使用下面这种方式
RUN ["/bin/bash", "-c", "echo hello"]

例:

 
1
2
RUN mkdir -p /data/www/ && \
    echo 'demo paga' > /data/www/index.html

CMD

 
1
2
3
CMD ["executable","param1","param2"]
CMD ["param1","param2"]
CMD command param1 param2

CMD指令为启动的容器指定默认要运行的命令,但是CMD指定的命令可以被docker run命令行选项所覆盖,在Dockerfile中可以存在多个CMD指令,但只有最后一条CMD指令有效。

在第三种格式中,command通常是一个shell命令,且以"/bin/sh -c"来运行它,此进程在容器中的PID不为1,不能接收Unix信号
在第一种格式中的参数是一个JSON数组,其中executable要运行的命令,paramN为传递给命令的选项或参数,但是此格式指定的命令不会以"/bin/sh -c"发起,所以shell操作(变量替换、通配符等)将不会进行。第二种CMD所指定的内容,会被当成参数传递给ENTRYPOINT。

例:

 
1
2
3
4
FROM busybox:latest
RUN mkdir -p /data/www/ && \
    echo 'demo paga' > /data/www/index.html
CMD ["/bin/httpd" "-f" "-h /data/www/"]

ENTRYPOINT

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

类似CMD指令,用于为容器提供默认运行程序,每次使用镜像创建容器时,通过ENTRYPOINT指定的程序都会被设置为默认程序,由ENTRYPOINT启动的程序不会被docker run命令行指定的参数所覆盖,而且,这些命令行参数会被当做参数传递给ENTRYPOINT指定的程序。

一个Dockerfile中可以有多条ENTRYPOINT指令,但只有最后一条ENTRYPOINT指令有效。

USER

 
1
2
USER <user>[:<group>]
USER <UID>[:<GID>]

指定运行镜像及Dockerfile中任何RUN、CMD、ENTRYPOINT指令使用的用户名或UID和用户组或GID,默认容器中运行的身份为root。

在Windows下内置帐户,则必须创建用户,可以通过net user作为Dockerfile的一部分调用的命令来完成。

HEALTHCHECK

 
1
2
HEALTHCHECK [OPTIONS] CMD command
HEALTHCHECK NONE

在CMD前的选项:

--interval=DURATION每隔30s检测一次,默认30s
--timeout=DURATION超时时长,默认30s
--start-period=DURATION等主进程初始化完成后进行检测,默认等待时间0s
--retries=N连续检查N次,默认3次,如果3次都是失败,则认为这个容器是不健康的

CMD后可以跟shell脚本或数组。命令退出状态值可能为:

0:成功-容器健康且可用
1:不健康-容器无法正常工作
2:保留状态值自定义

例:每隔五分钟检测一次,超时时间为3秒,使用curl命令对localhost进行检测,失败退出为1

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

SHELL

 
1
SHELL ["executable", "parameters"]

设置默认shell所使用的shell类型,linux默认shell是["/bin/sh", "-c"],Windows默认shell是["cmd", "/S", "/C"],在Dockerfile中必须以JSON形式编写shell指令。

SHELL指令在Windows下特别有用,Windows下通常有cmd和powershell两种shell,以及sh备用shell。

SHELL指令可以出现多次。每个SHELL指令将覆盖所有先前的SHELL指令,并影响所有后续的指令。

STOPSIGNAL

 
1
STOPSIGNAL signal

停止容器所要发送的系统调用信号,该信号可以内核系统调用表中合法的值(例如9或SIGKILL)。

ARG

 
1
ARG <name>[=<default value>]

用于Dockerfile内的环境变量,与ENV相似,但是ARG仅docker build的过程中有效,在docker build构建时,可以使用--build-arg <varname>=<value>参数传递替换,构建成功的镜像不存在此环境变量。

ARG指令可以进行一些宏定义,比如我定义ENV JAVA_HOME=/opt/jdk,之后RUN后面的shell命令中的${JAVA_HOME}都会被/opt/jdk代替。

例:

 
1
2
3
4
AGR VERSION=latest
FROM busybox:$VERSION
在构建时使用--build-arg替换变量
docker build --build-arg VERSION="1.31.1" -t demo:v1 ./

ONBUILD

 
1
ONBUILD <INSTRUCTION>

在Dockerfile中定义一个触发器,当所构建的镜像被用作其他镜像的基础镜像时,该镜像中的触发器会被触发。

ONBUILD不支持自我嵌套,而且不会触发FROM和MAINTAINER指令。

更多内容请见官方文档:https://docs.docker.com/engine/reference/builder/

【转帖】Dockerfile文件指令介绍的更多相关文章

  1. Docker DockerFile文件指令 & 构建

    1.dockerfile指令格式 # Comment注释 INSTRUCTION argument指令名 + 参数 2.普通指令 1. FROM 已存在的镜像,基础镜像,第一条非注释指令 FROM & ...

  2. Docker学习(三): Dockerfile指令介绍

    特别声明: 博文主要是学习过程中的知识整理,以便之后的查阅回顾.部分内容来源于网络(如有摘录未标注请指出).内容如有差错,也欢迎指正! =============系列文章============= 1 ...

  3. docker(8)Dockerfile指令介绍

    前言 Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明. Dockerfile简介 Dockerfile是用来构建Docker镜像的构建文件,是由一系列 ...

  4. docker学习笔记6:利用dockerfile创建镜像介绍(生成简单web服务器镜像)

    本文介绍如何利用dockerfile来创建镜像.下面介绍具体的操作过程: 一.创建构建环境 操作示例如下: xxx@ubuntu:~$ pwd /home/xxx xxx@ubuntu:~$ mkdi ...

  5. docker创建image方法以及常用指令介绍

    docker -help    # 显示帮助 docker COMMAND -help    # 帮助信息更详细 docker start “容器名称”    # 启动一个或多个容器 docker s ...

  6. Dockerfile常用指令及使用

    Dockerfile常用指令及使用 1. dockerfile介绍 2. Dockerfile常用指令 指令 描述 FROM 构建新镜像是基于哪个镜像 MAINTAINER 进行维护者姓名或邮箱地址 ...

  7. DOCKER学习_013:Dockerfile配置指令ENTRYPOINT详解

    前面已经介绍了一些Dockerfile的一些指令,对于ENTRYPOINT和CMD也有介绍实验 一 ENTRYPOINT和CMD配置使用 ENTRYPOINT相当于CMD,是配置容器后的一个指令,但是 ...

  8. Docker学习(六)——Dockerfile文件详解

    Docker学习(六)--Dockerfile文件详解 一.环境介绍 1.Dockerfile中所用的所有文件一定要和Dockerfile文件在同一级父目录下,可以为Dockerfile父目录的子目录 ...

  9. Docke--Dockerfile指令介绍

    Dockerfile 构建镜像常用指令 Dockerfile 是一个文本文件,其内包含了一条条的指定(Instruction),每一条指令构建一层,因此每一条指定的内容,就是描述该层应当如何构建. 通 ...

  10. docker18.09.5 Dockerfile文件编写

    Dockerfile命令详解(超全版本)  https://www.cnblogs.com/dazhoushuoceshi/p/7066041.html 案例1 dockerfile文件内容: FRO ...

随机推荐

  1. 细说GaussDB(DWS)的2种查询优化技术

    本文分享自华为云社区<GaussDB(DWS)查询优化技术大揭秘>,作者: 胡辣汤. 大数据时代,数据量呈爆发式增长,经常面临百亿.千亿数据查询场景,当数据仓库数据量较大.SQL语句执行效 ...

  2. 十问Huawei Cloud Toolkit:开发插件如何提升云上开发效能

    本文分享自华为云社区<[云享问答]第2期 十问Huawei Cloud Toolkit:开发插件如何提升云上开发效能>,作者:华为云社区精选. 众所周知,桌面集成开发环境(IDE)已经融入 ...

  3. 自定义TBE算子入门,不妨从单算子开发开始

    摘要:以单算子开发为例,带你了解算子开发及测试全流程. 为什么要自定义算子 深度学习算法由一个个计算单元组成,我们称这些计算单元为算子(Operator,简称Op).算子是一个函数空间到函数空间上的映 ...

  4. 案例展示自定义C函数的实现过程

    摘要:用户在使用数据库过程中,受限于内置函数的功能,部分业务不易实现时,可以使用自定义C函数实现特殊功能.本文通过两个示例展示自定义C函数的实现过程. 前言 用户在使用数据库过程中,常常受限于内置函数 ...

  5. appuploder全过程使用教程(Windows版本)

    转载:使用appuploader工具流程(Windows版本) 一.登录apple官网,注册账号 1.注册苹果账号 Sign In - Apple 2.登录开发者中心 ,出现协议弹框,同意即可. 二. ...

  6. JAVA PDF 截取N页,生成新文件,转图片,多个PDF 合并

    JAVA PDF 截取N页,生成新文件,转图片,多个PDF 合并 <dependency> <groupId>com.itextpdf</groupId> < ...

  7. byte[] 数组,创建的时候赋初始值

    C# //创建一个长度为10的byte数组,并且其中每个byte的值为0x08. byte[] myByteArray = Enumerable.Repeat((byte)0x08, 10).ToAr ...

  8. Unable to open debugger port (127.0.0.1:53471): java.net.SocketException "Socket closed"

    21:59 Error running 'Vipsoft': Cannot run program "/Users/jimmy/Java/apache-tomcat-9.0.14/bin/c ...

  9. Java 日志框架学习笔记

    日志概念 1. 日志文件 日志文件是用于记录系统操作事件的文件集合 1.1 调试日志 1.2 系统日志 系统日志是记录系统中硬件.软件和系统问题的信息,同时还可以监视系统中发生的事件.用户可以通过它来 ...

  10. 给科研人的 ML 开源发布工具包

    什么是开源发布工具包? 恭喜你的论文成功发表,这是一个巨大的成就!你的研究成果将为学界做出贡献. 其实除了发表论文之外,你还可以通过发布研究的其他部分,如代码.数据集.模型等,来增加研究的可见度和采用 ...