Search code examples
node.jsjsondockernpmdocker-build

Docker build does not use cache from npm ci


I have created my Dockerfile with attention to use the docker cache system. I'm adding the package.json and package-lock.json files into a clean container, and then run npm ci command. I expect it to be used from the cache if the package.json and package-lock.json were not changed, but it keeps running. Am I missing something? Is there something wrong with my 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

The output I get:

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
 > [email protected] 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'
[...]

Solution

  • Assuming that you don't run other commands before package.json was added, your Dockerfile is fine and the layer adding your package file is cached. For example, we build a simple Dockerfile that just adds your package.json config file:

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

    First run:

    $ 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
    

    Second run

    $ 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
    

    As you can see, the caching works. Could you please verify this with such a minium example? Most of the time caching breaks because of a suboptimal ordner. Please check the following:

    • Execute the build command twice. Caching could only work after the first run
    • Make sure, that no other steps you may havent posted here were executed in your Dockerfile that invalidates the cache
    • Are there any cleanup commands running? Something like docker prune or docker image prune (or manual list/delete images on older versions) would delete your image
    • Check/post your calls how you build the image