最近使用Dockerfile打镜像,简单总结了一下语法规则,分享给大家,如有错误,请大家即时指正。
【RUN CMD ENTRYPOINT】:
RUN:执行命令并创建新的镜像层,通常用于安装软件包。用于指定 docker build 过程中要运行的命令。
CMD:容器启动后需要执行的命令,CMD的命令可以被 docker run 的命令所覆盖,
只要docker run中制定了新的命令,那么CMD一定不会执行。
如果Dockerfile中有多个CMD命令,则只有最后一个生效。
ENTRYPOINT:容器启动时需要执行的命令,即时 docker run 中指定了其他的命令,ENTRYPOINT依然会被执行。
指令用于设定容器启动时第一个运行的命令及其参数。
如果Dockerfile中有多个ENTRYPOINT命令,则只有最后一个生效
# CMD可以为ENTRYPOINT提供额外的参数,如下:
NETRYPOINT ["/bin/echo","hello"]
CMD ["world"]
# 输出结果为:hello world
shell格式运行命令:RUN java -jar xxxx.jar
------------------------
# CMD执行多条命令
CMD yum -y istall net-tools /
&& java -jar xxxx.jar
exec 格式运行命令:ENTRYPOINT ["java","-jar","xxxx.jar"]
ENTRYPOINT ["sh","-c","java -c ${jar_path}"] #推荐,因为可以使用变量
【COPY ADD】:
COPY:复制宿主机的文件到容器,不会解压压缩包
ADD:复制宿主机的文件到容器,自动解压压缩包
COPY <源路径> <目标路径>
ADD <源路径> <目标路径>
-----------------------
其中 <源路径>为宿主机路径,<目标路径>为容器中的路径,目标路径不需要提前存在
【ENV ARG】
ENV:给容器设置环境变量,我们可以知道 容器 底层是一个linux,ENV的值会持久化到/etc/profil中,在Dockerfile中当变量使用。
ARG:在Dockerfile中当变量使用的。
二者的区别:作用域不同,ENV的作用域是作用域整个容器,ARG的作用域是只限于Dockerfile
值得注意的是,RUN CMD ENTRYPOINT 中不能直接使用ARG
-------------------------------
ENV JAVA_HOME /opt/jdk/jdk1.8.0_181
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV PATH $PATH:$JAVA_HOME/bin
ARG NAME studioustiger
【VOLUME】
VOLUME:用于挂载容器目录到宿主机;在启动容器 docker run 的时候,我们可以通过 -v 修改挂载节点
为了容器的可移植性,VOLUME只支持匿名挂载,如果想要实现具名挂载,可以通过 docker run -v 具名挂载
可以通过 [docker volumn inspect 容器名/ID] 查看数据卷的挂载情况
---------------------
VOLUME ["容器目录1","容器目录2",...]
【EXPOSE】
EXPOSE:仅仅用于声明端口号,EXPOSE声明的是容器中的端口号,其作用是用于告诉 docker run 容器要暴露的端口号。
当我们执行 docker run -P 的时候,会将 EXPOSE 的端口与宿主机的一个随机端口进行端口映射,我们可以通
过 [docker inspect 容器名/ID] 查看端口的映射情况
如果我们想要使得宿主机的端口与 EXPOSE 保持一致,那么可以使用 [docker run --net=network名]
-------------
EXPOSE 8080
【WORKDIR】
WORKDIR:在 WORKDIR 中需要使用绝对路径,如果镜像中对应的路径不存在,会自动创建此目录。
在Dockerfile中一般使用WORKDIR来代替‘切换目录’的操作,我们知道 RUN 每执行一次都会创建一个镜像层,
例如我们切换目录并打印路径:
RUN cd /usr
RUN pwd # 打印的结果是 /
我们可以看到,使用RUN切换路径只会在当前镜像层中其作用,当执行第二个RUN后,第一个RUN的指令并不会作用
于第二个RUN的镜像。
当我们使用WORKDIR后,WORKDIR将会作用于所有的镜像层
WORKDIR /usr
RUN pwd # 打印的结果是 /usr
【ONBUILD】
ONBUILD:当Dockerfile构建了镜像meImage1中使用了ONBUILD,那么 ONBUILD 并不会在构建meImage1镜像过程中被执行;
当Dockerfile构建了镜像meImage2中使用了 FROM meImage1,那么在构建meImage2镜像时,meImage1中的ONBUILD将会被执行。
ONBUILD就像是一个触发器,当别人(Dockerfile)用到(FROM)自己的时候,我自己触发执行自己的ONBUILD。
-----------------
ONBUILD Dockerfile的任何指令 ,如下例:
ONBUILD RUN ["java","-jar","xxx.jar"]