KaotoIO / kaoto-ui

Frontend for the Kaoto project to provide an easy-to-use integration framework based on Apache Camel.
https://www.kaoto.io
Apache License 2.0
88 stars 44 forks source link

Reduce container image size with multi-stage build #254

Closed evanshortiss closed 2 years ago

evanshortiss commented 2 years ago

A colleague was downloading and running this frontend and commented that it was a very large container image pull.

You folks might already be aware, but the image size could be reduced with a dockerfile similar to the example below. This reduced the image size from 2.65GB to 175MB in my test, and the React application loaded in my browser so I think it doesn't break anything.

FROM node:16 as appbuild

WORKDIR /app

# add `/app/node_modules/.bin` to $PATH
ENV PATH /app/node_modules/.bin:$PATH

COPY . ./
RUN yarn install
RUN echo "KAOTO_API=http://localhost:8081" > ./.env
HEALTHCHECK --interval=3s --start-period=10s CMD curl --fail http://localhost:8080/ || exit 1

RUN yarn build

FROM nginx:latest
COPY --from=appbuild /app/dist/* /usr/share/nginx/html/
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

I was curious about using cached layers for the build, but ran into Yarn issues that I didn't really understand!

Delawen commented 2 years ago

I was a complete newbie generating node based images :) Thank you! Do you want to create a PR with this?

evanshortiss commented 2 years ago

@Delawen sure. Will do. Are you guys using Yarn to speed up builds BTW? I noticed that there's a Yarn cache checked in, but I don't know enough about Yarn to understand the different versions of it being specified in package.json. Is that why the node_modules are added to the PATH too?

kahboom commented 2 years ago

Thanks @evanshortiss, I'm happy to see this issue. I'm not surprised the container image is huge, as I've done literally nothing to prepare for it. 😆 Lots of things to do for a production build as well, including minification, concatenation, and tree shaking. Any contributions are welcome should you have the interest and time. :)

Regarding Yarn, we're using Yarn Berry (2.x., 3.x). I can switch to npm if it makes it easier for others to collaborate, but basically Yarn 1.x and NPM are similar in that they use node_modules, whereas Yarn Berry (2.x, 3.x) with Plug’n’Play uses a much smaller version of node_modules in .yarn/cache, which, unlike node_modules, does get checked in, because the total file size is much smaller and ensures everyone is using the same version of everything, including Yarn.

It's also supposed to reduce the package installation time by around 70%. I will say, it doesn't seem to have gained as much momentum as quickly as I thought it would, probably due to breaking changes with Yarn 1.x, so if there is preference to use npm I'm happy to switch.

BTW there was a bug that was allowing node_modules to still get installed and breaks tests, so I'm fixing that now.

Relevant links:

evanshortiss commented 2 years ago

Very interesting, thanks for sharing those links. I was lost as to what Berry and other features were before those!

I did do a quick test and seems as though npm/yarn are similar in install times (~16 seconds) once npm has a cache built in wherever npm config get cache is set to, which is interesting. Definitely makes sense to use yarn to avoid the pesky version differences as you say, and probably helps CI time too depending on how cache is handled there!

I'll open a PR shortly now that I have a better understanding of this. Thank you 😄

evanshortiss commented 2 years ago

Related PR is #258