Search code examples
dockercachingnpmdocker-build

Does automatically updating my package.json at commit time disable docker build to reuse cache?


I've just started to get deep inside dockerfile syntax.

Here is the one I use currently:

FROM node:12-alpine as install

WORKDIR /Backend-graphql
COPY ./src ./src
COPY ./index.js ./index.js
COPY ./schema.graphql ./schema.graphql
COPY ./package.json ./
COPY ./package-lock.json ./package-lock.json
RUN npm install

FROM node:12-alpine as prismawork

WORKDIR /PrismaWork
COPY --from=install /Backend-graphql .
COPY ./datamodel.prisma ./datamodel.prisma
COPY ./prisma.yml ./prisma.yml
RUN npx prisma deploy
RUN npx prisma generate

FROM node:12-alpine
#curl needed for healthcheck
RUN apk --update --no-cache add curl
WORKDIR /app
COPY --from=prismawork /PrismaWork .
ENTRYPOINT ["npm", "start"]
EXPOSE 4000

From personnals tests and documentations founds online, i've respected the following advice :

  • Use multi-stage builds

But I notice something, docker do not reuse cache after the first COPY layer different in current and followings build stages. And I think its a problem, because I use an automatic bump version git hook based on commit message semantic versionning syntax who modifies my package.json. So, at each commit docker build re-RUN npm install and subsequents layers.

First of all, have I understood docker cache layering system ?

Secondly, should I use an other file for automatic bumping version and COPY it at the very end of my Dockerfile ?


Solution

  • First of all, have I understood docker cache layering system?

    Yes, you should. If any change happens in any step, like changes in package.json, the docker will rebuild the rest of the steps.

    No need to copy from the same image multiple times. We are also doing npm install after performing unrelated steps to catching other steps.

    FROM node:12-alpine
    #curl needed for healthcheck
    RUN apk --update --no-cache add curl
    WORKDIR /app
    COPY ./src ./src
    COPY ./index.js ./index.js
    COPY ./schema.graphql ./schema.graphql
    COPY ./datamodel.prisma ./datamodel.prisma
    COPY ./prisma.yml ./prisma.yml
    COPY ./package.json ./
    COPY ./package-lock.json ./package-lock.json
    RUN npm install
    RUN npx prisma deploy
    RUN npx prisma generate
    ENTRYPOINT ["npm", "start"]
    EXPOSE 4000
    

    Multiple staging useful when you need to build between multiple images like this example:

    FROM node:12-alpine
    RUN npm install -g gzipper
    WORKDIR /build
    ADD . .
    RUN npm install
    ARG CONFIGURATION
    RUN npm run build:${CONFIGURATION}
    RUN gzipper --gzip-level=6 ./dist
    
    FROM nginx:latest
    WORKDIR /usr/share/nginx/html
    COPY --from=0 /build/dist .
    COPY nginx/default.conf /etc/nginx/conf.d/default.conf