Dockerfile简介
Dockerfile是一个用来构建镜像的文本文档,它包含用户在命令行上可以调用的能被用来组装镜像的所有命令。Docker可以通过读取Dockerfile中的指令来自动构建图像(使用docker build命令,用户可以创建一个连续执行多个命令行指令的自动构建)。
常见模板
# 使用From指令指定基础镜像可以为hub中的镜像也可以为私有仓库的镜像(ACR、Harbor)
From nginx:latest
# 使用MAINTAINER指令描述维护者信息
MAINTAINER yuhua <your contact info>
# 镜像操作指令 把“./”(当前目录)下的所有文件拷贝到容器内的“/abc”目录
COPY ./ /abc
# 指定RUN、ENTRYPOINT、CMD指令的工作目录(容器内)
WORKDIR /abc
# 使用RUN指令,指定执行"npm install"命令
RUN npm install
# 对容器外暴露8080端口
EXPOSE 8080
# 容器启动时执行的指令 指定容器启动时执行“node bin/run”命令,启动node应用
ENTRYPOINT ["node","bin/run"]
常用指令
指令 | 概述 | 备注 |
---|---|---|
ADD | 添加指令,将源文件或者目录添加到指定路径下。 | 镜像操作指令。具有自动解压功能 |
ARG | 用于变量传递。 | |
CMD | 为执行容器提供默认值。 | 容器启动时执行的指令。 |
COPY | 复制指令,从上下文目录中复制文件或者目录到容器里指定路径。 | 镜像操作指令。 |
ENTRYPOINT | 配置作为可执行文件运行的容器的入口。 | 容器启动时执行的指令。 |
ENV | 用于设置环境变量,在容器内被脚本或者程序调用。 | 镜像操作指令。 |
EXPOSE | EXPOSE用来指定端口,使容器内的应用可以通过端口和外界交互。 | 镜像操作指令。 |
FROM | 初始化一个新的构建阶段,并为后续指令设置 基本映像。 | 属于基础镜像信息。若镜像不存在自动会去Docker Hub下载 |
MAINTAINER | MAINTAINER指令设置生成的映像的Author字段。 | 维护者信息 |
ONBUILD | ONBUILD指令向映像添加一个触发器指令,稍后将在该映像用作另一个构建的基础时执行。 | 镜像操作指令。 |
RUN | 用于执行后面跟着的命令行命令。 | 镜像操作指令。核心指令 |
USER | USER命令用于设置运行容器的UID。 | 镜像操作指令。 |
VOLUME | 定义匿名数据卷。在启动容器时忘记挂载数据卷,会自动挂载到匿名卷。 | 镜像操作指令。 |
WORKDIR | 指定RUN、CMD、ENTRYPOINT 指令的工作目录 | 镜像操作指令。 |
常用指令详解
ADD
作用:
添加指令,将源文件或者目录添加到指定路径下。
使用格式:
ADD [--chown=<user>:<group>] <src>... <dest>
ADD [--chown=<user>:<group>] ["<src>",... "<dest>"]
ADD指令从复制新文件、目录或远程文件url,并将它们添加到位于路径处的镜像文件系统中。
可以指定多个资源,但如果它们是文件或目录,则它们的路径被解释为相对于构建上下文的源。
示例:
#添加hom开头的所有文件
ADD hom* /mydir/
#?可被替换为任何单个字符,如home、homo等,起到占位符作用。
ADD hom?.txt /mydir/
#<dest>是一个绝对路径,或相对于WORKDIR的路径,如下表示将test.txt文件添加到<WORKDIR>/relativeDir/下
ADD test.txt relativeDir/
#将test.txt文件添加到绝对路径/absoluteDir下
ADD test.txt /absoluteDir/
#添加一个名为arr[0].txt的文件(含有特殊字符需要遵循golang规则)
ADD arr[[]0].txt /mydir/
注意事项:
- 当添加包含特殊字符的文件或目录时,需要按照Golang规则避开这些路径,以防止它们被视为匹配格式。
- 若不使用chown标志指定给定的用户名、groupname或UID/GID组合来请求所添加内容的特定所有权,则所有新文件和目录都使用UID和GID为0创建。chown标志的格式允许用户名和组名字符串或直接整数UID和GID的任意组合。
ADD --chown=55:mygroup files* /somedir/
ADD --chown=bin files* /somedir/
ADD --chown=1 files* /somedir/
ADD --chown=10:11 files* /somedir/
- ADD 指令和 COPY 的使用格式一致(同样需求下,官方推荐使用 COPY)。功能也类似,不同之处如下:
- ADD 的优点:在执行 <源文件> 为 tar 压缩文件的话,压缩格式为 gzip, bzip2 以及 xz 的情况下,会自动复制并解压到 <目标路径>。
- ADD 的缺点:在不解压的前提下,无法复制 tar 压缩文件。会令镜像构建缓存失效,从而可能会令镜像构建变得比较缓慢。具体是否使用,可以根据是否需要自动解压来决定。
3.更多详细介绍参见官方文档ADD说明
ARG
作用:
构建参数(说白了就是在dockerfile范围内起作用的变量),与 ENV 作用一至。不过作用域不一样。ARG 设置的环境变量仅对 Dockerfile 内有效,也就是说只有 docker build 的过程中有效,构建好的镜像内不存在此环境变量。
使用格式:
ARG <name>[=<default value>]
示例:
注意事项:
- Dockerfile可以包含一个或多个ARG指令。
- ARG是唯一一个可以用在FROM指令之前的指令。
CMD
作用:
CMD的主要目的是为执行容器提供默认值。这些缺省值可以包括可执行文件,也可以省略可执行文件,在这种情况下,还必须指定一个ENTRYPOINT指令。
使用格式:
#首选形式 exec形式
CMD ["executable","param1","param2"]
#为ENTRYPOINT提供默认的参数,可搭配ENTRYPOINT使用
CMD ["param1","param2"]
#shell形式 <命令>将在/bin/sh -c中执行
CMD command param1 param2
示例:
FROM ubuntu
CMD ["/usr/bin/wc","--help"]
FROM ubuntu
CMD echo "This is a test." | wc -
注意事项:
-
在Dockerfile中只能有一条CMD指令。如果列出了多个CMD,那么只有最后一个CMD将生效。
-
如果用户指定了docker运行的参数,那么他们将覆盖CMD中指定的默认值。
-
不要混淆RUN与CMD。RUN实际运行命令并提交结果;CMD在build时不执行任何东西,但可以指定镜像所需要的指令。说白了真正执行指令的是RUN,CMD是一般为ENTRYPOINT准备需要的指令。等于是给ENTRYPOINT 传参。
FROM nginx # 定参 ENTRYPOINT ["nginx", "-c"] # 变参 CMD ["/etc/nginx/nginx.conf"]
-
更多详细介绍参见官方文档CMD说明
COPY
作用:
复制指令从中复制新的文件或目录,并将它们添加到路径处的容器文件系统中。
使用格式:
COPY [--chown=<user>:<group>] <src>... <dest>
COPY [--chown=<user>:<group>] ["<src>",... "<dest>"]
示例:
#添加hom开头的所有文件
COPY hom* /mydir/
#?可被替换为任何单个字符,如home、homo等,起到占位符作用。
COPY hom?.txt /mydir/
#<dest>是一个绝对路径,或相对于WORKDIR的路径,如下表示将test.txt文件添加到<WORKDIR>/relativeDir/下
COPY test.txt relativeDir/
#将test.txt文件添加到绝对路径/absoluteDir下
COPY test.txt /absoluteDir/
#添加一个名为arr[0].txt的文件(含有特殊字符需要遵循golang规则)
COPY arr[[]0].txt /mydir/
注意事项:
-
路径必须在构建的上下文路径中。整个Dockerfile所在的路径都会添加到容器的上下文中。特别注意比如
/var/lib/docker/tmp/docker-builder438042188/+(不得在Dockerfile文件存在目录的上级目录)
-
如果是一个目录,则复制该目录的全部内容,包括文件系统元数据。
-
上下文路径,是指 docker 在构建镜像,有时候想要使用到本机的文件(比如复制),docker build 命令得知这个路径后,会将路径下的所有内容打包。
解析:由于 docker 的运行模式是 C/S。我们本机是 C,docker 引擎是 S。实际的构建过程是在 docker 引擎下完成的,所以这个时候无法用到我们本机的文件。这就需要把我们本机的指定目录下的文件一起打包提供给 docker 引擎使用。
如果未说明最后一个参数,那么默认上下文路径就是 Dockerfile 所在的位置。
ENTRYPOINT
作用:
配置作为可执行文件运行的容器的入口。
使用格式:
#首选形式 exec形式
ENTRYPOINT ["executable", "param1", "param2"]
#shell形式
ENTRYPOINT command param1 param2
示例:
#首选形式
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/iot_cmp.jar"]
#shell形式
FROM centos
ENTRYPOINT exec top -b
# ENTRYPOINT与CMD结合使用
FROM centos
ENTRYPOINT ["top", "-b"]
CMD ["-c"]
注意事项:
- 如果 Dockerfile 中如果存在多个 ENTRYPOINT 指令,仅最后一个生效。
- 更多详细介绍参见官方文档ENTRYPOINT 说明
ENV
作用:
ENV指令将环境变量设置为值。该值将在构建阶段的所有后续指令的环境中,并且可以在许多环境中内联替换。
使用格式:
# 为单个变量设置值
ENV <key> <value>
#为多个变量设置值
ENV <key>=<value> ...
示例:
# 设置环境变量 NODE_ENV 为 production,NODE_ENV这个变量在镜像中可能为占位变量
ENV NODE_ENV production
注意事项:
EXPOSE
作用:
EXPOSE用来指定端口,使容器内的应用可以通过端口和外界交互。
使用格式:
EXPOSE <port>
示例:
# 对外暴露8080端口
EXPOSE 8080
注意事项:
1.对外尽量别暴露一些常用端口,避免造成端口冲突。
FROM
作用:
FROM指令初始化一个新的构建阶段,并为后续指令设置 基本映像。
使用格式:
FROM [--platform=<platform>] <image> [AS <name>]
FROM [--platform=<platform>] <image>[:<tag>] [AS <name>]
FROM [--platform=<platform>] <image>[@<digest>] [AS <name>]
示例:
# 基于java8构建
FROM java:8
#ARG与FROM交互使用
ARG CODE_VERSION=latest
FROM base:${CODE_VERSION}
注意事项:
- 有效的
Dockerfile
必须从FROM
指令开始。该图像可以是任何有效图像- 从公共存储库中拉出图像特别容易启动。 - FROM可以在单个Dockerfile中出现多次,以创建多个映像或使用一个构建阶段作为另一个构建阶段的依赖项。只需在每条新的FROM指令之前记录commit输出的最后一个映像ID。每个FROM指令清除前面指令创建的任何状态。如指定
linux/amd64
,linux/arm64
, orwindows/amd64
. - platform标志可用于指定图像的平台,以防引用多平台图像。
- 更多详细介绍参见官方文档FROM说明
MAINTAINER
作用:
MAINTAINER指令设置生成的映像的Author字段。
使用格式:
MAINTAINER <name>
示例:
MAINTAINER yuhua <yuhua@163.com>
通过docker inspect :[tag]命令查看现有镜像信息,会有author字段,后面值就是MAINTAINER指定的值。
注意事项:
docker inspect [OPTIONS] NAME|ID [NAME|ID...]
RUN
作用:
用于执行后面跟着的命令行命令。RUN是核心指令,它接受命令作为参数并用于创建镜像。命令较多时可用""换行。
使用格式:
#<命令行命令> 等同于,在终端操作的 shell 命令。
RUN <command>
#exec形式
RUN ["executable", "param1", "param2"]
示例:
RUN /bin/bash -c 'source $HOME/.bashrc; \
echo $HOME'
RUN /bin/bash -c 'source $HOME/.bashrc; echo $HOME'
RUN ["/bin/bash", "-c", "echo hello"]
注意事项:
- RUN命令再docker build时运行。
- Dockerfile 的指令每执行一次都会在 docker 上新建一层。所以过多无意义的层,会造成镜像膨胀过大
- 更多详细介绍参见官方文档RUN说明
USER
作用:
USER命令用于设置运行容器的UID。
使用格式:
USER <UID>
示例:
# 指定容器的UID为23541
USER 23541
注意事项:
VOLUME
作用:
卷指令使用指定的名称创建一个挂载点,并将其标记为保存来自本机主机或其他容器的外部挂载的卷。可以避免容器重启而丢失重要数据以及避免容器因存储在容器内部数据而不断变大。
使用格式:
VOLUME ["<路径1>", "<路径2>"...]
VOLUME <路径>
示例:
FROM ubuntu
RUN mkdir /myvol
RUN echo "hello world" > /myvol/greeting
#主机挂载路径
VOLUME /myvol
这个Dockerfile会产生一个映像,使docker运行时在/myvol处创建一个新的挂载点,并将greeting文件复制到新创建的卷中。
注意事项:
- 更多详细介绍参见官方文档VOLUME说明