Dockerfile指令详解
目录
1. FROM
- 作用:指定基础镜像,是每个 Dockerfile 的第一条指令。每个 Dockerfile 必须以
FROM
指令开头,且至少有一个FROM
指令。 - 示例:
FROM <image>[:<tag>] [AS <name>] <image>:基础镜像的名称。 <tag>:可选参数,用于指定基础镜像的标签(版本),如果不指定,默认为 latest。 AS <name>:可选参数,用于定义一个构建阶段的名称,多阶段构建中常用。 1.指定基础镜像和标签 FROM ubuntu:20.04 2.使用最新版本 FROM nginx 3.多阶段构建 # 第一阶段:构建阶段 FROM golang:1.18 AS builder WORKDIR /app COPY . . RUN go build -o myapp # 第二阶段:运行阶段 FROM alpine:latest WORKDIR /app COPY --from=builder /app/myapp . CMD ["./myapp"]
2. LABEL
- 作用:为镜像添加元数据。元数据可以是任何键值对,用于描述镜像的用途、维护者信息、版本等。
LABEL
指令的主要作用是为镜像提供额外的信息,方便镜像的管理和使用。你可以指定一个或多个标签,每个标签都是一个键值对。 - 示例:
简单维护者信息格式: LABEL maintainer="yourname@example.com" 多标签添加: LABEL version="1.0" description="This is a sample Dockerfile" maintainer="yourname@example.com" 多行格式: LABEL \ version="1.0" \ description="This is a sample Dockerfile" \ maintainer="yourname@example.com"
3. ENV
- 作用:设置环境变量。这些环境变量在容器运行时可用,并且可以在 Dockerfile 中的后续指令中使用。环境变量可以帮助配置容器的运行时行为以及传递配置信息。
- 示例:
格式: ENV <key> <value> <key>:环境变量的名称。 <value>:环境变量的值。 1.简单示例 FROM ubuntu:20.04 ENV DEBIAN_FRONTEND=noninteractive RUN apt-get update && apt-get install -y tzdata 2.多行格式 ENV KEY1=value1 \ KEY2=value2 \ KEY3=value3 3.使用环境变量 FROM node:14 ENV APP_HOME=/usr/src/app WORKDIR $APP_HOME COPY . $APP_HOME
4. COPY
- 作用:将文件或目录从宿主机器复制到镜像中。它是将应用程序代码、配置文件和其他资源添加到镜像中的主要方式之一。
示例:
格式:
COPY <src>... <dest>
<src>:源文件或目录的路径,可以是相对路径或绝对路径。
<dest>:目标路径,指定文件或目录在镜像中的位置。
1.复制单个文件
FROM ubuntu:20.04
COPY myfile.txt /app/myfile.txt
2.使用通配符
FROM ubuntu:20.04
COPY *.txt /app/
3.复制多项内容
FROM ubuntu:20.04
COPY file1.txt file2.txt /app/
#将 file1.txt 和 file2.txt 复制到镜像中的 /app 目录下
5. ADD
- 作用:类似于
COPY
,但功能更强大,可以解压 tar 文件,并且可以从 URL 下载文件。但是二个功能只会用一个。 - 示例:
格式: ADD <src>... <dest> <src>:源文件或目录的路径,可以是相对路径、绝对路径或 URL。 <dest>:目标路径,指定文件或目录在镜像中的位置。 1.复制目录 FROM ubuntu:20.04 ADD mydir /app/mydir 2.使用通配符 FROM ubuntu:20.04 ADD *.txt /app/ 3.解压 tar 文件 FROM ubuntu:20.04 ADD files.tar.gz /app/ 4.从 URL 下载文件 FROM ubuntu:20.04 ADD http://example.com/file.txt /app/file.txt
区别于 COPY 指令
- 解压功能:
ADD
可以自动解压 tar 文件,而COPY
不能。 - URL 下载功能:
ADD
可以从 URL 下载文件,而COPY
不能。 - 使用场景:为了明确性和避免意外解压,通常推荐使用
COPY
来复制本地文件,只有在需要解压功能或 URL 下载功能时才使用ADD
。
6. VOLUME
- 作用:
VOLUME
指令在 Dockerfile 中用于声明一个数据卷。数据卷是一个专门设计用于持久化数据的目录,即使容器被删除,数据卷中的数据仍然会保留。数据卷可以在容器之间共享和重用,非常适合用于存储数据库文件、日志文件或其他需要持久化的数据。多个容器可以挂载同一个数据卷,实现数据共享。 - 示例:
VOLUME ["/path/to/directory"] 或 VOLUME /path/to/directory 1.声明单个数据卷 FROM ubuntu:20.04 VOLUME ["/data"] 2.声明多个数据卷 FROM ubuntu:20.04 VOLUME ["/data", "/backup"] 3.另一种声明方式 FROM ubuntu:20.04 VOLUME /data
7. EXPOSE
- 作用:声明容器将监听的端口。此指令不会实际打开端口或进行任何网络配置,只是将这些信息提供给构建镜像的用户和 Docker 容器运行时。
- 示例:
格式: EXPOSE <port> [<port>/<protocol>...] <port>:要暴露的端口号。 <protocol>(可选):协议,可以是 tcp 或 udp。默认为 tcp。 1.暴露单个端口 FROM nginx:latest EXPOSE 80 2.暴露多个端口 FROM ubuntu:20.04 EXPOSE 80 443 3.指定协议 FROM ubuntu:20.04 EXPOSE 53/udp 53/tcp
8. RUN
- 作用:在镜像构建过程中执行命令。它是 Dockerfile 中最常用的指令之一,主要用于安装软件包、执行脚本、配置系统等操作。
- 示例:
格式: RUN <command> <command>:要在构建过程中执行的命令,可以是任何有效的 Shell 命令。 1.安装软件包 FROM ubuntu:20.04 RUN apt-get update && apt-get install -y curl 2.运行脚本 FROM python:3.9 COPY setup.sh /setup.sh RUN chmod +x /setup.sh && /setup.sh 3.多个命令 FROM node:14 RUN apt-get update && \ apt-get install -y git && \ npm install -g nodemon
9. WORKDIR
- 作用:设置工作目录,所有后续指令(如 RUN、CMD、ENTRYPOINT)都会在这个目录下执行。这是容器内命令的默认执行目录。使用
WORKDIR
指令可以简化后续命令的路径设置,并使 Dockerfile 更加清晰和易于维护。 - 示例:
WORKDIR /path/to/directory 1.基本用法 FROM node:14 WORKDIR /usr/src/app COPY package*.json ./ RUN npm install COPY . . 2.使用 WORKDIR 指令创建多级目录 FROM python:3.9 WORKDIR /app/subdir COPY . . #如果 /app/subdir 目录不存在,Docker 会自动创建它。COPY 指令将所有文件复制到这个目录下。 3.结合其他指令使用 FROM debian:latest WORKDIR /opt RUN mkdir myapp WORKDIR /opt/myapp COPY . . #WORKDIR 指令用于在容器中设置两个工作目录:/opt 和 /opt/myapp。 #第二个 WORKDIR 指令确保后续的命令和文件操作都在 /opt/myapp 目录下进行。
使用
WORKDIR
的好处 -
简化路径管理
使用
WORKDIR
可以简化后续命令中的路径管理。例如,RUN
和COPY
命令都相对于设置的工作目录,而不需要每次都指定完整路径。 -
提高 Dockerfile 的可读性
通过设置工作目录,使 Dockerfile 更加清晰和易于维护。每个命令都会在指定的工作目录中执行,避免了路径的混乱和错误。
-
自动创建目录
WORKDIR
指令会自动创建目录(如果不存在),这减少了需要先创建目录的额外步骤。 -
减少重复代码
通过设置工作目录,可以避免在每个命令中重复书写路径,从而减少 Dockerfile 的冗余代码。
10. CMD
- 作用:指定容器启动时默认执行的命令。
CMD
指令可以用于设置容器启动时的默认程序及其参数。如果在docker run
命令中指定了其他命令,CMD
指令中的默认命令将会被覆盖。 - 示例:
1.使用 JSON 数组格式 FROM ubuntu:20.04 CMD ["echo", "Hello, Docker!"] #启动容器时将默认执行 echo "Hello, Docker!" 2.使用 Shell 格式 FROM ubuntu:20.04 CMD echo "Hello, Docker!" #启动容器时将默认执行 echo "Hello, Docker!",命令通过 Shell 执行 3.运行一个服务 FROM nginx:latest CMD ["nginx", "-g", "daemon off;"] 4.与 ENTRYPOINT 配合使用 FROM python:3.9 ENTRYPOINT ["python"] CMD ["app.py"] #ENTRYPOINT 指令设置了默认的执行命令为 python,而 CMD 指令提供了默认参数 app.py。 这意味着容器启动时会执行 python app.py
使用场景
-
默认命令:
CMD
适用于设置容器的默认启动命令,比如启动应用程序或服务。 -
默认参数:当配合
ENTRYPOINT
使用时,CMD
可以提供默认参数,允许在运行容器时根据需要覆盖这些参数。
11. ENTRYPOINT
- 作用:配置容器启动时运行的命令。不能被
docker run
命令行参数覆盖,但可以追加参数。 - 示例:
格式: ENTRYPOINT ["executable", "param1", "param2"] 或 ENTRYPOINT command param1 param2 1.使用 JSON 数组格式 FROM ubuntu:20.04 ENTRYPOINT ["echo", "Hello, Docker!"] #启动容器时将执行 echo "Hello, Docker!",并且不能被覆盖 2.使用 Shell 格式 FROM ubuntu:20.04 ENTRYPOINT echo "Hello, Docker!" #启动容器时将执行 echo "Hello, Docker!",Shell 会解析并执行该命令。 3.运行一个服务 FROM nginx:latest ENTRYPOINT ["nginx", "-g", "daemon off;"] 4.与 CMD 配合使用 FROM python:3.9 ENTRYPOINT ["python"] CMD ["app.py"]
CMD
与ENTRYPOINT
的区别 -
CMD
:指定容器启动时的默认命令和参数。如果在docker run
中指定了其他命令或参数,CMD
的默认设置将会被覆盖。 -
ENTRYPOINT
:设置容器启动时必须执行的命令。ENTRYPOINT
指定的命令不能被覆盖,但可以通过CMD
提供默认参数,允许在运行时指定不同的参数。
12. ARG
- 作用:定义在构建期间可传递的变量,这些变量可以在 Docker 镜像构建过程中使用。
ARG
指令定义的变量在构建过程中可用,但它们不会在构建完成后的镜像中保留。这使得ARG
非常适合用于配置构建过程中的参数,如版本号、构建选项等。 - 示例:
格式: ARG <name>[=<default_value>] <name>:变量的名称。 <default_value>(可选):变量的默认值。如果没有提供默认值,则变量在构建时必须被显式指定。 1.定义和使用构建时变量 FROM ubuntu:20.04 ARG VERSION=1.0 RUN echo "Version is $VERSION" #ARG 定义了一个名为 VERSION 的构建时变量,默认值为 1.0。在 RUN 指令中,使用 $VERSION 变量打印版本信息。 2.在构建时覆盖默认值 FROM ubuntu:20.04 ARG VERSION=1.0 RUN echo "Version is $VERSION" #构建镜像时可以通过 --build-arg 选项覆盖默认值: docker build --build-arg VERSION=2.0 -t my-app . #这会将 VERSION 设置为 2.0,并在构建过程中使用这个值。 3.使用多个 ARG 指令 FROM node:14 ARG APP_ENV=production ARG APP_PORT=3000 RUN echo "Environment is $APP_ENV and port is $APP_PORT" #在构建过程中,可以使用 --build-arg 选项为多个变量指定值: docker build --build-arg APP_ENV=development --build-arg APP_PORT=8080 -t my-node-app . 4.结合 ENV 使用 #ARG 和 ENV 可以结合使用,将构建时变量的值传递给环境变量,以便在容器运行时使用: FROM ubuntu:20.04 ARG VERSION=1.0 ENV APP_VERSION=$VERSION RUN echo "Application version is $APP_VERSION" #在这个示例中,ARG 变量 VERSION 的值被传递给 ENV 变量 APP_VERSION,并在 RUN 指令中使用。
注意事项
-
作用范围:
ARG
变量仅在 Dockerfile 的FROM
指令之后、到下一个FROM
指令之前有效。它们不能在构建后的镜像中访问。 -
安全性:
ARG
变量不会在最终镜像中保留,因此适用于需要在构建时使用的敏感数据或配置。为了在构建过程中保护敏感信息,确保不将它们以明文形式包含在 Dockerfile 中。 -
优先级:如果在构建过程中使用了
--build-arg
选项,指定的值将覆盖 Dockerfile 中定义的默认值。
13. USER
- 作用:指定运行容器时的用户。通过设置用户,可以控制容器中的文件权限和安全性,确保容器以非特权用户身份运行,从而减少安全风险。
- 示例:
格式: USER <username|UID>[:<group|GID>] <username|UID>:指定要切换到的用户的用户名或用户ID (UID)。 <group|GID>(可选):指定要切换到的组的名称或组ID (GID)。如果省略,用户将不会更改所属的组。 1.使用用户名 FROM ubuntu:20.04 RUN useradd -m myuser USER myuser 2.使用 UID 和 GID FROM ubuntu:20.04 RUN groupadd -g 1001 mygroup && useradd -u 1001 -g mygroup myuser USER 1001:1001 #USER 指令使用 UID 和 GID 进行设置,将用户切换到 ID 为 1001 的用户和组。 3.结合使用 USER 和 WORKDIR FROM node:14 RUN useradd -m myuser USER myuser WORKDIR /home/myuser/app COPY . . RUN npm install #USER 指令切换到 myuser,然后在 /home/myuser/app 目录下执行后续命令。 #由于切换了用户,COPY 和 RUN 命令将以 myuser 的身份运行。 4.设置用户后运行命令 FROM ubuntu:20.04 RUN useradd -m myuser USER myuser RUN whoami #这个示例将输出当前用户,结果应该是 myuser,因为 USER 指令已经切换了用户。
使用场景
-
安全性:运行容器时使用非特权用户可以减少安全风险。避免以 root 用户身份运行应用程序,尤其是在生产环境中。
-
文件权限:使用
USER
指令可以确保容器中的文件和目录具有适当的权限,防止权限问题。 -
最佳实践:作为最佳实践,在 Dockerfile 中创建并使用非特权用户,而不是以 root 用户身份运行所有命令。
14. HEALTHCHECK
- 作用:配置容器的健康检查指令。这个指令允许 Docker 定期检查容器的健康状态,并根据检查结果决定是否重新启动或标记容器为不健康。健康检查对于确保容器中的应用程序正常运行非常有用,可以帮助检测和处理潜在的问题。
- 示例:
格式: HEALTHCHECK [OPTIONS] CMD <command> OPTIONS(可选):用于配置健康检查的选项,如超时、重试次数等。 CMD <command>:指定用于检查容器健康状态的命令。 --interval:指定检查之间的时间间隔。默认为 30s(30 秒)。 HEALTHCHECK --interval=10s CMD curl -f http://localhost/ || exit 1 --timeout:指定检查命令的超时时间。默认为 30s(30 秒)。 HEALTHCHECK --timeout=5s CMD curl -f http://localhost/ || exit 1 --retries:指定检查失败的重试次数。默认为 3。 HEALTHCHECK --retries=5 CMD curl -f http://localhost/ || exit 1 --start-period:容器启动后等待一段时间才开始执行健康检查。默认为 0s(不等待)。 HEALTHCHECK --start-period=60s CMD curl -f http://localhost/ || exit 1
健康检查的工作原理
- 检查容器状态:Docker 守护进程定期执行
HEALTHCHECK
指令中定义的命令,以检查容器的健康状态。 - 健康状态标记:健康检查的结果会影响容器的状态。如果健康检查命令返回非零状态,容器将被标记为不健康。如果连续多次检查失败,容器可能会被重新启动(如果启用了自动重启策略)。
使用场景
- 确保服务可用性:使用
HEALTHCHECK
确保容器中运行的服务在预期的状态下运行。及时发现服务问题并采取适当的措施。 - 自动恢复:通过健康检查结合 Docker 的重启策略,可以自动重新启动不健康的容器,确保服务的高可用性。
15. ONBUILD
- 作用:在当前镜像用作其他镜像的基础镜像时,配置触发的指令。它主要用于创建具有特定构建步骤的基础镜像,这些步骤会在继承该镜像的 Dockerfile 中自动执行。这可以简化构建过程,避免在每个 Dockerfile 中重复相同的步骤。
- 示例:
格式: ONBUILD <command> <command>:在继承该镜像的 Dockerfile 中被执行的命令。 1.创建通用的基础镜像 # Base Dockerfile FROM node:14 WORKDIR /app COPY package*.json ./ RUN npm install ONBUILD COPY . . ONBUILD RUN npm run build #在这个示例中,基础镜像在其 ONBUILD 指令中定义了 COPY 和 RUN 命令。 #这些命令将在继承该基础镜像的 Dockerfile 中自动执行。 2.在创建特定类型的镜像时自动执行步骤 # Python Base Dockerfile FROM python:3.9 WORKDIR /app ONBUILD COPY requirements.txt ./ ONBUILD RUN pip install -r requirements.txt #在这个示例中,ONBUILD 指令会自动将 requirements.txt 文件复制到 /app 目录,并安装其中列出的 Python 包。
注意事项
-
执行时机:
ONBUILD
指令中的命令会在继承镜像的 Dockerfile 中构建时执行,而不是在基础镜像的构建时。 -
有限使用:
ONBUILD
指令在某些情况下可能会导致不必要的复杂性或不可预测的行为。应谨慎使用,并确保明确了解ONBUILD
指令在继承镜像中的执行顺序和影响。 -
不支持某些操作:
ONBUILD
指令通常用于简化重复的构建步骤,但在某些情况下,如多阶段构建或动态构建需求,可能不适合使用。
16.STOPSIGNAL
注意事项
17.SHELL
- 作用:
STOPSIGNAL
指令在 Dockerfile 中用于设置容器停止时发送的信号。这可以帮助容器优雅地停止,允许容器中的应用程序在接收到特定信号时执行清理操作或完成正在进行的任务。 - 实例:
格式: STOPSIGNAL <signal> <signal>:指定容器停止时发送的信号。常见的信号包括 SIGTERM(默认)、SIGKILL、SIGQUIT 等。 1.设置 STOPSIGNAL 为 SIGTERM FROM ubuntu:20.04 STOPSIGNAL SIGTERM #在这个示例中,STOPSIGNAL 指令将容器的停止信号设置为 SIGTERM。这是 Docker 的默认行为,通常情况下不需要显式设置。 2.设置 STOPSIGNAL 为 SIGQUIT FROM nginx:latest STOPSIGNAL SIGQUIT #这个示例将容器的停止信号设置为 SIGQUIT。SIGQUIT 会让容器中的应用程序执行核心转储操作,适用于需要在容器停止时获取诊断信息的场景。 3.设置 STOPSIGNAL 为 SIGKILL FROM python:3.9 STOPSIGNAL SIGKILL #在这个示例中,STOPSIGNAL 指令将容器的停止信号设置为 SIGKILL。SIGKILL 直接终止进程,不允许应用程序执行任何清理操作,因此通常在需要强制停止容器时使用。
使用场景
-
优雅停止:在需要优雅地停止应用程序时,
STOPSIGNAL
可以让容器在接收到停止信号时执行清理操作或完成当前任务。例如,SIGTERM
可以让应用程序处理清理工作,然后正常退出。 -
调试和诊断:通过设置特定的停止信号(如
SIGQUIT
),可以让应用程序生成核心转储文件,帮助诊断和调试问题。 -
默认信号:如果不显式设置
STOPSIGNAL
,Docker 默认使用SIGTERM
作为停止信号。这通常适用于大多数应用程序。 -
应用程序支持:确保容器中的应用程序正确处理接收到的停止信号。不同的应用程序可能对不同的信号有不同的响应方式。
-
信号选择:选择适当的信号来满足容器停止时的需求。避免使用
SIGKILL
作为默认停止信号,因为它会直接终止进程,不允许应用程序执行任何清理操作。-
强制停止:在某些情况下,可能需要强制停止容器而不等待应用程序的清理操作。
SIGKILL
可以用来强制终止容器中的进程。
注意事项
- 作用:
SHELL
指令在 Dockerfile 中用于更改RUN
指令使用的默认 shell。这可以用于指定自定义的 shell 或修改现有 shell 的行为。SHELL
指令允许用户使用不同的 shell 特性或语法,满足特定的构建需求。 - 实例:
格式: SHELL ["<shell>", "<option>"] <shell>:指定要使用的 shell 程序。例如,/bin/bash 或 /bin/sh。 <option>(可选):指定 shell 的选项。例如,-c 选项用于执行命令。 1.使用 Bash 作为默认 shell FROM ubuntu:20.04 SHELL ["/bin/bash", "-c"] RUN echo "This is using bash" #在这个示例中,SHELL 指令将 shell 更改为 /bin/bash,并使用 -c 选项执行 RUN 指令中的命令。 2.在 Bash 中启用调试模式 FROM ubuntu:20.04 SHELL ["/bin/bash", "-x", "-c"] RUN echo "This is using bash with debug mode" #-x 选项启用 Bash 的调试模式,可以在构建过程中打印每个命令及其参数。
使用场景
-
使用特定的 shell 功能:如果需要在 Dockerfile 中使用特定 shell 的功能或语法,例如 Bash 的扩展功能,可以通过
SHELL
指令指定使用该 shell。 -
改变默认 shell:在某些情况下,可能需要使用不同的 shell 来满足构建过程的要求。例如,Windows 容器中的默认 shell 是
cmd.exe
,但可以使用 PowerShell 进行更多的脚本操作。 -
作用范围:
SHELL
指令只影响在它之后的RUN
指令。在SHELL
指令之前的RUN
指令仍使用默认 shell。 -
兼容性:确保指定的 shell 和选项在基础镜像中可用,并且与容器中的应用程序兼容。
-
性能:更改 shell 可能会影响构建的性能和行为,因此应根据需要谨慎选择。
-
启用调试模式:使用
SHELL
指令可以在构建过程中启用调试模式,以帮助调试和排查问题。
-
-
原文地址:https://blog.csdn.net/Lzcsfg/article/details/140547695
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!