构建时如何调试docker-compose缓存未命中

时间:2020-02-24 21:55:49

标签: docker docker-compose

我正在执行相同的docker-compose build命令,但发现它错过了缓存

Building service1
Step 1/31 : FROM node:10 as build-stage
 ---> a7366e5a78b2
Step 2/31 : WORKDIR /app
 ---> Using cache
 ---> 8a744e522376
Step 3/31 : COPY package.json yarn.lock ./
 ---> Using cache
 ---> 66c9bb64a364
Step 4/31 : RUN yarn install --production
 ---> Running in 707365c332e7
yarn install v1.21.1
..
..
..

您可以看到缓存丢失了,但是我不明白为什么 调试更改并尝试找出原因的最佳方法是什么

编辑:问题不在于调试我的特定问题。但是,我一般如何调试此类问题。我怎么知道为什么docker-compose认为事情发生了变化(尽管我很确定没什么变化),哪些文件/命令/结果不同?

1 个答案:

答案 0 :(得分:2)

我通常如何调试此类问题。我怎么知道为什么docker-compose认为事情发生了变化(尽管我很确定没什么变化),哪些文件/命令/结果是不同的

通常,as shown here

我有点沮丧,我似乎找不到任何使Docker构建更加冗长的方法

但是关于docker-compose,这取决于您使用的版本和选项。
moby/moby issue 30081解释(通过Sebastiaan van Stijn (thaJeztah)

在许多(或全部)情况下,docker-composedocker build的当前版本将不会共享构建缓存,或者至少不会产生相同的摘要。

这样做的原因是,当使用docker-compose发送构建上下文时,它将使用略有不同的压缩(docker-compose是用Python编写的,而docker cli是用Python编写的去)。
可能还有其他差异,因为它们是不同的实现(和语言)。

(在docker/compose issue 883中也进行了讨论)

下一版docker compose将具有(当前选择加入)功能,使其使用实际的docker cli来执行构建(通过设置COMPOSE_DOCKER_CLI_BUILD=1环境变量) 。这是在docker/compose#6865(1.25.0-rc3 +,2019年10月)中实现的

借助该功能,docker compose还可以使用 BuildKit 来构建映像(设置DOCKER_BUILDKIT=1环境变量)。
如果可能的话,我强烈建议您使用buildkit
使用BuildKit时(需要Docker 18.09或更高版本,并且目前不支持构建Windows容器),您会看到构建速度有了极大的提高,并且在重复构建中将构建上下文发送到守护程序所需的时间(buildkit使用交互式会话仅发送在构建过程中需要的那些文件,而不是上传整个构建上下文。)

因此,请首先仔细检查您的docker-compose是否使用BuildKit,以及问题(缓存未重用)是否仍然存在,然后:

COMPOSE_DOCKER_CLI_BUILD=1 DOCKER_BUILDKIT=1 docker-compose build

塞巴斯蒂安添加到issue 4012

BuildKit仍处于启用状态(因为尚不支持Windows),但具有生产质量,可以用作构建Linux映像的默认选项。

最后,我意识到,对于Azure管道,您(可能)无法控制已安装的Docker和Docker Compose的版本,但是对于您的本地计算机,请确保更新至最新的19.03补丁程序版本;例如,Docker 19.03.3及更高版本对BuildKit的缓存机制进行了各种改进和修复(请参见docker#373)。


请注意,在您的特定情况下,即使这不是您问题中的主要问题,也很高兴知道以下内容是否有帮助:

yarnpkg/yarn/issue 749建议:

您将不会挂载Yarn缓存目录。相反,您应该确保利用Docker的图像层缓存。

这些是我正在使用的命令:

COPY package.json yarn.lock ./
RUN yarn --pure-lockfile

然后尝试使用yarn install命令,查看docker是否仍然不使用其缓存。

RUN yarn install --frozen-lockfile --production && yarn cache clean 

别忘了yarn cache clean,以prevent the yarn cache from winding up in docker layers

如果问题仍然存在,请直接切换到buildkit(进行测试),并使用buildctl build --progress=plain查看更详细的输出,并调试缓存情况。


通常,multi-stage approach, as shown here可能会有用:

FROM node:alpine
WORKDIR /usr/src/app
COPY . /usr/src/app/

# We don't need to do this cache clean, I guess it wastes time / saves space: https://github.com/yarnpkg/rfcs/pull/53
RUN set -ex; \
  yarn install --frozen-lockfile --production; \
  yarn cache clean; \
  yarn run build

FROM nginx:alpine
WORKDIR /usr/share/nginx/html
COPY --from=0 /usr/src/app/build/ /usr/share/nginx/html