urban-toolkit/utk

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"]