胖蔡说技术
随便扯扯

Dockerfile镜像构建基础

Docker可以通过从Dockerfile中读取指令来自动构建图像。Dockerfile是一个文本文档,其中包含用户可以在命令行上调用以组装图像的所有命令。本文介绍了可以在Dockerfile中使用的命令。

概述

编写Dockerfile文件来构建Docker镜像之前,我们需要了解Dockerfile文件编写支持的命令、关键词具体有哪些,各自有代表什么意思,如下给出一些DockerFile中的一些指令:

ADD指令

添加本地或远程文件和目录。指令格式如下:

ADD [--chown=<user>:<group>] [--chmod=<perms>] [--checksum=<checksum>] <src>... <dest>  #或
ADD [--chown=<user>:<group>] [--chmod=<perms>] ["<src>",... "<dest>"]

后一种形式对于包含空白的路径是必需的。--chown--chmod功能仅在用于构建Linux容器的Dockerfiles上受支持,而在Windows容器上不起作用。由于用户和组所有权概念不会在LinuxWindows之间转换,因此使用/etc/passwd/etc/group将用户和组名称转换为ID会限制此功能仅适用于基于Linux操作系统的容器。--chmodDockerfile 1.3开始支持。当前仅支持八进制表示法。

ADD指令从<src>复制新文件、目录或远程文件URL,并将它们添加到路径<dest>的映像文件系统中。可以指定多个<src>资源,但如果它们是文件或目录,则它们的路径将被解释为相对于构建上下文的源。每个<src>都可能包含通配符,并且将使用Go的文件路径进行匹配。匹配规则。例如:

ADD hom* /mydir/ # 要添加所有以“hom”开头的文件:

ARG指令

使用生成时变量。ARG指令定义了一个变量,用户可以在构建时通过使用--build ARG<varname>=<value>标志的docker构建命令将该变量传递给构建器。如果用户指定的构建参数未在Dockerfile中定义,则该构建会输出警告。格式如下:

ARG <name>[=<default value>]

Dockerfile可以包括一个或多个ARG指令。例如,以下是有效的Dockerfile

FROM busybox
ARG user1
ARG buildno=1 #ARG指令可以选择性地包括一个默认值:
# ...

CMD指令

指定默认命令。CMD指令设置从映像运行容器时要执行的命令。您可以使用shell或exec形式指定CMD指令:

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

COPY指令

复制文件和目录。命令格式如下:

COPY [--chown=<user>:<group>] [--chmod=<perms>] <src>... <dest>
COPY [--chown=<user>:<group>] [--chmod=<perms>] ["<src>",... "<dest>"]

使用功能字面意思就是复制文件,将当前目录下的指定路径文件复制到镜像或容器指定地址。这个命令在使用过程中用的频率较高,示例如下:

PY hom* /mydir/

ENTRYPOINT指令

指定默认可执行文件。ENTRYPOINT允许您配置将作为可执行文件运行的容器。你也可以不配置,它会执行默认的可执行文件。使用格式如下:

ENTRYPOINT ["executable", "param1", "param2"] #或
ENTRYPOINT command param1 param2 

ENV指令

设置环境变量。用的比较多,如系统设置运行环境参数,常规的我们的前端项目可能会设置NODE_ENV区分开发环境。其常用格式如下:

ENV <key>=<value> ...

ENV指令将环境变量<key>设置为值<value>。该值将在构建阶段的所有后续指令的环境中,并且可以在许多指令中内联替换。该值将被解释为其他环境变量,因此如果引号字符没有转义,它们将被删除。与命令行解析一样,引号和反斜杠可以用于在值中包含空格。使用示例如下:

ENV MY_NAME="John Doe"
ENV MY_DOG=Rex\ The\ Dog
ENV MY_CAT=fluffy

ENV指令允许多个<key>=<value>。。。一次设置变量,下面的例子将在最终图像中产生相同的净结果:

ENV MY_NAME="John Doe" MY_DOG=Rex\ The\ Dog \
    MY_CAT=fluffy

当从生成的映像运行容器时,使用ENV设置的环境变量将保持不变。您可以使用docker inspect查看这些值,并使用docker run--env=更改它们。

EXPOSE指令

描述您的应用程序正在监听哪些端口。需要注意的是这个只是描述当前应用容器正在监听的端口并不能指定映射的宿主机的端口。使用格式如下:

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

EXPOSE指令通知Docker容器在运行时侦听指定的网络端口。您可以指定端口侦听TCP还是UDP,如果未指定协议,则默认为TCP。

EXPOSE指令实际上并没有发布端口。它的作用是构建映像的人和运行容器的人之间的一种文档,说明要发布哪些端口。要在运行容器时发布端口,请在docker运行时使用-p标志来发布和映射一个或多个端口,或者使用-p标志来发布所有公开的端口并将其映射到高阶端口。

EXPOSE 80/udp

FROM指令

从基本映像创建新的构建阶段。即当前构建镜像的依赖镜像,一般多为系统级别的基础镜像信息,使用格式如下:

FROM [--platform=<platform>] <image> [AS <name>] # 或
FROM [--platform=<platform>] <image> [AS <name>] # 或
FROM [--platform=<platform>] <image>[@<digest>] [AS <name>]

FROM指令初始化一个新的构建阶段,并为后续指令设置基本映像。因此,有效的Dockerfile必须以FROM指令开头。该镜像可以是任何有效的镜像。

  • ARGDockerfileFROM之前的唯一指令。
  • FROM可以在单个Dockerfile中多次出现,以创建多个映像,或者将一个构建阶段用作另一个的依赖项。只需在每条新的FROM指令之前记下提交输出的最后一个映像ID即可。每个FROM指令都会清除先前指令创建的任何状态。
  • 可选地,可以通过将AS名称添加到FROM指令来为新的构建阶段指定名称。该名称可以在随后的FROMCOPY-FROM=指令中使用,以引用在此阶段构建的镜像。
  • 标记值或摘要值是可选的。如果省略其中任何一个,则默认情况下构建器将采用最新的标记。如果生成器找不到标记值,则返回一个错误。

可选的--platform标志可用于在FROM引用多平台映像的情况下指定映像的平台。例如,linux/amd64、linux/arm64windows/amd64。默认情况下,将使用构建请求的目标平台。全局构建参数可以用于此标志的值,例如,自动平台ARG允许您将阶段强制到本机构建平台(--platform=$BUILDPORM),并使用它交叉编译到阶段内的目标平台。

HEALTHCHECK指令

启动时检查容器的运行状况。HEALTHCHECK指令告诉Docker如何测试容器以检查它是否仍在工作。这可以检测到一些情况,例如web服务器陷入无限循环,无法处理新的连接,即使服务器进程仍在运行。格式如下:

HEALTHCHECK [OPTIONS] CMD command #通过在容器内运行命令来检查容器运行状况
HEALTHCHECK NONE # 禁用从基本映像继承的任何健康检查

LABEL指令

向镜像中添加元数据。LABEL指令将元数据添加到图像中。LABEL是一个键值对。若要在LABEL值中包含空格,请像在命令行分析中一样使用引号和反斜杠。一些用法示例:

LABEL <key>=<value> <key>=<value> <key>=<value> ... #格式

#示例
LABEL "com.example.vendor"="ACME Incorporated"
LABEL com.example.label-with-value="foo"
LABEL version="1.0"
LABEL description="This text illustrates \
that label-values can span multiple lines."

MAINTAINER指令

指定镜像的作者信息。MAINTAINER指令设置生成镜像的“作者”字段。LABEL指令是一个更灵活的版本,您应该使用它,因为它可以设置您需要的任何元数据,并且可以很容易地查看,例如使用docker inspect。要设置与MAINTAINER字段相对应的标签,可以使用:

MAINTAINER <name> # 指令格式

# LABEL 使用
LABEL org.opencontainers.image.authors="SvenDowideit@home.org.au"

ONBUILD指令

指定在生成中使用镜像的时间说明。ONBUILD指令向映像中添加一条触发器指令,该指令将在以后映像用作另一个生成的基础时执行。触发器将在下游构建的上下文中执行,就好像它是在下游Dockerfile中的FROM指令之后立即插入的一样。格式如下:

ONBUILD INSTRUCTION

# 示例
ONBUILD ADD . /app/src
ONBUILD RUN /usr/local/bin/python-build --dir /app/src

需要注意的是:

  • 不允许使用ONBUILD-ONBUILD链接ONBUILD指令。
  • ONBUILD指令可能不会触发FROMMAINTAINER指令。

RUN指令

执行构建命令。RUN指令将执行任何命令,在当前图像的顶部创建一个新层。添加的层将在Dockerfile的下一步中使用。

RUN apt-get update
RUN apt-get install -y curl

可以使用shell或exec形式指定RUN指令:

RUN ["executable","param1","param2"] #或
RUN command param1 param2 

shell形式是最常用的,使用换行符或heredocs,可以更容易地将较长的指令分解为多行:

RUN <<EOF
apt-get update
apt-get install -y curl
EOF

SHELL指令

设置镜像的默认执行shellSHELL指令允许覆盖用于命令SHELL形式的默认SHELLLinux上的默认shell[“/bin/sh”,“-c”]Windows上的默认shell为[“cmd”,“/S”,“/c”]SHELL指令必须在Dockerfile中以JSON形式编写。

SHELL ["executable", "parameters"] #指令格式

#使用示例
FROM microsoft/windowsservercore

# Executed as cmd /S /C echo default
RUN echo default

# Executed as cmd /S /C powershell -command Write-Host default
RUN powershell -command Write-Host default

# Executed as powershell -command Write-Host hello
SHELL ["powershell", "-command"]
RUN Write-Host hello

# Executed as cmd /S /C echo hello
SHELL ["cmd", "/S", "/C"]
RUN echo hello

STOPSIGNAL指令

指定退出容器的系统调用信号。STOPSSIGNAL指令设置将发送到容器以退出的系统调用信号。该信号可以是SIG<name>格式的信号名称,例如SIGKILL,也可以是与内核系统调用表中的位置匹配的无符号数字,例如9。如果未定义,则默认值为SIGTERM

STOPSIGNAL signal

USER指令

设置用户和组ID。USER指令设置用户名(或UID)和可选的用户组(或GID),用作当前阶段剩余部分的默认用户和组。指定的用户用于执行RUN指令,并在运行时运行相关的ENTRYPOINT和CMD命令。格式如下:

USER <user>[:<group>] # 或者
USER UID[:GID]

#使用配置
FROM microsoft/windowsservercore
# Create Windows user in the container
RUN net user /add patrick
# Set it for subsequent commands
USER patrick

VOLUME指令

设置卷挂载地址。VOLUME指令使用指定的名称创建一个装载点,并将其标记为容纳来自本机主机或其他容器的外部装载卷。该值可以是JSON数组,VOLUME[“/var/log/”],或带有多个参数的纯字符串,如VOLUME/var/logVOLUME/var/log/var/db

docker run命令使用基本映像中指定位置存在的任何数据初始化新创建的卷。例如,考虑以下Dockerfile片段:

FROM ubuntu
RUN mkdir /myvol
RUN echo "hello world" > /myvol/greeting
VOLUME /myvol

Dockerfile会生成一个映像,该映像使docker run/myvol上创建一个新的装载点,并将问候文件复制到新创建的卷中。

WORKDIR指令

更改工作目录。WORKDIR指令为Dockerfile中的任何RUN、CMD、ENTRYPOINT、COPYADD指令设置工作目录。如果WORKDIR不存在,即使它没有在任何后续的Dockerfile指令中使用,它也会被创建。格式如下:

WORKDIR /path/to/workdir

WORKDIR指令可以在Dockerfile中多次使用。如果提供了一个相对路径,它将是相对于上一个WORKDIR指令的路径。例如:

WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd

这个Dockerfile中的最后一个pwd命令的输出将是/a/b/c

WORKDIR指令可以解析先前使用ENV设置的环境变量。只能使用Dockerfile中显式设置的环境变量。例如:

ENV DIRPATH=/path
WORKDIR $DIRPATH/$DIRNAME
RUN pwd

这个Dockerfile中最后一个pwd命令的输出将是/path/$DIRNAME

赞(1) 打赏
转载请附上原文出处链接:胖蔡说技术 » Dockerfile镜像构建基础
分享到: 更多 (0)

请小编喝杯咖啡~

支付宝扫一扫打赏

微信扫一扫打赏