首页 > 解决方案 > Docker 构建不使用来自 npm ci 的缓存

问题描述

我创建了我的 Dockerfile,并注意使用 docker 缓存系统。我将package.jsonandpackage-lock.json文件添加到一个干净的容器中,然后运行npm ci命令。package.json如果andpackage-lock.json没有更改,我希望它可以从缓存中使用,但它会继续运行。我错过了什么吗?我的 Dockerfile 有问题吗?

FROM node:13.10.1-stretch as base

ADD package.json /app/package.json
ADD package-lock.json /app/package-lock.json
WORKDIR /app

RUN npm ci --unsafe-perm

我得到的输出:

Step 1/12 : FROM node:13.10.1-stretch as base
  ---> 7aef30ae6655
 Step 2/12 : ADD package.json /app/package.json
  ---> ce655a3453f2
 Step 3/12 : ADD package-lock.json /app/package-lock.json
  ---> 797cda1e10b2
 Step 4/12 : WORKDIR /app
 Removing intermediate container 5b6929b80ad6
  ---> 80c2aac903c5
 Step 5/12 : RUN npm ci --unsafe-perm
  ---> Running in 7732a8aca146
 > fsevents@1.2.12 install /app/node_modules/webpack-dev-server/node_modules/fsevents
 > node-gyp rebuild
 make: Entering directory '/app/node_modules/webpack-dev-server/node_modules/fsevents/build'
   SOLINK_MODULE(target) Release/obj.target/.node
   COPY Release/.node
 make: Leaving directory '/app/node_modules/webpack-dev-server/node_modules/fsevents/build'
[...]

标签: node.jsjsondockernpmdocker-build

解决方案


假设您在添加之前 没有运行其他命令,那么您很好,并且添加了您的包文件的层被缓存了。例如,我们构建了一个简单的 Dockerfile,它只添加了您的配置文件:package.jsonDockerfilepackage.json

FROM node:13.10.1-stretch as base
ADD package.json /app/package.json

首轮:

$ docker build -t so-example .
Sending build context to Docker daemon  3.072kB
Step 1/2 : FROM node:13.10.1-stretch as base
13.10.1-stretch: Pulling from library/node
[...]
Status: Downloaded newer image for node:13.10.1-stretch
 ---> 7aef30ae6655
Step 2/2 : ADD package.json /app/package.json
 ---> a7bb80c06ecb
Successfully built a7bb80c06ecb
Successfully tagged so-example:latest

第二轮

$ docker build -t so-example .
Sending build context to Docker daemon  3.072kB
Step 1/2 : FROM node:13.10.1-stretch as base
 ---> 7aef30ae6655
Step 2/2 : ADD package.json /app/package.json
 ---> Using cache
 ---> a7bb80c06ecb
Successfully built a7bb80c06ecb
Successfully tagged so-example:latest

如您所见,缓存有效。您能否用这样一个小型示例来验证这一点?大多数情况下,缓存由于次优排序而中断。请检查以下内容:

  • 执行两次构建命令。缓存只能在第一次运行后起作用
  • 确保在您的 Dockerfile 中没有执行您可能未在此处发布的其他步骤,从而使缓存无效
  • 是否有任何清理命令正在运行?docker prunedocker image prune(或旧版本上的手动列表/删除图像)之类的东西会删除您的图像
  • 检查/发布您的电话,您如何构建图像

推荐阅读