螺竹编程
发布于 2024-05-12 / 5 阅读
1

Dockerfile

Dockerfile介绍

Dockerfile 是用于构建 Docker 镜像的文本文件,其中包含一系列的指令和参数,用于描述如何构建镜像。Dockerfile 是 Docker 构建镜像的重要组成部分,可以让用户自定义镜像的构建过程,从而满足不同的需求。

Dockerfile组成部分

一个典型的 Dockerfile 包含以下几个部分:

  1. 基础镜像信息:指定所使用的基础镜像,例如 FROM ubuntu:latest​​。

  2. 维护者信息:指定 Dockerfile 的维护者,例如 MAINTAINER Name <email>​​。

  3. 执行操作指令:包括安装软件、复制文件、设置环境变量等操作,例如 RUN apt-get update && apt-get install -y nginx​​。

  4. 暴露端口指令:指定容器运行时需要开放的端口,例如 EXPOSE 80​​。

  5. 容器启动时执行指令:指定容器启动时需要执行的命令,例如 CMD ["nginx", "-g", "daemon off;"]​​。

  6. 其他指令:包括 COPY​​、ADD​​、ENTRYPOINT​​、WORKDIR​​ 等指令,用于完成更多的操作。

注意事项

在编写 Dockerfile 时,需要注意以下几点:

  1. 每个指令都会创建一个新的中间镜像,因此应该尽量合并多个指令,减少中间镜像的数量。

  2. 指令的顺序很重要,应该按照依赖关系和执行顺序来编写。

  3. 镜像构建时会缓存之前的构建结果,如果某个步骤出现错误,可以通过 --no-cache​ 参数来禁用缓存。

  4. Dockerfile 中可以使用各种变量和参数,例如 $ENV_VAR​ 和 ${PARAM:-default}​ 等。

使用 Dockerfile 构建镜像非常简单,只需要在 Dockerfile 所在的目录下执行以下命令即可:docker build -t <image_name> .​

其中,-t​ 参数用于指定镜像的名称和版本号,.​ 表示使用当前目录下的 Dockerfile 构建镜像。

总之,Dockerfile 是 Docker 镜像构建的核心组件,通过编写 Dockerfile,可以自定义镜像的构建过程,并创建出符合自己需求的 Docker 镜像。

Dockerfile指令与参数详解

总览

Dockerfile 是一个文本文件,它包含了一系列的指令和参数,用于构建一个 Docker 镜像。以下是 Dockerfile 中常见的指令及其参数的详细解释:

  1. FROM - 指定基础镜像。

    • ​FROM​ 指令是 Dockerfile 中的第一条指令,它指定了新镜像的基础镜像。

  2. RUN - 执行命令并创建一个新的层来保存这些命令的执行结果。

    • ​RUN​ 指令用于执行命令,通常用于安装软件包、设置环境等。

  3. CMD - 指定容器启动时默认执行的命令。

    • ​CMD​ 指令定义了容器启动时执行的命令,可以是可执行文件的路径或 shell 命令。

  4. ENTRYPOINT - 配置容器启动时执行的命令。

    • ​ENTRYPOINT​ 定义了容器启动时要运行的可执行文件或命令。

  5. EXPOSE - 声明容器运行时监听的端口。

    • ​EXPOSE​ 指令用于声明容器在运行时监听的端口,这样 Docker 守护进程就可以将这些端口映射到宿主机上。

  6. ENV - 设置环境变量。

    • ​ENV​ 用于设置环境变量,这些变量可以在后续的 RUN​ 指令中使用,也可以在容器运行时使用。

  7. ADD - 将文件添加到镜像中。

    • ​ADD​ 可以复制新文件或者解压 tar 压缩文件到镜像中。

  8. COPY - 类似于 ADD,但只复制文件。

    • ​COPY​ 用于复制新文件或者目录到镜像中,与 ADD​ 的区别在于它不支持自动解压缩 tar 文件。

  9. VOLUME - 创建一个可以从本地主机或其他容器挂载的挂载点。

    • ​VOLUME​ 指令用于定义一个挂载点,可以用于持久化存储或共享数据。

  10. USER - 设置运行容器时的用户名或 UID。

    • ​USER​ 用于指定运行容器时的用户名或用户 ID。

  11. WORKDIR - 设置容器内的工作目录。

    • ​WORKDIR​ 用于设置容器启动后的工作目录。

  12. ARG - 定义构建参数。

    • ​ARG​ 允许用户在构建镜像时传递参数。

  13. ONBUILD - 指定当镜像被用作其他镜像的基础镜像时,自动执行的指令。

    • ​ONBUILD​ 指令用于设置触发器,当镜像作为另一个镜像的基础时,这些指令将被执行。

  14. STOPSIGNAL - 设置停止容器时使用的信号。

    • ​STOPSIGNAL​ 用于设置停止容器时使用的信号。

  15. LABEL - 设置镜像的元数据。

    • ​LABEL​ 用于设置镜像的元数据,可以是键值对。

  16. SHELL - 覆盖容器内使用的 shell。

    • ​SHELL​ 用于指定构建镜像时使用的 shell,通常与 RUN​ 指令结合使用。

这些指令构成了 Dockerfile 的基础,通过组合使用这些指令,用户可以定制自己的 Docker 镜像,以满足特定的应用需求。

version

在Dockerfile文件的开头,通常会指定Dockerfile的格式版本,这是通过VERSION​指令来指定的。例如:

# syntax=docker/dockerfile:1.2

上述指令指定了Dockerfile的格式版本为1.2。这个版本号对于Docker引擎来说是非常重要的,因为它指定了Dockerfile中可以使用哪些指令和语法。

以下是Docker引擎版本和Dockerfile格式版本之间的对应关系:

Docker 引擎版本

Dockerfile 格式版本

18.09 及更早版本

1.0

18.09 至 20.10 版本

1.1

20.10 版本及更晚版本

1.2

如果使用的Docker引擎版本早于18.09,则只能使用Dockerfile格式版本1.0。如果使用的Docker引擎版本在18.09和20.10之间,则可以使用Dockerfile格式版本1.0和1.1。如果使用的Docker引擎版本是20.10或更晚版本,则可以使用Dockerfile格式版本1.0、1.1和1.2。

在编写Dockerfile时,应该根据使用的Docker引擎版本来选择正确的格式版本。如果使用不正确的格式版本,则可能会遇到构建错误或无法使用某些功能的问题。

多阶段Dockerfile

Dockerfile是用于构建Docker镜像的文本文件。多阶段Dockerfile是一种技术,可以使用单个Dockerfile文件创建多个阶段的镜像,以便在构建最终镜像时减少镜像的大小。

多阶段Dockerfile通常包括多个FROM语句,每个FROM语句都表示一个构建阶段。在每个构建阶段中,Docker将使用不同的基础镜像来构建镜像,并在每个构建阶段中运行一组指令。在最后一个构建阶段中,使用COPY或ADD指令将从之前的构建阶段中提取的文件复制到最终镜像中。

使用多阶段Dockerfile的好处是可以减少最终镜像的大小。由于每个构建阶段都可以使用不同的基础镜像,因此可以只包含需要的依赖项和文件,而不是在每个阶段中都复制整个项目。这样可以减少最终镜像的大小,提高构建速度和部署效率。

另外,多阶段Dockerfile还可以提高镜像的安全性。由于每个构建阶段都是独立的,可以使用不同的基础镜像和安装程序来减少潜在的漏洞和攻击面。这样可以使镜像更加安全和可靠。

示例

下面是一个 Java Web 应用的 Dockerfile 示例,它使用了 Maven 来构建 Java 项目,并且尽可能地包含了 Dockerfile 中的多种指令:

# 使用官方的 Maven 镜像作为基础镜像
FROM maven:3.6.3-jdk-11-slim AS build

# 设置工作目录为 /app
WORKDIR /app

# 将本地的 src 目录复制到工作目录下
COPY src /app/src
# 将本地的 pom.xml 文件复制到工作目录下
COPY pom.xml /app

# 使用 RUN 指令执行 Maven 构建,结果输出到 target 目录
RUN mvn -f /app/pom.xml clean package

# 使用官方的 Java 镜像作为运行时镜像
FROM openjdk:11-jre-slim

# 设置工作目录为 /app
WORKDIR /app

# 从构建阶段的镜像中复制已构建的 jar 包到当前工作目录
COPY --from=build /app/target/my-java-app.jar /app

# 声明容器运行时监听的端口,假设 Java Web 应用监听 8080 端口
EXPOSE 8080

# 使用 LABEL 设置镜像的元数据
LABEL maintainer="[email protected]" \
      version="1.0"

# 使用 ARG 定义构建参数
ARG BUILD_DATE
ARG VCS_REF

# 使用 STOPSIGNAL 设置停止容器时使用的信号
STOPSIGNAL SIGTERM

# 使用 SHELL 覆盖默认的 shell
SHELL ["/bin/bash", "-c"]

# 使用 RUN 指令执行一些命令来设置应用环境
RUN echo "Building at: $BUILD_DATE" \
 && echo "Based on the following source code revision: $VCS_REF"

# 使用 CMD 指定容器启动时默认执行的命令
CMD ["sh", "-c", "java -jar /app/my-java-app.jar"]

# 使用 ENTRYPOINT 指定容器启动时执行的命令
ENTRYPOINT ["sh"]

# 使用 USER 设置运行容器时的用户
USER 1000

# 使用 VOLUME 创建一个挂载点,用于持久化存储
VOLUME /app/data

# 使用 ONBUILD 设置触发器,这里仅为示例,实际中可能不会用到
ONBUILD USER root
ONBUILD RUN mkdir -p /app/data
ONBUILD USER 1000

这个 Dockerfile 包含了以下指令:

  • ​FROM​: 指定基础镜像。

  • ​WORKDIR​: 设置工作目录。

  • ​COPY​: 复制本地文件到镜像中。

  • ​RUN​: 执行命令并创建一个新的层。

  • ​EXPOSE​: 声明容器运行时监听的端口。

  • ​LABEL​: 设置镜像的元数据。

  • ​ARG​: 定义构建参数。

  • ​STOPSIGNAL​: 设置停止容器时使用的信号。

  • ​SHELL​: 覆盖容器内使用的 shell。

  • ​CMD​: 指定容器启动时默认执行的命令。

  • ​ENTRYPOINT​: 配置容器启动时执行的命令。

  • ​USER​: 设置运行容器时的用户名或 UID。

  • ​VOLUME​: 创建一个可以从本地主机或其他容器挂载的挂载点。

  • ​ONBUILD​: 指定当镜像被用作其他镜像的基础镜像时,自动执行的指令。

请注意,这个示例假设你的 Java 应用是一个 Maven 项目,并且最终生成的 jar 包名为 my-java-app.jar​。在实际应用中,你需要根据自己的项目结构和需求来调整 Dockerfile 中的指令。此外,ONBUILD​ 指令在这个示例中并未实际使用,它们被包含在内只是为了展示 Dockerfile 中可以包含的指令种类。在实际的 Dockerfile 中,只有在创建一个镜像作为其他镜像基础时,ONBUILD​ 指令才会被用到。