Docker images are a combination of layers, each instruction in your Dockerfile creates a layer. The docker daemon can reuse those layers between builds if the instructions are identical or in the case of a COPY
or ADD
files used are identical.
- Image taken from Digging into Docker layers by jessgreb01*
If you have a label containing the build number at the top of your Dockerfile, the cache will be invalidated at every build
#Beginning of the file
FROM node:10.22.0-alpine3.11 as builder
# Don't do that here!
LABEL build_number="483"
#... Rest of the Dockerfile
See: On the importance of docker ignore
The docker ignore avoids copying files that could bust our cache logic, like tests results reports, logs or temporary files.
It is recommended to create a base docker image that has all the system packages you use. If you really need to install packages using apt
,yum
,apk
or the likes, this should be one of the first instructions. You don't want to reinstall make,gcc or g++ every time you build your node app.
Do not install package only for convenience, this is a production app.
COPY "package.json" "package-lock.json" "./"
RUN npm ci
The lockfile and the package.json change less often. Copying them first will keep the npm install
step in the cache, this saves precious time.
COPY . .
RUN npm run build
#Create node image version alias
FROM node:10.22.0-alpine3.11 as builder
RUN apk add --no-cache \
build-base \
gcc \
g++ \
make
USER node
WORKDIR /app
COPY "package.json" "package-lock.json" "./"
RUN npm ci --production
COPY . "./"
FROM node as app
USER node
WORKDIR /app
COPY --from=builder /app/ "./"
RUN npm prune --production
CMD ["node", "dist/server.js"]
#Create node image version alias
FROM node:10.22.0-alpine3.11 as builder
RUN apk add --no-cache \
build-base \
gcc \
g++ \
make
USER node
WORKDIR /app
COPY "package.json" "package-lock.json" "./"
RUN npm ci
COPY . .
RUN npm run build
FROM node as app
USER node
WORKDIR /app
# Only copying the files that we need
COPY --from=builder /app/node_modules node_modules
COPY --from=builder /app/package.json .
COPY --from=builder /app/dist dist
RUN npm prune --production
CMD ["node", "dist/server.js"]
Docker docs: https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#leverage-build-cache