什么是 Dockerfile?
Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。使用docker build
命令,用户可以创建基于基础镜像的自定义镜像。
Dockerfile格式
# Comment
INSTRUCTION arguments # INSTRUCTION表示指令(不止一条)
指令详解
FROM-指定基础镜像
指定基础镜像,并且Dockerfile中第一条指令必须是FROM指令,且在同一个Dockerfile中创建多个镜像时,可以使用多个FROM指令。
语法格式如下:
FROM <image>
FROM <image>:<tag>
其中<tag>
是可选项,如果没有选择,那么默认值为latest
。
如果不以任何镜像为基础,那么写法为:FROM scratch
。
RUN-运行指定的命令
运行指定的命令。
包含两种语法格式,如下所示:
# shell格式:就像在命令行中输入的Shell脚本命令一样。
RUN <command>
# exec格式:就像是函数调用的格式。
RUN ["executable", "param1", "param2"]
第一种后边直接跟shell命令。
- 在linux操作系统上默认为
/bin/sh -c
- 在windows操作系统上默认为
cmd /S /C
第二种是类似于函数调用。可将executable理解成为可执行文件,后面就是两个参数。
样例:
RUN /bin/bash -c 'source $HOME/.bashrc; echo $HOME'
RUN ["/bin/bash", "-c", "echo hello"]
注意:
多行命令不要写多个RUN,原因是Dockerfile中每一个指令都会建立一层。多少个RUN就构建了多少层镜像,会造成镜像的臃肿、多层,不仅仅增加了构件部署的时间,还容易出错。RUN书写时的换行符是\
CMD-容器启动时要运行的命令
容器启动时要运行的命令。
包含三种语法格式,如下所示:
# 第一种就是shell这种执行方式和写法
CMD command param1 param2
# 第二种是可执行文件加上参数的形式(推荐)
CMD ["executable","param1","param2"]
# 该写法是为 ENTRYPOINT 指令指定的程序提供默认参数
CMD ["<param1>","<param2>",...]
推荐使用第二种格式,执行过程比较明确。第一种格式实际上在运行的过程中也会自动转换成第二种格式运行,并且默认可执行文件是sh
。
样例:
CMD [ "sh", "-c", "echo $HOME" ]
CMD [ "echo", "$HOME" ]
注意:
这里边包括参数的一定要用双引号,不能是单引号。千万不能写成单引号。原因是参数传递后,docker解析的是一个JSON array.
ENTRYPOINT-为容器指定默认运行程序
类似CMD指令的功能,用于为容器指定默认运行程序,从而使得容器像是一个单独的可执行程序。
在写Dockerfile时, ENTRYPOINT或者CMD指令会自动覆盖之前的ENTRYPOINT或者CMD指令。即ENTRYPOINT或者CMD指令只能写一条,如果写了多条,那么,ENTRYPOINT或者CMD都只有最后一条生效。
在Docker镜像运行时, 用户也可以在命令行指定具体命令, 覆盖在Dockerfile里的命令。
与CMD不同的是,由ENTRYPOINT启动的程序不会被docker run
命令行指定的参数所覆盖,而且,这些命令行参数会被当作参数传递给ENTRYPOINT指令指定的程序,不过,docker run
命令的--entrypoint
选项的参数可覆盖ENTRYPOINT指令指定的程序。
其语法如下:
# exec格式(推荐)
ENTRYPOINT ["executable", "param1", "param2"]
# shell格式
ENTRYPOINT command param1 param2
第一种就是可执行文件加参数。与CMD
指令一样,ENTRYPOINT
也更加推荐使用exec
格式。
第二种就是shell格式。
样例:
FROM ubuntu
RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/*
ENTRYPOINT ["curl", "-s", "http://ip.cn"]
# 将其构建成镜像ubuntu:v1.2,下面我们创建并启动容器:
docker run -it ubuntu:v1.2
# 将会在控制台输出我们相应的公网IP信息!
# 此时,如果我们还需要获取HTTP头信息时,我们可以这样:
docker run -it ubuntu:v1.2 -i
CMD与ENTRYPOINT的异同点
这俩命令非常想,而且还可以配合使用。
相同点:
- 只能写一条,如果写了多条,那么只有最后一条生效。
- 容器启动时才运行,运行时机相同。
不同点:
- ENTRYPOINT不会被运