Multi-Step building for docker (front-end)
supaidaman opened this issue · 2 comments
Currently, the dockerfile for the react frontend is running the appplication in de mode(start:web). That usally brings a bunch of dependencies that are not needed to the application itself. We can make that docker image smaller by using the following steps:
- Using a multi-stage build, so that only what's relevant to the project itself is bundled
- Trying to use a tool like webpack or esbuild to output the file as a minified file.
I have a sample dockerfile for the type of application I usually have here (I haven't tried changing at the code as of now to see how it will behave):
FROM node18-alpine3:latest AS base
WORKDIR /home/appuser/
FROM base as development
COPY package.json ./
COPY package-lock.json ./
COPY .npmrc ./
RUN npm install --omit=dev
RUN cp -R node_modules /tmp/node_modules
RUN npm install
COPY . .
RUN pwd
RUN ls -la
FROM development as builder
RUN npm run build
RUN pwd
RUN ls -la
FROM base as release
COPY --from=builder /tmp/node_modules ./node_modules
COPY --from=builder /home/appuser/dist ./dist
CMD [ "node", "./dist/app.js" ]
USER appuser
Basically, this makes the final app to have only the relevant production node_modules files and the outputed dist files.
Here's a better idea in how to use the multi-stage build. I tried here and it works. However, the image has still the same size as before since I'm not really clear about how the build and production scripts are supposed to work.
Was this front-end made with create-react-app or similar? I think we could try to review a little of it so that it's possible to parse the tsx and build it properly to prod.
###
FROM node:18-alpine AS base
# set working directory
WORKDIR /usr/src/utk-frontend
# add `/usr/src/app/node_modules/.bin` to $PATH
ENV PATH /usr/src/utk-frontend/node_modules/.bin:$PATH
FROM base as development
COPY package.json ./
COPY package-lock.json ./
RUN npm ci --omit=dev
RUN cp -R node_modules /tmp/node_modules
RUN npm ci
COPY . .
FROM development as builder
RUN npm run build:web
FROM base as release
COPY --from=builder /tmp/node_modules ./node_modules
COPY --from=builder /usr/src/utk-frontend/dist ./dist
CMD [ "npm", "run", "deploy:web" ]
I managed to reduce the image a little but by doing that I broke the front end hahaha:
# base
FROM node:18-alpine AS base
WORKDIR /usr/src/utk-frontend
COPY package*.json ./
RUN npm install
COPY . .
# for build
FROM base as builder
WORKDIR /usr/src/utk-frontend
RUN npm run build:web
# for production
FROM node:18-alpine AS base
WORKDIR /usr/src/utk-frontend
COPY package*.json ./
RUN npm install --omit=dev
COPY --from=builder /usr/src/utk-frontend/dist ./
#EXPOSE 3000
CMD ["npm", "run", "deploy:web"]