术语
镜像构建上下文(Context)
docker是c/s架构,分客户端和服务端,客户端通过rest api与服务端通信完成各种任务。docker build 时,会将指定的上下文目录下的文件打包发给服务端(你可以使用.dockerignore 来除去不传的文件),那么像COPY、ADD这些涉及添加文件的指令,就能将发到服务器的文件打包进镜像中。这些命令,在操作源文件(src)是相对目录时,都是相对发到服务端的上下文目录的。
工作目录(WORKDIR)
镜像的工作目录。那么所有涉及操作的目标目录(dest)是相对目录时,一般是相对于该目录的。
指令
ARG
该指令一般用来指定构建时的变量默认值。from指令支持由第一个from之前出现的任何arg指令声明的变量
ARG设置默认值,供FROM命令使用:
ARG VERSION=latestFROM busybox:${VERSION} # 解析结果:busybox:latestRUN echo done# 构建命令:docker build .
ARG设置默认值,供FROM和其他命令一起使用:
ARG VERSION=latestFROM busybox:${VERSION} # 解析结果:busybox:latestARG VERSION ## 如果非FROM命令也想使用FROM之前声明的变量的默认值,这里一定要来个空声明,后续命令才能使用RUN echo $VERSION # 解析结果:echo latest# 构建命令:docker build .
多次声明且初始化同一个变量:
ARG VERSION=latestFROM busybox:${VERSION} # 解析结果:busybox:latestARG VERSION=1.0.0RUN echo $VERSION # 解析结果:echo 1.0.0ARG VERSION=1.0.1RUN echo $VERSION # 解析结果:echo 1.0.1# 构建命令:docker build .
通过CLI覆盖内部声明的同名变量:
ARG VERSION=1.0.0FROM busybox:${VERSION} # 解析结果:busybox:latestARG VERSION=1.0.1RUN echo $VERSION # 解析结果:busybox:latestARG VERSION=1.0.2RUN echo $VERSION # 解析结果:busybox:latest# 构建命令: docker build --build-arg VERSION=latest .
FROM
该指令用来指定基础镜像。
用法:
FROM <image> [AS <name>]FROM <image>[:<tag>] [AS <name>]FROM <image>[@<digest>] [AS <name>]
- ARG 是唯一一个可先于FROM的命令
- FROM 可以在出现多次,来创建多个镜像。或者把其中一个作为另外一个的依赖。注意只需在每条新的from指令之前记录commit输出的最后一个映像id。每条from指令都清除以前指令创建的任何状态。
- 也可以通过将
as name添加到from指令中,为新的生成阶段指定一个名称。该名称可以在后续的from和copy --from=<name index>指令中使用,以引用在此阶段中生成的图像。 - 标记或摘要值是可选的。如果忽略其中任何一个,则生成器默认采用最新的标记。如果生成器找不到标记值,则返回错误。
ENV
该指令用来声明变量。变量可在其他指令当中解析使用。声明语法
ENV <key> <value>ENV <key>=<value> ...
应用语法
$variable_name${``variable_name``}带有大括号的写法可以解决没有空格的变量名字。如${for}_bar。${variable:-word}表示指示如果设置了变量,则结果将是该值。如果未设置变量,则结果为word。${variable:+word}表示指示如果设置了变量,则结果为word,否则结果为空字符串。
可以使用环境变量的命令
FROM busyboxENV foo /barWORKDIR ${foo} # WORKDIR /barADD . $foo # ADD . /barCOPY \$foo /quux # COPY $foo /quux
ENV abc=helloENV abc=bye def=$abc # def=hellENV ghi=$abc # ghi=bye
RUN
该指令用来定义每一层如何构建。每一条RUN指令执行后,都会commit这层修改,构成新的镜像。
RUN指令有2种形式:
RUN <command>(shell form, the command is run in a shell, which by default is/bin/sh -con Linux orcmd /S /Con Windows)RUN ["executable", "param1", "param2"](exec form)
如果2种方式执行命令是 shell, 那么就会存在环境变量替换。
CMD
该指令如果有多条,只有最后一个有效。
RUN指令有3种形式:
CMD ["executable","param1","param2"](exec form, this is the preferred form)CMD ["param1","param2"](as default parameters to ENTRYPOINT)CMD command param1 param2(shell form)
第一种方式和第三种方式的区别是:
第三种方式会放到shell来执行,即: /bin/sh -c "command param1 param2", 也就是说如果镜像里没有安装shell, 这种方式就执行失败。第一种方式则直接执行命令,不会借助shell来执行命令。
LABEL
改制指令用来给镜像增加metadata,具有继承性,可包含多条LABEL指令。
EXPOSE
该指令用来通知docker,当前容器监听的端口。
使用方法:
EXPOSE <port> [<port>/<protocol>...]
该指令可以多次使用。如果不指定协议,默认是tcp。
EXPOSE 80/tcpEXPOSE 80/udp
可以在容器启动的时候,使用 -p来覆盖 EXPOSE 设置:
docker run -p 80:80/tcp -p 80:80/udp
ADD
该指令用来复制文件、目录、远程文件到镜像的文件系统下。
使用方法:
ADD [--chown=<user>:<group>] <src>... <dest>ADD [--chown=<user>:<group>] ["<src>",... "<dest>"](this form is required for paths containing whitespace)
COPY
该指令和ADD之指令一样,唯独比ADD少一个功能,就是不能添加远程文件。
ENTRYPOINT
该命令通常用来配置一个可执行命令,指定容器启动后运行的第一个命令。
该指令有2种用法:
ENTRYPOINT ["executable", "param1", "param2"](exec form, preferred)ENTRYPOINT command param1 param2(shell form)
CMD 和 ENTRYPOINT 协作关系:
| No ENTRYPOINT | ENTRYPOINT exec_entry p1_entry | ENTRYPOINT [“exec_entry”, “p1_entry”] | |
|---|---|---|---|
| No CMD | error, not allowed | /bin/sh -c exec_entry p1_entry | exec_entry p1_entry |
| CMD [“exec_cmd”, “p1_cmd”] | exec_cmd p1_cmd | /bin/sh -c exec_entry p1_entry | exec_entry p1_entry exec_cmd p1_cmd |
| CMD [“p1_cmd”, “p2_cmd”] | p1_cmd p2_cmd | /bin/sh -c exec_entry p1_entry | exec_entry p1_entry p1_cmd p2_cmd |
| CMD exec_cmd p1_cmd | /bin/sh -c exec_cmd p1_cmd | /bin/sh -c exec_entry p1_entry | exec_entry p1_entry /bin/sh -c exec_cmd p1_cmd |
VOLUMN
在的镜像内创建了不可改变的目录。
用法:
VOLUME ["/data"]
构建阶段,在volume声明之后,声明目录下发生的数据变化,都会被丢失。
宿主挂载的目录只能在容器启动时指定。
USER
该命令用来指定RUN CMD ENTRYPOINT等命令的用户和用户组。
用法:
USER <user>[:<group>] # orUSER <UID>[:<GID>]
WORKDIR
该指令用来制定容器的工作目录,可以使用多次,如果是相对目录,那么也是相对前一次制定的工作目录:
WORKDIR /aWORKDIR bWORKDIR cRUN pwd # /a/b/c
