术语
镜像构建上下文(Context)
docker是c/s架构,分客户端和服务端,客户端通过rest api与服务端通信完成各种任务。docker build 时,会将指定的上下文目录下的文件打包发给服务端(你可以使用.dockerignore 来除去不传的文件),那么像COPY、ADD这些涉及添加文件的指令,就能将发到服务器的文件打包进镜像中。这些命令,在操作源文件(src)是相对目录时,都是相对发到服务端的上下文目录的。
工作目录(WORKDIR)
镜像的工作目录。那么所有涉及操作的目标目录(dest)是相对目录时,一般是相对于该目录的。
指令
ARG
该指令一般用来指定构建时的变量默认值。from指令支持由第一个from之前出现的任何arg指令声明的变量
ARG设置默认值,供FROM命令使用:
ARG VERSION=latest
FROM busybox:${VERSION} # 解析结果:busybox:latest
RUN echo done
# 构建命令:docker build .
ARG设置默认值,供FROM和其他命令一起使用:
ARG VERSION=latest
FROM busybox:${VERSION} # 解析结果:busybox:latest
ARG VERSION ## 如果非FROM命令也想使用FROM之前声明的变量的默认值,这里一定要来个空声明,后续命令才能使用
RUN echo $VERSION # 解析结果:echo latest
# 构建命令:docker build .
多次声明且初始化同一个变量:
ARG VERSION=latest
FROM busybox:${VERSION} # 解析结果:busybox:latest
ARG VERSION=1.0.0
RUN echo $VERSION # 解析结果:echo 1.0.0
ARG VERSION=1.0.1
RUN echo $VERSION # 解析结果:echo 1.0.1
# 构建命令:docker build .
通过CLI覆盖内部声明的同名变量:
ARG VERSION=1.0.0
FROM busybox:${VERSION} # 解析结果:busybox:latest
ARG VERSION=1.0.1
RUN echo $VERSION # 解析结果:busybox:latest
ARG VERSION=1.0.2
RUN 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 busybox
ENV foo /bar
WORKDIR ${foo} # WORKDIR /bar
ADD . $foo # ADD . /bar
COPY \$foo /quux # COPY $foo /quux
ENV abc=hello
ENV abc=bye def=$abc # def=hell
ENV 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 -c
on Linux orcmd /S /C
on 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/tcp
EXPOSE 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>] # or
USER <UID>[:<GID>]
WORKDIR
该指令用来制定容器的工作目录,可以使用多次,如果是相对目录,那么也是相对前一次制定的工作目录:
WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd # /a/b/c