Dockerfile
Dockerfile 是用于构建Docker镜像的脚本文件,由一系列指令构成。通过docker build命令构建镜像时,Dockerfile中的指令会由上到下依次执行,每条指令都会构建出一个镜像。这就是镜像的分层。因此,指令越多,层次也就越多,创建的镜像也就越多,效率也会越低。
所以在定义Dockerfile时,能在一个指令完成的动作就不要分为两条。
scratch镜像与ADD指令
scratch镜像是一个空镜像,不能pull、runn。
ENV
【语法1】ENV
<key>
<value>
用于指定环境变量,这些环境变量,后续可以被RUN指令使用,容器运行起来后,也可以在容器中获取这些环境变量。
【语法2】 ENV
<key>
=<value1>
<key2>
=<value2>
...可以设置多个变量,每个变量为一对
<key>=<value>
指定。
WORKDIR
【语法】WORKDIR path
容器打开后默认进入的目录,一般在后续的RUN、CMD、ENTRYPOINT、ADD等指令中会引用改目录。可以设置多个WORKDIR指令。后续WORKDIR指令若是用的是相对路径,则会基于之前WORKDIR指令指定的路径。在使用docker run运行容器时,可以通过
-w
参数覆盖构建时所设置的工作目录
RUN
【语法1】RUN
<command>
这里的command就是shell命令。docker build执行的过程中,会使用shell运行指定的command。
【语法2】RUN ["EXECUTABLE","PARAM1","PARAM2",...] 非shell,可执行命令
在docker build执行过程之中,会调用第一个参数"EXECUTABLE"指定的应用程序运行,并使用后面第二、三等参数作为应用程序的运行参数。
CMD
【语法1】CMD ["EXECUTABLE","PARAM1","PARAM2",...]
在容器启动之后,即在执行完 docker run 后会立即调用执行"EXECUTABLE"指定的可执行文件,并使用后面的第二、三等参数作为应用程序的运行参数。
【语法2】 CMD command param1 param2,...
这里的command就是shell命令,在容器启动之后会立即运行指定的shell命令。
【语法3】 CMD ["PARAM1","PARAM2",...]
提供给ENTERYPOINT的默认参数
dockerfile
FROM centos:7
CMD cal
FROM centos:7
CMD ["cal"]
bash
docker build -t mycal:1.0
我也可以把cal给替换掉
bash
docker run mycal:1.0 date
bash
docker build -f Dockerfile2 -t mycal:2.0 .
dockerfile
FROM centos:7
CMD ["/bin/bash","-c","cal"]
语法:CMD ["EXECUTABLE","PARAM1","PARAM2",...]
/bin/bash表示可执行文件,-c表示要执行的命令来源于命令行
其实就是用/bin/bash来执行cal
依旧还是不能加参数-y
结论:CMD的都不能用带选项的命令来替换
ENTRYPOINT
【语法1】ENTRYPOINT ["EXECUTABLE","PARAM1","PARAM2",...]
【解析】在容器启动过程中,也就是在执行docker run时,会调用执行"EXECUTABLE"指定的应用程序,并使用后面第二、三等参数作为应用程序的运行参数。
【语法2】ENTRYPOINT command param1 param2,...
【解析】这里的command就是shell命令。在容器启动过程中,也就是在执行docker run时,会运行指定的shell命令。
dockerfile
FROM centos:7
ENTRYPOINT ["cal"]
dockerfile
FROM centos:7
ENTRYPOINT ["/bin/bash","-c","cal"]
dockerfile
FROM centos:7
ENTRYPOINT cal 不起作用
如果ENTRYPOINT发现后面是一个shell,直接就运行shell了,不会去进行拼接
FROM centos:7
ENTRYPOINT ["cal"] OK
只有这种才会进行拼接
FROM centos:7
ENTRYPOINT ["/bin/bash","-c","cal"] 不起作用
因为这里的-y的作用对象变成/bin/bash了,会被直接忽略
CMD和ENTRYPOINT联用
dockerfile
FROM centos:7
CMD ["hello world"]
ENTRYPOINT ["echo"]
CMD中的内容就是ENTRYPOINT的参数。
也就是 echo "hello world"
总结:Dockerfile中的[command]或者["EXCUTABLE"]如果是通过CMD指定的,该镜像的启动命令docker run 中是不能添加参数[ARG]的。一位内Dockerfile中的CMD是可以被命令中[COMMAND]替代的。
如果命令中的IMAGE后依旧有内容,此时对于docker daemon来说,其首先认为是替代用的[COMMAND],如果有两个或者两个以上的内容,后面的内容才会认为是[ARG]。所以,添加的-y会报错,因为没有-y这样的[COMMAND]。
ADD
【语法1】ADD
<src>
<dest>
【语法2】ADD [
"<src>"
,"<dest>"
] #路径中存在空格时使用双引号引起来【解析】该指令将赋值当前宿主机中指定文件src到容器中的指定目录dest中。src可以是宿主机中的绝对路径,也可以是相对路径。但是相对路径是相对于docker build命令所指定的路径的。src指定的文件可以是一个压缩文件,压缩文件复制到容器后会自动解压为目录。src也可以是一个URL,此时ADD指令相当于wget。src最好不要使目录,其会将该目录中的所有内容复制到指定目录中。dest是一个绝对路径,其最后面的路径必须要加上斜杠,否则系统会将最后的目录名称当作是文件名的。
COPY
【说明】功能和ADD指令相同,不过src不能是URL,如果src为压缩文件,复制到容器后也不会自动解压。
如果COPY zookeeper.tar.gz /opt/copy/ 没有最后的 / ,表示copy是一个文件
【建议】全都加上
/
dockerfile
FROM centos:7
WORKDIR /opt
ADD zookeeper.tar.gz /opt/add/
COPY zookeeper.tar.gz /opt/copy/
CMD ["/bin/bash"]
ARG
【语法】ARG
<varname>
[=<default value>
]【解析】定义一个变量,该变量将会使用于镜像构建时。若要定义多个变量,则需要定义多个ARG指令。
dockerfile
FROM centos:7
ARG name=TOM
RUN echo $name
指定变量
bash
docker build -t myargs:2.0 --build-arg name=Jerry .
前提是这个ARG在Dockerfile中存在
ONBUILD
【语法】ONUILD [INSTRUCTION]
【解析】该指令用于指定当前镜像的子镜像进行构建时要执行的指令。
dockerfile
FROM centos:7
ENV WORKPATH /usr/local
WORKDIR $WORKPATH
ONBUILD RUN yum install -y wget
CMD ["/bin/bash"]
dockerfile
FROM parent:1.0
bash
docker build -f Dockerfile2 -t son:1.0 .
会在子镜像中安装wget
EXPOSE
【语法】RUN
<port>
[<port>...]
指定容器准备对外暴露的端口号,但该端口号并不会真正的对外暴露。如果要真的暴露,需要在执行docker run命令的时候使用-p来指定。
构建新镜像的方式总结
可以构建出新镜像的方式:
docker build
docker commit
docker import
docker compose
docker hub
中完成Automated Builds
注意:
docker load
并没有构建出新的镜像,和原镜像是同一个镜像。