Well, there's this Node.js app that I built using Typescript + ExpressJS, and now I'm trying to setup docker to have both a working development container and a production one.
I'd like to have only one Dockerfile in order to use the multi-stage building process.
My project consists of the root folder, inside of it there are all these dockerfile and compose files, and also my package.json, src/ folder, yarn.lock and etc.
For now I have this:
Dockerfile
FROM node:14.18.1-alpine3.14 as base
ENV APP=/app
WORKDIR $APP
COPY . $APP/
RUN yarn install --frozen-lockfile &&\
rm -rf "$(yarn cache dir)"
RUN yarn build
FROM base as prod
ENV APP=/home/node/app
WORKDIR $APP
RUN chown node:node $APP
USER node
COPY --chown=node:node --from=base ./app/dist/ $APP/dist/
COPY --chown=node:node package.json yarn.lock $APP/
RUN NODE_ENV=production yarn install --frozen-lockfile &&\
rm -rf "$(yarn cache dir)"
If I build the base stage only, this is the image I get:
355.65 MB of image size.
Now if I check how big the node_modules
inside the image is, this is:
That's ok for a dev node_modules.
Checking the layers with
dive
, I get these:
You can see that 237 MB of those 355 is the node_modules folder.
Now, the production part.
If I build to the prod
target of the dockerfile, that's my image size:
That's even bigger than the dev one.
Checking the node_modules size inside of that image:
Wen from 237 to only 36 MB, really good
But now if I check the layers from that image, that's the result:
The 237 MB node_modules is still there, that's almost the entire image size. How can I avoid having that thresh in my production image? Without that, the result image should be something like 80 MB only, really better than 391.
Please, help me with that!!!