Docker学习笔记之Dockerfile
阅读原文时间:2022年05月18日阅读:1

  Dockerfile的编写格式为<命令><形式参数>,命令不区分大小写,但一般使用大写字母。Docker会依据Dockerfile文件中编写的命令顺序依次执行命令。Dockerfile文件中,命令总是以FROM开始。如无FROM命令或FROM命令之前有其它命令,则无法创建镜像。此外,各个命令是独立运行的,即使用RUN cd /home 转移目录,也不会对后面的命令产生影响。

  创建镜像时,在Dockerfile所在目录下执行docker build命令。如根据Dockerfile创建一个名为example的镜像:

sudo docker build --tag example . #创建镜像

  1. .dockerignore

  所有与Dockerfile同目录下的文件都称为“上下文”。在创建镜像时,上下文都会被传送到Docker守护进程,所以有必要设置不相关的文件排除在外。如:

>>.dockerignore文件

hello.txt

  2. FROM

  FROM用于设置以哪个镜像为基础镜像。Dockerfile创建的镜像是以已有的镜像为基础的。如下所示:

>>Dockerfile文件

FROM ubuntu:latest

  命令的使用格式为FROM <镜像><标签>或FROM <镜像>。

  3. MAINTAINER

  MAINTAINER用于设置镜像创建者的信息,一般输入名字和邮箱即可。如下所示:

>>Dockerfile文件

MAINTAINER super lollipop superlollipop@163.com

  4. RUN

  RUN用于在FROM中设置的镜像上运行脚本或命令。RUN运行结果会生成新的镜像,运行的详细信息记录到镜像历史。如下所示:

>>Dockerfile文件

RUN apt install -y nginx
RUN echo "hello" >> /tmp/hello.txt

  命令格式为RUN <命令>。

  5. CMD

  CMD用于设置容器启动时运行的脚本或命令,即使用docker run命令创建容器或使用docker start命令启动停止的容器时运行。如下所示:

>>Dockerfile文件

CMD touch /home/hello.txt

  使用格式为CMD <命令>。

6. ENTRYPOINT

ENTRYPOINT用于设置容器启动时运行的脚本或命令,即使用docker run命令创建容器或使用docker start命令启动停止的容器时运行,而且ENTRYPOINT只执行一次。如下所示:

>>Dockerfile文件

ENTRYPOINT touch /home/hello.txt

  使用格式为ENTRYPOINT <命令>。

  CMD与ENTRYPOINT的区别:

>>CMD的Dockerfile文件

FROM ubuntu:latest
CMD echo "hello"

  可以看到,如果docker run命令后面附加上了CMD命令后,Dockerfile文件的CMD命令不会被执行。下面再看看ENTRYPOINT命令。

>>ENTRYPOINT的Dockerfile文件

FROM ubuntu:latest
ENTRYPOINT ["echo", "hello"]

  可以看到,后面的echo “world”命令被当成参数执行了Docekerfile里面的ENTRYPOINT设置的echo命令了。相当于在容器启动时执行了echo "hello" "echo" "world"。If the image also specifies an ENTRYPOINT then the CMD or COMMAND get appended as arguments to the ENTRYPOINT.

注意:如果Dockerfile中有多个CMD或者ENTRYPOINT,只有最后一个CMD或ENTRYPOINT会被执行,CMD和ENTRYPOINT可以组合使用。

7. EXPOSE

EXPOSE用于设置与主机相连的端口号,与docker run命令中的 --expose选项功能一致。

>>Dockerfile文件

EXPOSE 80
EXPOSE 443

  使用格式为EXPOSE <端口号>。使用一个EXPOSE也可以设置多个端口号,如上面两行可以换成EXPOSE 80 443。

  注意:EXPOSE只用于与主机进行连接,并不对外暴露。若想将端口暴露在外,需要在docker run命令添加选项-p或-P。

8. ENV

ENV用于设置环境变量。使用ENV设置的环境变量应用于RUN、CMD、ENTRYPOINT。如下所示:

>>Dockerfile文件

FROM ubuntu:latest
ENV HELLO 12345
CMD echo ${HELLO}

  

  可以看到CMD echo ${HELLO}输出了ENV设置的变量值12345。

  9. ADD

ADD用于向镜像添加文件。如下所示:

>>Dockerfile文件

FROM ubuntu:latest
ADD Diagram1.dia.autosave /Diagram1.dia.autosave
ADD apache-tomcat-9.0.24.tar.gz /

  命令格式为ADD <要复制文件的路径> <文件在镜像中的路径>

  可以看到添加到容器内的两个文件,添加的tar.gz文件会被解压。注意:要复制的文件的路径以上下文为基准,即要和Dockerfile在同一文件夹下。除此,<要添加的文件>也可以设置为目录或者网络文件的URL,如ADD hello-dir /hello-dir、ADD http://localhost:8080/apache-tomcat-9.0.24.tar.gz /。

  10. COPY

  COPY用于向镜像添加文件。与ADD不同,使用COPY添加压缩文件时,不会解压缩,也不能使用文件的URL。如下所示:

>>Dockerfile文件

FROM ubuntu:latest
COPY Diagram1.dia.autosave /Diagram1.dia.autosave
COPY apache-tomcat-9.0.24.tar.gz /

  可以看到COPY添加的tar.gz文件并没有被解压添加到容器,而是仅仅添加了压缩包文件到容器。

11. VOLUME

VOLUME设置用于将目录下的内容存储到主机而非容器。如下所示:

>>Dockerfile文件

VOLUME /data
VOLUME ["/data","/var/log/test"]

  使用格式为VOLUME <容器目录>或VOLUME ["容器目录1",“容器目录2”]。但使用VOLUME不能与主机的特定目录相连,若想连接数据卷与主机的特定目录,则必须在docker run命令中使用-v选项。

  12. USER

USER用于设置运行命令的用户账号,该用户会应用于RUN、CMD、ENTRYPOINT。如下所示:

>>Dockerfike

FROM ubuntu:latest
USER nobody
RUN touch /tmp/hello.txt

USER root
RUN touch /hello.txt

  首先以nobody用户在tmp目录下创建hello.txt文件,然后用root用户在/目录下创建hello.txt文件,只有root用户有权限在/目录下创建文件。

  可以看到/tmp/hello.txt文件的用户所有者是nobody。

  13. WORKDIR

  WORKDIR用于设置执行RUN、CMD、ENTRYPOINT命令的目录。

>>Dockerfile

WORKDIR /tmp
RUN touch hello.txt

  使用格式为WORKDIR <路径>。上述Dockerfile会在/tmp目录下创建hello.txt文件。

  14. ONBUILD

  将当前镜像作为基础镜像创建其他镜像时,ONBUILD指定用于设置一些要触发的操作。ONBUILD指定的命令在构建镜像时不会被执行,而是在其子镜像中执行。如下所示:

>>Dockerfile

FROM ubuntu:latest
ONBUILD RUN touch hello.txt

  然后创建镜像并运行容器

  发现并没有执行ONBUILD后的RUN touch hello.txt,然后我修改Docker文件,再以此创建的镜像再次创建镜像exampletest2

>>Dockerfile文件

FROM exampletest1

  

  创建镜像exapletest2后并且运行容器,ONBUILD触发执行了,容器内存在文件hello.txt。