Dockerfile简介及其各种说明

152 阅读5分钟

什么是Dockerfile

Dockerfile是一个特殊的文本文件,包含了构建镜像所需的所有命令。Docker读取Dockerfile,并根据Dockerfile中提供的命令和说明构建一个镜像。

一个Docker镜像遵循一个分层架构。Dockerfile中的每一行都在镜像的架构中形成一个新的层。Docker缓存了镜像的各个层,因此在镜像构建工作中,每次都会重复使用这些未改变的缓存层,而不是每次都重建整个镜像。

如何编写Docker文件

编写Docker文件的基本语法是

INSTRUCTION ARGUMENTS

指令应始终使用大写字母。在编写Docker文件时,最好的做法是将这些行放在最后,这一点因每个镜像的构建而异。我们写Docker文件需要的一些基本指令如下。

每个Docker镜像都需要一个基础镜像,该镜像是在此基础上构建的。所以我们需要在FROM指令中提到基础镜像的名字。

如果基础镜像不在Docker主机中,它将从中央资源库(即DockerHub)中获取镜像。

语法。
FROM openjdk:jdk AS builder

这里的builder是指向在这个阶段构建的镜像的别名。 我们可以在另一个构建阶段使用这个镜像作为基础镜像。在上面的例子中,jdk是一个标签,指定了基础镜像的版本。如果没有指定这个标签,它将拉动最新的版本。

RUN

我们使用RUN指令在当前镜像上运行任何命令。这种执行命令的结果是在图像构建中创建一个新的层。我们在Docker文件中可以有多个RUN指令。它有两种形式。

语法。
  • 可执行形式。
RUN ["apt","install","python"]
  • Shell形式。
RUN apt install python

ARG

ARG指令用于在镜像的构建阶段传递一个值。我们可以使用传递的值来设置Docker文件中的任何命令。它是唯一可以在FROM指令之前的指令。一个Dockerfile可以有多个ARG指令。

语法。
ARG version=jdk
FROM openjdk:$version

使用-build-arg标志,我们可以在镜像构建时传递参数值。

docker build --build-arg version="18-jdk" -t custom-image:latest .

工作目录(WORKDIR

我们可以通过使用WORKDIR指令在镜像中设置一个工作目录。因此,所有下面的指令都在这个目录内执行。如果该目录不存在,Docker会创建它。

语法。
WORKDIR ~/workingDirectory

ENV

我们使用ENV指令来设置镜像的环境变量。环境变量是以键值对的形式设置的。该值在以下所有命令中保持不变,但我们可以在容器的执行过程中改变该值。

语法。
ENV username root
#Here we set a default value to the environment variable, username=root 

EXPOSE

我们使用EXPOSE指令来指定容器化应用程序在运行期间将监听的端口。使用EXPOSE可以指定多个端口。

默认情况下,暴露的端口监听TCP协议。协议也可以与端口一起指定。

语法。
#EXPOSE <port>/<protocol>

EXPOSE 80 443
# Specifying the protocols
EXPOSE 80/tcp 443/udp 

ADD

我们使用ADD指令来复制文件、目录和远程URL文件到Docker镜像中。

当从Docker主机复制一个tarball文件到镜像中的任何位置时,ADD指令不仅会复制文件,还会自动提取tarball文件。

语法。
#ADD source1 source2 sourceN destination
ADD ~/localFolder/File.java ~/folderInsideImage

复制

我们使用COPY指令来复制文件和目录到Docker镜像中。ADD和COPY的区别在于,当从Docker主机复制一个tarball到镜像中的任何位置时,COPY指令会复制tarball文件的原样。

语法。
#COPY source1 source2 sourceN destination
COPY ~/localFolder/Application.java ~/folderInsideImage

CMD

我们使用CMD指令来设置一个在运行容器时将被执行的命令。一个Docker文件中必须有一个CMD。如果文件中存在多个CMD,则最后一个CMD生效。我们可以覆盖CMD指令如果用户在运行命令后面加上要执行的命令,那么CMD指令可以被覆盖。

语法。
  • 可执行形式。
CMD ["java","Application"]
  • Shell形式。
CMD java Application
覆盖CMD指令
# docker run image_name:tag <instruction> <argument>
docker run -d custom-image:latest javac Application.java 

ENTRYPOINT

我们使用 ENTRYPOINT 指令来设置作为容器入口点的命令。换句话说,它们将在容器被执行时始终运行。与CMD不同,我们只有在添加
--entrypoint
标志时才能覆盖ENTRYPOINT指令
。否则,我们只能附加到ENTRYPOINT命令上。

语法。
  • 可执行形式。
ENTRYPOINT ["java","Application"]
  • Shell形式。
ENTRYPOINT java Application

如果我们需要一个具有指定可执行文件和默认参数的容器,我们可以将ENTRYPOINTCMD结合起来。

用户

Docker容器默认以Root用户的身份运行。我们使用USER指令来改变容器内的用户。我们可以使用RUN指令创建一个新的用户,然后我们可以使用USER指令来切换默认用户。

语法。
RUN useradd newUser
USER newUser

结论

读完这篇博客后,你将熟悉如何编写Docker文件来构建一个自定义镜像。这篇博客涵盖了编写Dockerfile所需的说明。我已经提供了Dockerfile的官方网页链接。如果你需要更多关于Dockerfile的详细介绍,你可以前往该网站。

参考资料