Building docker image for a REACT App
Let me start by sharing my final docker file. The docker file builds a react project and serves it using nginx.
It itself is pretty descriptive, but if there is anything you don't understand then ping me.
#First we build the app.
FROM node:alpine3.10 as build
WORKDIR /app
RUN echo "Starting stage 1 Build"
#We pass arguments to run our build
ARG yourregistrytoken
ARG someapiurl
ARG cdnurl
ARG buildNumber
ENV NODE_ENV=production
COPY .dockernpmrc ./.npmrc
COPY ["package.json", "package-lock.json*", "./"]
RUN npm set progress=false && \
npm config set depth 0 && \
npm install --only=production
RUN rm -f .npmrc
COPY . ./
RUN rm -f .env
RUN rm -f .env.local
RUN rm -rf build
# I have a custom docker env file that I copy and replace values in.
COPY .dockerenv ./.env
# This code below replaces the values from the argument.
RUN sed -i "s/#someapiurl#/${someapiurl}/g" ./.env
RUN sed -i "s/#cdnurl#/${cdnurl}/g" ./.env
RUN sed -i "s/#buildNumber#/${buildNumber}/g" ./package.json
RUN cat ./.env
# Just to check what is going on with the files.
RUN ls -al
# Let's run the NPM build
RUN npm run build
# #Stage two - Take the Build folder and serve :)
FROM nginx:alpine
RUN rm /etc/nginx/conf.d/default.conf
COPY --from=build /app/build /usr/share/nginx/html
COPY ./nginx.conf /etc/nginx/conf.d
ENTRYPOINT ["nginx", "-g", "daemon off;"]
There are 2 files that are very important for the execution to work. The ".dockerenv" which looks like this
REACT_APP_Dashboard_Api_URL=https://#someapiurl#/api
REACT_APP_imagecdn=https://#cdnurl#
SKIP_PREFLIGHT_CHECK=true
Version=#version#
I replace all these values using sed. These values are then embedded into the built application which is where I spent an awful lot of time. On K8S, injecting values using config-maps just does not work for react applications. Using this way also means we can inject values at build time and can easily integrate for CI/CD.
This results in a super tiny docker image of about 40 Mb and runs smoothly in K8S. The load time is zero for the image is compiled and the entry point is with nginx. Honestly, it took me a while to get to this and I really hope I save someone some time. :)
Comments