Reputation: 189
I am building my app into docker image.
My docker file:
FROM node:12-alpine
WORKDIR /usr/app
COPY ./package.json ./package.json
RUN yarn
COPY ./src ./src
COPY ./gulpfile.js ./gulpfile.js
COPY ./tsconfig.json ./tsconfig.json
RUN yarn build
RUN rm -rf ./node_modules
RUN rm -rf ./src
RUN rm -rf ./gulpfile.js
RUN rm -rf ./yarn.lock
RUN rm -rf ./package.json
RUN rm ./tsconfig.json
RUN cd dist && yarn
CMD ["node", "./dist/boot.js"]
After build I opened docker image and found my app in /user/app/dist
size is 264MB (including node_modules).
But docker image has 867MB
.
Why?
is there anything wrong in my dockerfile script? I am using node alpine, it should be small.
Upvotes: 7
Views: 7336
Reputation: 159781
Adding lines to a Dockerfile never makes an image smaller. Because of the way an image is constructed from layers, a RUN
line generally results in everything from the previous layer, plus whatever changes result from that RUN
command.
As a specific example in your Dockerfile:
# Build the contents of the dist/ directory
RUN yarn build
# Keep the entire contents of the previous layer
# PLUS add markers that the node_modules directory should be removed
RUN rm -rf ./node_modules
As @jonrsharpe points out in comments, you're probably looking for a multi-stage build. The basic concept here is that a second FROM
line will cause docker build
to completely start over from a new base image, but then you can COPY --from=
a previous stage into the final stage.
You might rebuild your existing image like so:
# Add "AS build" for later use
FROM node:12-alpine AS build
# This is exactly what you had before
WORKDIR /usr/app
COPY ./package.json ./package.json
RUN yarn
COPY ./src ./src
COPY ./gulpfile.js ./gulpfile.js
COPY ./tsconfig.json ./tsconfig.json
RUN yarn build
# Now build the actual image, starting over.
FROM node:12-alpine
WORKDIR /usr/app
COPY --from=build /usr/src/app/dist .
# but not its node_modules tree or anything else
CMD ["node", "boot.js"]
Upvotes: 12