docker build 如何知道 Dockerfile RUN 或 COPY 行是否可以使用缓存?

Joh*_*ohn 5 python docker

如果我的 Python 项目的 Dockerfile 如下所示:

FROM python:3.7

# Set env variables
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1

# Set work dir
WORKDIR /code

# Install rust
# Needed by cryptography package
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | bash -s -- -y

# Install dependencies from apt repo
RUN apt-get update && \
    apt-get install -y \
        build-essential \
        python-dev && \
    rm -rf /var/lib/apt/lists/*

# Copy and install requirements
COPY requirements.txt /code/requirements.txt
RUN pip install --no-cache --upgrade pip && \
    pip install --no-cache -r requirements.txt

# Copy code
COPY my_code /code/

# Set CMD
CMD ["python", "run.py"]
Run Code Online (Sandbox Code Playgroud)
  1. 如何docker build知道是否COPY requirements.txt /code/requirements.txt可以使用缓存,或者是否需要重新运行此命令?
    • 通过运行此命令创建的映像是否具有元数据来跟踪复制的每个文件的哈希值,以便下次运行时,它可以检查复制操作是否会复制任何更改的文件?
  2. 操作可以RUN被缓存吗?Docker 如何知道何时使用缓存,以及何时重新运行命令来构建新的镜像层?
  3. 如果完全禁用缓存,这是否意味着COPY requirements.txt /code/requirements.txt如果启用缓存,类似的命令会导致图像层不变,可能会导致新的图像层具有不同的摘要,从而完全否定图像层的有效性?
  4. 是否有文档描述了哪些内容可以缓存、哪些内容不可以缓存的规则?

Ash*_*h.. 4

1 - docker build 如何知道 COPYrequirements.txt /code/requirements.txt 是否可以使用缓存,或者是否需要重新运行此命令?

对于 ADD 和 COPY 指令,将检查映像中文件的内容并计算每个文件的校验和。这些校验和中不考虑文件的上次修改时间和上次访问时间。在缓存查找期间,会将校验和与现有映像中的校验和进行比较。如果文件中发生任何更改,例如内容和元数据,则缓存将失效。

2 - RUN 操作是否可以被缓存?docker 如何知道何时使用缓存,以及何时重新运行命令来构建新的镜像层?

除了 ADD 和 COPY 命令之外,缓存检查不会查看容器中的文件来确定缓存匹配。例如,在处理 RUN apt-get -y update 命令时,不会检查容器中更新的文件以确定是否存在缓存命中。在这种情况下,仅使用命令字符串本身来查找匹配项。

3 - 如果您完全禁用缓存,这是否意味着诸如 COPYrequirements.txt /code/requirements.txt 之类的命令在启用缓存的情况下会导致图像层未更改,可能会导致新的图像层,具有不同的消化,完全否定图像层的有效性?

是的,这会导致图层具有不同的摘要。

要测试它,你可以

  1. docker build -t test:latest .构建并记下 COPY 层的哈希值
  2. docker save test > test.tar
  3. tar xvf test.tar
  4. docker build --no-cache -t test:latest .使用无缓存标志构建并记下 COPY 层的新哈希
  5. docker save test > test.tar
  6. tar xvf test.tar
  7. 将旧 COPY 层的 {hash}.json 与新 COPY 层的 {hash}.json 进行比较。

json 之间的唯一区别是created key 的值,即构建层的日期。

根据此来源,用于SHA256hex(uncompressed layer tar data) 提供层摘要,如果您的cat {hash}.json | sha256sum输出将与文件名相同。

另外,negating the effectiveness of image layers?我认为这根本不会否定有效性,我们明确提供了不使用缓存的指令。

即使createdmeta没有存储在layer中,由于no-cache docker会重建layer,只是摘要会是相同的,但重建layer的时间会和现在一样。

4 - 是否有文档描述了哪些内容可以缓存、哪些内容不可以缓存的规则?

前 3 个答案复制自https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#leverage-build-cache