DockerFile详解


DockerFile是用来构建Docker镜像的文本文件,是有一条条构建镜像所需的指令和参数构成的脚本。

构建三步骤

1、编写DockerFile文件
2、docker build命令构建镜像
3、docker run 依镜像运行容器实例

DockerFile内容基础知识

  1. 每条保留字指令都必须为大写字母且后面跟随至少一个参数
  2. 指令按照从上到下,顺序执行
  3. # 表示注释
  4. 每条指令都会创建一个新的镜像层并对镜像进行提交。

图示

在这里插入图片描述

  1. Dockerfile,需要定义一个Dockerfile,Dockerfile定义了进程需要的一切东西。Dockerfile涉及的内容包括执行代码或者是文件、环境变量、依赖包、运行时环境、动态链接库、操作系统的发行版、服务进程和内核进程(当应用进程需要和系统服务和内核进程打交道,这时需要考虑如何设计namespace的权限控制)等等;

  2. Docker镜像,在用Dockerfile定义一个文件之后,docker build时会产生一个Docker镜像,当运行 Docker镜像时会真正开始提供服务;

  3. Docker容器,容器是直接提供服务的。

DockerFile常用保留字指令

关键字作用备注
FROM指定父镜像指定dockerfile基于那个image构建
MAINTAINER作者信息用来标明这个dockerfile谁写的
LABEL标签用来标明dockerfile的标签 可以使用Label代替Maintainer 最终都是在docker image基本信息中可以查看
RUN执行命令执行一段命令 默认是/bin/sh 格式: RUN command 或者 RUN [“command” , “param1”,“param2”]
CMD容器启动命令提供启动容器时候的默认命令 和ENTRYPOINT配合使用.格式 CMD command param1 param2 或者 CMD [“command” , “param1”,“param2”]
ENTRYPOINT入口一般在制作一些执行就关闭的容器中会使用
COPY复制文件build的时候复制文件到image中
ADD添加文件build的时候添加文件到image中 不仅仅局限于当前build上下文 可以来源于远程服务
ENV环境变量指定build时候的环境变量 可以在启动的容器的时候 通过-e覆盖 格式ENV name=value
ARG构建参数构建参数 只在构建的时候使用的参数 如果有ENV 那么ENV的相同名字的值始终覆盖arg的参数
VOLUME定义外部可以挂载的数据卷指定build的image那些目录可以启动的时候挂载到文件系统中 启动容器的时候使用 -v 绑定 格式 VOLUME [“目录”]
EXPOSE暴露端口定义容器运行的时候监听的端口 启动容器的使用-p来绑定暴露端口 格式: EXPOSE 8080 或者 EXPOSE 8080/udp
WORKDIR工作目录指定容器内部的工作目录 如果没有创建则自动创建 如果指定/ 使用的是绝对地址 如果不是/开头那么是在上一条workdir的路径的相对路径
USER指定执行用户指定build或者启动的时候 用户 在RUN CMD ENTRYPONT执行的时候的用户
HEALTHCHECK健康检查指定监测当前容器的健康监测的命令 基本上没用 因为很多时候 应用本身有健康监测机制
ONBUILD触发器当存在ONBUILD关键字的镜像作为基础镜像的时候 当执行FROM完成之后 会执行 ONBUILD的命令 但是不影响当前镜像 用处也不怎么大
STOPSIGNAL发送信号量到宿主机该STOPSIGNAL指令设置将发送到容器的系统调用信号以退出。
SHELL指定执行脚本的shell指定RUN CMD ENTRYPOINT 执行命令的时候 使用的shell

FROM

基础镜像,当前新镜像是基于哪个镜像的,指定一个已经存在的镜像作为模板

下面以定制一个 nginx 镜像(构建好的镜像内会有一个 /usr/share/nginx/html/index.html 文件)

FROM nginx
RUN echo '这是一个本地构建的nginx镜像' > /usr/share/nginx/html/index.html

MANINTAINER

在 Dockerfile 中,MAINTAINER 是一个旧版本的指令,用于指定镜像的维护者信息。然而,自Docker 1.13版本开始,MAINTAINER 指令被标记为过时(deprecated),不再建议使用。

MAINTAINER 指令的作用是在镜像的元数据中添加维护者的姓名和电子邮件地址。它的语法如下:

MAINTAINER <姓名> <电子邮件地址>

它在镜像构建过程中没有实际的功能性作用,而是用于提供人类可读的信息。在使用 Docker Hub 或其他镜像仓库时,这些信息可以帮助其他用户联系到镜像的维护者或提供反馈。

然而,建议使用更现代的指令 LABEL 来替代 MAINTAINERLABEL 指令允许添加自定义的键值对元数据,包括维护者的信息。以下是使用 LABEL 指令指定维护者信息的示例:

LABEL maintainer="<姓名> <电子邮件地址>"

使用 LABEL 指令不仅可以提供维护者信息,还可以添加其他自定义元数据,例如版本号、描述、构建日期等,使镜像的元数据更丰富和有用。

LABEL maintainer="<维护者姓名> <维护者电子邮件地址>"
LABEL version="1.0"
LABEL description="这是一个示例镜像"
LABEL build_date="2023-07-05"

EXPOSE

在 Dockerfile 中,EXPOSE 是用于指定容器运行时将要监听的端口的指令。它不会实际打开或发布端口,而是向用户和开发人员提供了一个提示,表明容器在运行时可能使用的网络接口。

EXPOSE 指令的语法如下:

EXPOSE <port> [<port>/<protocol>...]

其中,<port> 是要暴露的端口号,可以是单个端口,也可以是一系列用空格或逗号分隔的端口。您还可以使用 <port>/<protocol> 的形式指定特定的协议,如 TCP 或 UDP。

示例:

EXPOSE 80
EXPOSE 8080/tcp
EXPOSE 9000/tcp 9000/udp

EXPOSE 指令的作用是为了方便用户和开发人员知道容器映射的端口,以便在运行容器时进行正确的端口绑定。它在运行容器时没有直接的功能性作用,仅提供了一个文档化的方式来描述容器所需的端口。

要在运行容器时实际发布和映射端口,需要使用 -p-P 参数来指定端口映射规则。例如:

docker run -p 8080:80 my-image

上述命令将容器的端口 80 映射到主机的端口 8080,从而使主机上的请求能够访问容器中运行的服务。

WORKDIR

在 Dockerfile 中,WORKDIR 是用于设置容器内部的工作目录(working directory)的指令。它指定了在容器中运行命令时的默认路径。

WORKDIR 指令的语法如下:

WORKDIR <directory>

其中,<directory> 是要设置的工作目录路径。可以是绝对路径或相对于之前指定的工作目录的路径。

示例:

WORKDIR /app

上述示例将容器内部的工作目录设置为 /app

WORKDIR 指令的作用是为了方便在后续的命令中操作容器中的文件和目录。例如,使用 COPY 指令将文件复制到容器中时,可以相对于工作目录指定源文件的路径。运行其他命令时,也可以相对于工作目录来引用文件和目录。

请注意,WORKDIR 指令可以多次使用。每次使用时,都会覆盖之前的工作目录设置。如果在 Dockerfile 中没有指定 WORKDIR 指令,则默认工作目录为根目录 /

使用 WORKDIR 指令可以提高 Dockerfile 的可读性,并确保在容器中运行的命令可以正确地引用文件和目录。

USER

在 Dockerfile 中,USER 是用于指定在容器中运行后续命令时所使用的非特权用户的指令。它允许您切换到指定的非特权用户,以增加容器的安全性和降低潜在的风险。

USER 指令的语法如下:

USER <username>

其中,<username> 是要切换到的非特权用户的用户名。这个用户名必须是容器镜像中已经存在的用户。通常,容器镜像中都会预先创建一个非特权用户,以便在运行容器时切换到这个用户。

使用 USER 指令的好处是,在容器中运行的应用程序或服务将以非特权用户的身份运行,从而减少了攻击者利用容器进行潜在攻击的可能性。特权用户可能会对容器及其宿主系统造成更大的安全风险,因为攻击者可以利用特权权限进行更多的破坏。

示例:

# 在镜像中创建一个名为 "appuser" 的非特权用户
RUN useradd -m appuser

# 切换到 "appuser" 用户
USER appuser

# 在这之后的命令都将以 "appuser" 用户的身份运行
CMD ["python", "app.py"]

请注意,使用 USER 指令后,后续的命令都会以指定的非特权用户的身份运行,直到遇到另一个 USER 指令或其他涉及用户权限的指令(例如 RUN useradd)。如果在 Dockerfile 中没有指定 USER 指令,默认情况下会使用容器镜像中的默认非特权用户(通常是 root 用户)运行容器中的命令。

ENV&ARG

ENV

在 Dockerfile 中,ENV 是用于设置环境变量的指令。它允许您在镜像构建过程中设置持久的环境变量,这些变量可以在容器运行时被访问和使用。

ENV 指令的语法如下:

ENV <key>=<value>
ENV <key> <value>
ENV <key1>=<value1> <key2>=<value2>...

其中,<key> 是环境变量的名称,<value> 是要设置的值。您可以通过等号将键和值连接在一起。也可以通过多个 ENV 指令设置多个环境变量。

示例:

ENV APP_VERSION=1.0
ENV DB_HOST=localhost DB_PORT=5432

上述示例中,我们设置了两个环境变量:APP_VERSIONDB_HOSTDB_PORT。这些环境变量可以在容器运行时使用,例如在启动脚本、应用程序代码或其他命令中引用它们。

ENV 指令的作用是为了提供可配置和可重用的环境配置。通过将环境变量设置为特定的值,可以轻松地修改容器中应用程序的行为,而无需修改 Dockerfile 或重新构建镜像。

您还可以在运行容器时使用 -e 参数或 --env 参数来覆盖或添加环境变量的值。例如:

docker run -e DB_HOST=mydbhost -e DB_PORT=5433 my-image

上述命令将覆盖镜像中设置的 DB_HOSTDB_PORT 环境变量的值。

可以在 RUN 指令中使用环境变量,并且在 Dockerfile 中的其他位置也可以通过 ${VAR_NAME} 的方式引用环境变量。例如:

ENV MY_VAR hello
RUN echo "The value of MY_VAR is ${MY_VAR}"

这将在构建镜像时输出:The value of MY_VAR is hello。

ARG

在 Dockerfile 中,ARG 是用于定义构建参数(build-time arguments)的指令。它允许您在构建镜像时传递参数,并在 Dockerfile 中使用这些参数。

ARG 指令的语法如下:

ARG <name>[=<default value>]

其中,<name> 是参数的名称,可以在 Dockerfile 中使用这个名称引用参数的值。<default value> 是可选的默认值,当构建命令没有指定参数值时使用。

示例:

ARG APP_VERSION=1.0.0
ARG BUILD_ENV

上述示例定义了两个构建参数,APP_VERSIONBUILD_ENVAPP_VERSION 参数具有默认值为 “1.0.0”,而 BUILD_ENV 参数没有默认值。

在 Dockerfile 中,您可以使用 ${<name>} 的形式引用构建参数的值。例如:

ENV VERSION=${APP_VERSION}

上述示例使用了构建参数 APP_VERSION 的值,并将其赋给环境变量 VERSION

构建镜像时,您可以通过在 docker build 命令中使用 --build-arg 标志来传递参数值。例如:

docker build --build-arg APP_VERSION=2.0.0 .

上述命令将构建参数 APP_VERSION 的值设置为 “2.0.0”。

使用 ARG 指令可以使您的镜像构建过程更具灵活性,允许您在构建时根据需要动态地传递参数。这对于在构建多个环境(如开发环境和生产环境)中使用相同的 Dockerfile,并根据环境的不同进行一些自定义配置非常有用。

要传递多个构建参数(build-arg),您可以在 docker build 命令中使用多个 --build-arg 标志。每个标志后面跟着构建参数的名称和值。

以下是一个示例命令,演示如何传递多个构建参数:

docker build --build-arg ARG1=value1 --build-arg ARG2=value2 .

上述命令中,ARG1ARG2 是构建参数的名称,value1value2 是对应的值。在 Dockerfile 中,您可以通过 ${<name>} 的形式引用这些构建参数的值。

例如,假设在 Dockerfile 中定义了两个构建参数 APP_VERSIONENVIRONMENT

ARG APP_VERSION
ARG ENVIRONMENT

ENV VERSION=${APP_VERSION}
ENV ENVIRONMENT=${ENVIRONMENT}

您可以使用以下命令将这些构建参数的值传递给 docker build

docker build --build-arg APP_VERSION=1.0.0 --build-arg ENVIRONMENT=production .

上述命令将构建参数 APP_VERSION 设置为 “1.0.0”,ENVIRONMENT 设置为 “production”。

通过这种方式,您可以传递任意数量的构建参数,只需在 docker build 命令中使用适当的 --build-arg 标志即可。

ADD&CoPY

ADD

在 Dockerfile 中,ADD 是用于将文件、目录或远程 URL 复制到容器中的指令。它类似于 COPY 指令,但在一些特定情况下具有更多的功能。

ADD 指令的语法如下:

ADD <src> <dest>

其中,<src> 是源文件、目录或 URL 的路径,可以是相对于构建上下文的相对路径,也可以是一个完整的 URL。<dest> 是目标路径,指定了文件或目录复制到容器中的位置。

示例:

ADD app.jar /app/
ADD http://example.com/file.tar.gz /data/

上述示例将当前构建上下文中的 app.jar 文件复制到容器的 /app/ 目录中,同时将远程 URL http://example.com/file.tar.gz 下载并复制到容器的 /data/ 目录中。

ADD 指令与 COPY 指令的不同之处在于,ADD 指令可以自动解压缩压缩文件(如 .tar、.gz、.zip 等)。如果源文件是一个压缩文件,ADD 指令会在复制到容器后自动解压缩。这在将压缩文件复制到容器中并进行解压操作时非常方便。

请注意,如果您只需要简单地将文件或目录复制到容器中,而不需要自动解压缩功能,请使用 COPY 指令,因为它是更常用的指令。只有在确实需要自动解压缩的情况下,才使用 ADD 指令。

此外,需要注意的是,ADD 指令在构建镜像时,会自动根据文件的内容进行缓存,而不是根据文件的修改时间。这意味着,如果文件内容没有发生改变,即使源文件更新,Docker 在构建镜像时也会使用缓存,而不会重新复制文件。这可能会导致一些不符合预期的结果,因此在使用 ADD 指令时应当小心处理。

COPY

在 Dockerfile 中,COPY 是用于将文件或目录复制到容器中的指令。它允许您将本地文件系统上的文件复制到容器镜像中指定的目录。

COPY 指令的语法如下:

COPY <src> <dest>

其中,<src> 是要复制的源文件或目录的路径,可以是相对于构建上下文的相对路径。<dest> 是目标路径,指定了文件或目录复制到容器中的位置。

示例:

COPY app.jar /app/
COPY config/ /app/config/

上述示例将当前构建上下文中的 app.jar 文件复制到容器的 /app/ 目录中,同时将当前构建上下文中的 config/ 目录复制到容器的 /app/config/ 目录中。

COPY 指令只用于复制本地文件到容器中,并且它会保持文件的原始权限和属性。在构建镜像时,源文件会从构建上下文中复制到镜像中,而不会从远程 URL 下载或解压文件。

相对于 ADD 指令,COPY 指令更为常见,特别是在您只需要简单地将本地文件或目录复制到容器中时。如果您需要复制压缩文件并在容器中进行解压缩等更高级的操作,可以考虑使用 ADD 指令。

请注意,在 COPY 指令中,如果目标路径以斜杠(/)结尾,它将被视为目录,而不是文件。如果目标路径不存在,Docker 将自动创建它。

此外,与 ADD 指令类似,COPY 指令在构建镜像时会自动根据文件的内容进行缓存。因此,在文件内容没有更改的情况下,Docker 在构建镜像时会重复使用缓存的结果。这有助于提高构建速度,但也需要注意在使用 COPY 指令时的缓存问题。

COPY . /

COPY . / 是 Dockerfile 中的一条指令,表示将当前构建上下文中的所有文件和目录复制到容器的根目录 / 中。

在 Dockerfile 中,COPY 指令用于将本地文件或目录复制到容器镜像中。. 是表示当前目录的特殊符号,代表当前构建上下文的根目录。因此,COPY . / 表示将当前构建上下文中的所有文件和目录复制到容器的根目录。

这条指令的效果是将构建上下文中的所有内容复制到容器镜像的根目录下,包括 Dockerfile 所在的目录中的所有文件和子目录。

需要注意的是,这样的复制可能会导致不必要的文件复制,增加镜像大小,并且可能包含一些不应该出现在镜像中的敏感文件。因此,在编写 Dockerfile 时,建议使用更明确和精确的路径来指定要复制的文件和目录,而不要过度使用 COPY . / 这样的泛用指令。

VOLUME

在 Dockerfile 中,VOLUME 是用于指定容器中的挂载点的指令。它允许您在镜像中声明一个或多个目录,这些目录可以在容器运行时被挂载为卷(volume),用于持久化数据或与其他容器共享数据。

VOLUME 指令的语法如下:

VOLUME ["<mountpoint>", ...]

其中,<mountpoint> 是要声明为挂载点的目录路径。您可以指定一个或多个目录,用逗号分隔。每个指定的目录路径将作为容器的挂载点。

示例:

VOLUME ["/data", "/config"]

上述示例将 /data/config 目录声明为容器的挂载点。

使用 VOLUME 指令声明的挂载点具有以下特性:

  1. 容器中的挂载点可以与主机上的目录或其他容器的卷进行绑定,以实现数据的持久化和共享。
  2. 挂载点中的数据不会随着容器的删除而丢失。即使容器被删除,挂载的数据仍然可以在其他容器中访问。
  3. 挂载点的数据可以被容器内的应用程序读写,类似于在容器中的本地文件系统上操作文件。
  4. VOLUME 指令可以在 Dockerfile 中多次使用,以声明多个挂载点。

请注意,使用 VOLUME 指令声明的挂载点在容器运行时是可以被忽略的。这意味着,即使没有显式地将宿主机目录或其他卷与挂载点进行绑定,容器仍然可以正常运行,但其中的数据将不会持久化到主机上。

当在 Dockerfile 中使用 VOLUME 指令声明挂载点时,它主要用于提供一个标记或文档,以指示用户或其他开发者可以在容器运行时通过挂载来处理特定目录。

即使在 Dockerfile 中没有显式使用 VOLUME 指令声明挂载点,仍然可以通过在 docker run 命令中使用 -v--volume 标志来挂载文件或目录到容器中。

挂载文件或目录到容器时,可以使用以下格式:

docker run -v <host-path>:<container-path> ...

其中,<host-path> 是主机上的文件或目录路径,<container-path> 是容器中的目标挂载路径。

示例:

docker run -v /host/data:/container/data ...

上述示例将主机上的 /host/data 目录挂载到容器内的 /container/data 目录。

通过使用 -v--volume 标志,可以在容器运行时自定义挂载点,并与主机上的文件或目录进行绑定。这种方式不需要在 Dockerfile 中显式声明挂载点,而是在容器运行时通过命令行参数进行指定。

请注意,使用 VOLUME 指令在 Dockerfile 中声明挂载点具有一些额外的好处,例如更好的可读性和文档化,以及在使用 docker inspect 命令查看容器元数据时能够清楚地显示挂载点。但即使没有在 Dockerfile 中声明挂载点,仍然可以通过命令行参数进行挂载。

CMD&RUN

CMD

在 Dockerfile 中,CMD 是用于指定容器启动时要执行的默认命令或应用程序的指令。它可以定义容器的默认行为。

CMD 指令有两种不同的形式:

  1. Shell 形式(Shell form):

    CMD command param1 param2
    

    在 Shell 形式中,command 是要执行的命令,param1param2 等是命令的参数。当容器启动时,Docker 会使用 Shell 来解析该命令,并在容器中执行。例如:

    CMD echo "Hello, Docker!"
    

    上述示例中的命令 echo "Hello, Docker!" 将作为容器启动时的默认命令。

  2. Exec 形式(Exec form):

    CMD ["executable", "param1", "param2"]
    

    在 Exec 形式中,executable 是要执行的可执行文件或应用程序,param1param2 等是执行该程序时的参数。与 Shell 形式不同,Exec 形式不会通过 Shell 解析命令,而是直接在容器中执行指定的可执行文件或应用程序。例如:

    CMD ["java", "-jar", "app.jar"]
    

    上述示例中的命令 java -jar app.jar 将作为容器启动时的默认命令。

CMD 指令在 Dockerfile 中只能出现一次。如果多次使用 CMD 指令,则只有最后一条 CMD 指令会生效。

当使用 docker run 启动容器时,可以覆盖 Dockerfile 中指定的默认命令,提供自定义的命令或参数。例如:

docker run myimage echo "Custom command"

上述命令将覆盖 Dockerfile 中的默认命令,并执行 echo "Custom command"

需要注意的是,CMD 指令不会在构建镜像过程中执行任何操作,它只会在容器启动时生效。如果需要在构建镜像时执行特定命令,可以使用 RUN 指令。

RUN

在 Dockerfile 中,RUN 是用于在镜像构建过程中执行命令的指令。它允许您在容器中运行任何有效的命令,例如安装软件包、配置环境、下载文件等。每个 RUN 指令都会在当前镜像的一个新的临时容器上执行,然后将结果提交为一个新的镜像层,从而构建出一个新的镜像。

RUN 指令的基本语法如下:

RUN <command>

在上面的语法中,<command> 是您要在容器中执行的命令。可以使用 Shell 命令或其他可执行的脚本命令。例如:

RUN apt-get update && apt-get install -y python3
RUN mkdir /app && cd /app && git clone <repository-url>
RUN wget https://example.com/file.tar.gz && tar -xvzf file.tar.gz

每个 RUN 指令都会生成一个新的镜像层。因此,在书写 Dockerfile 时,通常建议将多个命令合并成一个 RUN 指令,以减少镜像层的数量,从而优化镜像构建的性能和减少镜像的大小。

请注意,每个 RUN 指令都会在其自己的临时容器中执行命令,所以一些在运行时需要保持状态的命令(例如更改环境变量)在一个 RUN 指令中执行可能无法影响后续 RUN 指令。对于需要保持状态的操作,可以使用其他指令如 ENVWORKDIR 来实现。

CMD和RUN的区别

CMDRUN 是 Dockerfile 中两个不同的指令,它们在功能和使用方式上有着明显的区别。

  1. RUN 指令:

    • RUN 指令用于在镜像构建过程中执行命令,并在构建过程中对镜像进行修改。
    • 在 Dockerfile 中,RUN 指令通常用于安装软件包、运行脚本、设置环境等操作。
    • RUN 指令会创建一个新的镜像层,并在其中执行指定的命令。每个 RUN 指令都会生成一个新的镜像层,因此建议通过链式调用来合并多个 RUN 指令,以减少镜像层的数量,优化镜像的构建效率。
    • 示例:
      RUN apt-get update && apt-get install -y curl
      
  2. CMD 指令:

    • CMD 指令用于定义容器启动时的默认命令或应用程序。
    • 在 Dockerfile 中,CMD 指令只能出现一次,并且会覆盖之前的任何 CMD 指令。如果容器启动命令没有被显式指定,那么 CMD 指令中定义的命令将作为容器的默认命令。
    • CMD 指令可以有两种形式:Shell 形式和 Exec 形式。
      • Shell 形式示例:CMD echo "Hello, Docker!"
      • Exec 形式示例:CMD ["java", "-jar", "app.jar"]
    • CMD 指令不会在构建镜像过程中执行命令,而是在容器启动时生效。
    • 示例:
      CMD echo "Hello, Docker!"
      

总结:

  • RUN 指令用于在构建镜像过程中执行命令,对镜像进行修改。
  • CMD 指令用于定义容器启动时的默认命令或应用程序。
  • RUN 指令在镜像构建过程中执行,而 CMD 指令在容器启动时生效。
  • RUN 指令可以多次出现,每次执行命令都会生成一个新的镜像层。而 CMD 指令只能出现一次,覆盖之前的任何 CMD 指令。
  • RUN 指令用于构建镜像,而 CMD 指令用于定义容器的默认行为。

ENTRYPOINT

在 Dockerfile 中,ENTRYPOINT 是用于指定容器启动时要执行的默认命令或应用程序的指令,类似于 CMD 指令。它也可以定义容器的默认行为。

ENTRYPOINT 指令有两种不同的形式:

  1. Shell 形式(Shell form):

    ENTRYPOINT command param1 param2
    

    在 Shell 形式中,command 是要执行的命令,param1param2 等是命令的参数。当容器启动时,Docker 会使用 Shell 来解析该命令,并在容器中执行。与 CMD 不同的是,ENTRYPOINT 的命令部分是不可被覆盖的,只有参数部分可以被替换。

    例如:

    ENTRYPOINT echo "Hello, Docker!"
    

    上述示例中的命令 echo "Hello, Docker!" 将作为容器启动时的默认命令,而且无法通过命令行参数覆盖。

  2. Exec 形式(Exec form):

    ENTRYPOINT ["executable", "param1", "param2"]
    

    在 Exec 形式中,executable 是要执行的可执行文件或应用程序,param1param2 等是执行该程序时的参数。与 Shell 形式不同,Exec 形式不会通过 Shell 解析命令,而是直接在容器中执行指定的可执行文件或应用程序。与 CMD 不同的是,ENTRYPOINT 的命令和参数都是不可被覆盖的。

    例如:

    ENTRYPOINT ["java", "-jar", "app.jar"]
    

    上述示例中的命令 java -jar app.jar 将作为容器启动时的默认命令,无法通过命令行参数覆盖。

CMD 不同,ENTRYPOINT 的主要目的是定义容器的主要执行命令或应用程序,它提供了容器的主要入口点。ENTRYPOINT 通常与 CMD 结合使用,CMD 作为 ENTRYPOINT 的默认参数,以允许用户在容器启动时提供额外的参数或覆盖默认参数。

例如,在 Dockerfile 中同时使用 ENTRYPOINTCMD

ENTRYPOINT ["java", "-jar", "app.jar"]
CMD ["--config", "config.yml"]

上述示例中,java -jar app.jarENTRYPOINT 的默认命令,而 --config config.ymlCMD 提供的默认参数。这意味着在容器启动时,如果没有提供其他命令,容器将执行 java -jar app.jar --config config.yml

需要注意的是,ENTRYPOINT 指令不会在构建镜像过程中执行任何操作,它只会在容器启动时生效。如果需要在构建镜像时执行特定命令,可以使用 RUN 指令。

在这里插入图片描述

优点:在执行docker run 的时候可以指定 ENTRYPOINT 运行所需的参数。

注意:如果Dockerfile 中如果存在多个 ENTRYPOINT 指令,最后一个生效。

总结

在这里插入图片描述

案例

vim Dockerfile

FROM centos
MAINTAINER Genralzy<xxxx@qq.com> 

# 配置work目录
# 与 WORKDIR /usr/local 等价
ENV MYPATH /usr/local 
WORKDIR $MYPATH 
  
#安装vim编辑器 
RUN yum -y install vim 
#安装ifconfig命令查看网络IP 
RUN yum -y install net-tools 
#安装java8及lib库 
RUN yum -y install glibc.i686 
RUN mkdir /usr/local/java 

#ADD 是相对路径jar,把jdk-8u171-linux-x64.tar.gz添加到容器中,安装包必须要和Dockerfile文件在同一位置 
ADD jdk-8u171-linux-x64.tar.gz /usr/local/java/ 

#配置java环境变量 
ENV JAVA_HOME /usr/local/java/jdk1.8.0_171 
ENV JRE_HOME $JAVA_HOME/jre 
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib:$CLASSPATH 
ENV PATH $JAVA_HOME/bin:$PATH 

# 暴露80端口
EXPOSE 80 

# docker run时执行cmd命令
CMD echo $MYPATH 
CMD echo "success--------------ok" 
CMD /bin/bash 

构建

docker build -t 新镜像名字: TAG

例如:docker build -t centosjava8:1.5 .

【注意】
上面TAG 后面有个空格,有个点

运行

docker run -it 新镜像名字:TAG

docker run -it centosjava8:1.5 /bin/bash 
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Generalzy

文章对您有帮助,倍感荣幸

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值