在使用Dockerfile一构建Docker镜像之前需要先搞清楚Dockerfile中都有哪些常用的指令,这样在使用起来才能得心应手。
这篇文章主要列举出Dockerfile中比较常用的指令及其用法和说明,需要注意的是这些指令都是全部大写。
FROM
:
- 说明:指定该镜像的基础镜像
- 格式如:
FROM <image>
或FROM <image>:<tag>
- 示例:
FROM centos:7
- 注意:
FROM
一般出现在文件头,且每个镜像都需要有一个FROM
来指定基础镜像。
MAINTAINER
:
- 说明:指定作者信息
- 格式如:
MAINTAINER <name>
- 示例:
MAINTAINER 知识林 "393156105@qq.com"
RUN
:
- 说明:在构建镜像时执行脚本
- 格式如:
RUN <command>
、RUN ["exec", "par1", "par2"]
- 示例:
RUN ls -l
(以详细信息方式列表当前目录下的文件,跟在shell终端运行一样)
CMD
:
- 说明:在运行容器时执行脚本
- 格式如:
CMD <command> <par1> <par2> ...
、CMD ["exec", "par1", "par2"]
- 示例:
CMD ["ls", "-l"]
- 注意:一个Dockerfile中只有一条
CMD
,如果有多条只执行最后一条;在运行容器时如果用户指定了运行命令则Dockerfile中的CMD将被覆盖。
ENTRYPOINT
:
- 说明:在运行容器时执行脚本
- 格式如:
ENTRYPOINT ["exec", "par1", "par2"]
、ENTRYPOINT command par1 par2
- 示例:
ENTRYPOINT ["catalina.sh", "run"]
- 注意:一个Dockerfile中只有一条
ENTRYPOINT
,如果有多条只执行最后一条;不可以被容器运行时的命令所覆盖。
EXPOSE
:
- 说明:让Docker暴露容器的端口号,供其他容器使用,在宿主机以外的网络中是无法使用的
- 格式如:
EXPOSE <port> ...
- 示例:
EXPOSE 8080
- 注意:
- 在Docker中有两种暴露端口的概念,一种叫
EXPOSE
隐式暴露,只供Docker服务内部使用;另一种叫PUBLISH
显式暴露,供外部网络使用,PUBLISH
只是一个概念在Dockerfile中没有这个指令。 EXPOSE
只在Dockerfile中出现,所暴露的端口只是被其他容器使用PUBLISH
没有该指令而是通过docker run
命令的参数-p
、-P
或在docker-compose
中的ports
来体现-P
:大写是属于自动映射,将Dockerfile中EXPOSE
所暴露的所有端口分别映射到宿主机的随机端口,每次启动或重启容器时端口都可能有所不同-p
:小写是属于固定映射,格式如:-p 宿主端口:容器端口
,宿主端口和容器端口可以是纯数字也可以是一个范围,如:-p 8060-8080:8060-8080
,意为将宿主机的8060
(含)到8080
(含)的端口映射到容器的8060
(含)到8080
(含)端口,需要注意的是在使用范围时,宿主端口个数应该与容器端口个数匹配;但上面这个例子可以写成:-p 7060-7080:8060-8080
,这样宿主的端口就在7060-7080
范围内
- 在Docker中有两种暴露端口的概念,一种叫
ENV
:
- 说明:指定环境变量,在Dockerfile文件中的后续代码中使用,在容器运行时也可以使用
- 格式如:
ENV <key> <value>
- 示例:
ENV tomcat_home /web/tomcat/
ADD
:
- 说明:添加文件(夹)到容器
- 格式如:
ADD <src> <dest>
- 示例:
ADD web.jar /web.jar
- 注意:复制指定的
<src>
到容器中的<dest>
,<src>
可以是Dockerfile所在目录的一个相对路径,也可以是一个URL,也可以是一个tar
文件(tar
文件将自动解压成文件目录)
COPY
:
- 说明:添加文件(夹)到容器
- 格式如:
COPY <src> <dest>
- 示例:
COPY web.jar /web.jar
- 注意:与
ADD
功能相似,只是不能指定URL,使用本地文件(夹)为源文件时,推荐使用COPY
VOLUME
:
- 说明:创建挂载点
- 格式如:
VOLUME [path]
- 示例:
VOLUME ["/datas"]
-
注意:
VOLUME
在原理和概念上与EXPOSE
差不多,都是属于供容器与容器间使用- 通过
VOLUME
挂载的卷可以供其他容器使用 -
举例说明:
-
创建一个Dockerfile来构建一个镜像,内容如下:
FROM centos VOLUME ["/web/images", "/web/files"]
-
构建镜像
docker build -t "zsl131/test01" .
-
启动容器
docker run -d --name test-root
-
可以使用命令:
docker inspect test-root
来查看容器详细信息,在Mounts
部份可以看到两个挂载点:/web/images
和/web/files
-
启动另一个容器来共用这两个挂载卷
docker run -it --name test-1 --volumes-from test-root centos
注意:使用
--volumes-from
来指定挂载点,这时容器test-root
和test-1
里面都分别有挂载卷/web/images
和/web/files
,可以启动任意多个容器使用--volumes-from
来共用这些挂载卷,这些容器可以来自不同的镜像。当任何一个容器中的挂载卷中的文件发生变化时其他容器挂载卷中的内容也随之改变。容器
test-root
即使已经停止也可以在启动其他容器时使用--volumes-from test-root
来挂载这些卷,只要test-root
不被删除,不过如果test-root
真被删除还可以使用--volumes-from test-1
,因为容器test-1
中还存在我们所需要的挂载卷,换句话说这些挂载卷永远存在直到所有使用这些挂载卷的容器都被删除。 -
VOLUME
与docker run
参数-v
是有区别的。docker run -v /host/web/images:/web/images -v /host/web/files:/web/files:rw
是将容器内的/web/images
挂载到宿主机的/host/web/images
目录上;将容器内的/web/files
挂载到宿主机的/host/web/files
目录上,rw
表示可读写。
-
WORKDIR
:
- 说明:设置工作目录
- 格式如:
WORKDIR /path
- 示例:
WORKDIR /web
- 注意:可以使用绝对路径,也可以使用相对路径,设置之后的所有操作都将在这个目录下完成
特别注意
在上面的描述中可以看到有两组指令在功能上都差不多,但也是有区别的:
-
RUN
、CMD
、ENTRYPOINT
执行脚本的指令- 三个指令都是执行脚本
RUN
是在创建镜像是执行,即使用docker build
命令时执行,在一个Dockerfile里面可以有多个RUN
CMD
和ENTRYPOINT
是在运行容器时执行,即使用docker run
命令时执行,这两个指令在Dockerfile中都只有最行一条被执行CMD
在使用docker run
时可以加参数将Dockerfile中的CMD
覆盖ENTRYPOINT
在Dockerfile中出现后就一定会在docker run
时被执行,不必担心会被其他参数所覆盖。
-
ADD
、COPY
拷贝文件(夹)到容器ADD
拷贝文件(夹)时可以指定本地文件、远程URL地址,如果拷贝的是tar
文件时将会被自动解压成文件夹COPY
拷贝文件(夹)时不可以指定远程URL地址,拷贝tar
文件也不会被自动解压成文件夹,在拷贝本地文件时建议使用COPY