一旦镜像在容器中使用,Docker 构建缓存就会被破坏。为什么?如何避免?

一旦镜像在容器中使用,Docker 构建缓存就会被破坏。为什么?如何避免?

我构建了一个映像,它有一个 RUN 阶段,只加载包,另一个阶段之后进行一些初始化。如果我立即重建,它会按应有的方式使用缓存进行阶段。对于稍后的初始化 RUN 阶段,我设置了一个“手动破坏”。如果我在那时“破坏”,那么它会使用缓存进行所有前面的阶段。它按预期正常工作。

如果我在容器中使用该镜像,然后返回并构建镜像,则整个缓存将被破坏,整个镜像将被重建。我希望这种情况不会发生,因为软件包安装花费的时间最长,并且不需要一次又一次地安装。

简而言之,我想测试图像,如果有问题,则仅重建最后的初始化运行阶段,而不是安装包的阶段,但是一旦我使用图像,整个缓存就会被破坏。

为什么会发生这种情况?有没有办法使用图像但保留构建缓存?我想知道为什么在容器中运行图像与构建缓存有什么关系?

ARG BASE_IMAGE
FROM $BASE_IMAGE
ARG BASE_IMAGE
ARG KEEP
ARG SYSADMIN_PW
ARG LINUX_DISTRO=alpine
ARG BUILD_DIR=/build 
WORKDIR $BUILD_DIR
COPY .src ./

# PACKAGES
RUN echo -e "\n ************************************************* \n"\
    echo "****** Building Image from Base: $BASE_IMAGE; : Distro: $LINUX_DISTRO; *****"; \
    echo " ---- running packages install script ---"; /bin/sh ./packages.sh; \
    echo -e "\n********************************************************" 
# END PACKAGES    

ARG BUST_INIT_CACHE

# INITIALIZATION
RUN echo -e "\n ************************************************* \n" \
    echo "****** BUST_INIT_CACHE ${BUST_INIT_CACHE} "; \
    echo "****** Running Initialization Script "; \
    chmod -R +x .; \ 
    pwd; ls -la; \
    echo " ---- running init script ---"; /bin/bash ./init.sh; \
    echo -e "\n********************************************************" 
# END INITIALIZATION    

VOLUME [ "/data", "/opt", "/shell" ]
WORKDIR /opt
# ENTRYPOINT ["entrypoint.sh"]
CMD ["/bin/bash", "-l"]

答案1

docker 论坛上的一个帖子就是线索。问题出在 copy 命令上。我在 copy 语句中使缓存无效。

我需要两个复制语句。我需要通过它们自己的子文件夹复制包和初始化脚本。这样,如果我在初始化脚本子文件夹中更改了某些内容,包复制命令就不会失效。

这也解决了运行容器和使缓存无效的问题。附带的好处是现在我不需要手动清除缓存,因为只需更改 init 脚本文件夹中的任何内容即可。

COPY .src/packages ./packages
# PACKAGES
RUN \
    echo -e "\n ************************************************* \n"\
    echo "****** Building Image from Base: $BASE_IMAGE; : Distro: $LINUX_DISTRO; *****"; \
    echo " ---- running packages install script ---"; /bin/sh ./packages/packages.sh; \
    echo -e "\n********************************************************" 
# END PACKAGES    

COPY .src/init ./init

# INITIALIZATION
RUN echo -e "\n ************************************************* \n" \
    echo "****** Running Initialization Script "; \
    chmod -R +x .; \ 
    pwd; ls -la; \
    echo " ---- running init script ---"; /bin/bash ./init/init.sh; \
    echo -e "\n********************************************************" 
# END INITIALIZATION    

相关内容