Use npm run build serveral times - reactjs

I have a React App and I need to run it in docker. Inside this container I need to build 3 instance with the same code, but with different environments by replacing .env.production with my .env.production2 and .env.production3 file. I have a problem with dockerfile: if I'm not use RUN npm install after changing WORKDIR - build stops with error:
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm WARN Local package.json exists, but node_modules missing, did you mean to install?
So right now it works only with this dockerfile:
FROM node:12 as build-box
COPY . /app/expert
COPY . /app/expert-control-chat
COPY . /app/expert-control-support
WORKDIR /app/expert
ARG NPMTOKEN
ENV NPMTOKEN=$NPMTOKEN
RUN npm config set _auth $NPMTOKEN
RUN npm install
# Build
FROM build-box as publish
WORKDIR /app/expert
RUN npm run build
WORKDIR /
RUN rm -rf /app/expert-control-chat/.env.production
COPY .env.production.chat-control /app/expert-control-chat/.env.production
WORKDIR /app/expert-control-chat
RUN npm install
RUN npm run build
WORKDIR /
RUN rm -rf /app/expert-control-support/.env.production
COPY .env.production.chat-support /app/expert-control-support/.env.production
WORKDIR /app/expert-control-support
RUN npm install
RUN npm run build
FROM nginx as runtime
RUN rm -rf /etc/nginx/conf.d
COPY nginx.conf /etc/nginx/nginx.conf
WORKDIR /app/expert
COPY --from=publish /app/expert/build ./
WORKDIR /app/expert-control-chat
COPY --from=publish /app/expert-control-chat/build ./
WORKDIR /app/expert-control-support
COPY --from=publish /app/expert-control-support/build ./
# Start
EXPOSE 3000
CMD ["nginx", "-g", "daemon off;"]
Can you tell me the correct way to make a build?
I think that there is another way to build it, but I can't get that.

Related

React App Docker image copy is taking too long

Below is my Dockerfile
FROM node:16 as build-stage
WORKDIR /app
COPY package*.json /app/
ARG PROJECT_NAME=react-ui
RUN npm install --force
COPY ./ /app/
RUN npm run build
FROM nginx:alpine
WORKDIR /usr/share/nginx/html
RUN rm -rf ./*
COPY --from=build-stage /app/build/ .
EXPOSE 8080
ENTRYPOINT ["nginx", "-g", "daemon off;"]
Step --> COPY ./ /app/ is taking too long, currently almost 50 mins and running. How do I fix this?
I tried building without the below step and it takes 4 mins average
RUN npm run build
but what I understand is we need to include npm run build too, right? This is my first time dockerizing a React Frontend App. Your help would be really appreciated, thank you
I suspect it is copying node_modules folder as well, although I have included that in .dockerignore. So my solution to this was to specify directly which folder and contents I need to copy rather than copying everything using COPY ./ /app/

Multiple react apps on nginx with seperate folders and Dockerfiles

This is my admin react Dockerfile;
FROM node:16-alpine AS builder
WORKDIR /usr/src/app
COPY package*.json ./
COPY package-lock*.json ./
RUN npm install --force
COPY . .
RUN npm run build
## second stage
FROM nginx:1.22.0-alpine
COPY --from=builder /usr/src/app/build/ /usr/share/nginx/admin
RUN rm /etc/nginx/conf.d/default.conf
COPY nginx/nginx.conf /etc/nginx/conf.d
EXPOSE 3030:3030
CMD ["nginx","-g","daemon off;"]
This my main react app:
## first stage
FROM node:16-alpine AS builder
WORKDIR /usr/src/app
COPY package*.json ./
COPY package-lock*.json ./
RUN npm install --force
COPY . .
RUN npm run build
## second stage
FROM nginx:1.22.0-alpine
COPY --from=builder /usr/src/app/build/ /usr/share/nginx/main
RUN rm /etc/nginx/conf.d/default.conf
COPY nginx/nginx.conf /etc/nginx/conf.d
EXPOSE 80:80
EXPOSE 443:443
CMD ["nginx","-g","daemon off;"]
So i have one main react app and one that is admin, i am trying to
copy their build to the same nginx but i can not find way around this.
With this way am i creating two nginx server image? I have no idea i
am a newbie at this. Thanks in advance for any help :)

What is a normal npm install time when dockerizing a react js app?

I am trying to dockerize a simple react js app. It takes so long time when running npm install. It's been 1 hour it's still running. Is it just because the memory of my hardware too low? It's 1gb.
Below is my dockerfile
FROM node:lts-alpine
ENV NODE_ENV=production
WORKDIR /usr/src/app
COPY ["package.json", "package-lock.json*", "npm-shrinkwrap.json*", "./"]
RUN npm install --production verbose
COPY . .
EXPOSE 3000
RUN chown -R node /usr/src/app
USER node
CMD ["npm", "start"]

Docker image size for ReactJS

I'm using following Dockerfile for ReactJS application:
FROM node:latest
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . ./
RUN npm run build
RUN npm install -g serve
RUN rm -rf node_modules
EXPOSE 3000
CMD ["serve", "-s", "build"]
I'm installing node_modules, but I'm deleting node_modules after I run the npm run build. But still image size in GBs. May I know the reason please?
use the alpine version.
the size only 38 MB (the "standard" is 332 MB)
https://hub.docker.com/layers/node/library/node/current-alpine3.14/images/sha256-2829f9b05a85038bd04412c45e5929f0005c64f8ae444e65ba4e02635f904871?context=explore

npm run tests in docker with travis CI

I am deploying a react app to Heroku via TravisCI. The fact that I'm using Heroku doesn't really affect what I'm about to ask, I'm pretty sure, it's just there for context. Travis successfully deploys the app until I add a testing step (the script section) in .travis.yml:
language: generic
sudo: required
services:
- docker
before_install:
- docker build -t myapp:prod -f Dockerfile.prod .
script:
- docker run -e CI=true myapp:prod npm run test
after_success:
- docker build -t myapp:prod -f Dockerfile.prod .
- echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_ID" --password-stdin
- docker push myapp:prod
deploy:
provider: heroku
app: myapp
skip_cleanup: true
api_key:
secure: <my_key>
However, my Dockerfile.prod is a multi-stage node + nginx where the nginx stage doesn't keep any node or npm stuff:
# build environment
FROM node:13.12.0-alpine as builder
# set working directory
WORKDIR /app
# add `/app/node_modules/.bin` to $PATH
ENV PATH /app/node_modules/.bin:$PATH
# install app dependencies
COPY package.json ./
COPY package-lock.json ./
# some CI stuff I guess
RUN npm ci
RUN npm install react-scripts#3.4.1 -g --silent
COPY . ./
RUN npm run build
# production environment
FROM nginx:stable-alpine
COPY nginx.conf /etc/nginx/conf.d/default.conf
# If using React Router
COPY --from=builder /app/build /usr/share/nginx/html
# For Heroku
CMD sed -i -e 's/$PORT/'"$PORT"'/g' /etc/nginx/conf.d/default.conf && nginx -g 'daemon off;'
Therefore, it is my understanding that .travis.yml tries to run that npm run test command inside my nginx container and can't execute npm commands (no node installed, right?). So guided by SO answers such as this one I started adding commands into that nginx stage such as
COPY package.json ./
COPY package-lock.json ./
RUN apk add --update npm
but I realized I might be approaching this the wrong way. Should I perhaps be adding npm through Travis? That is, should I include in .travis.yml in the scripts section something like docker run -e CI=true myapp:prod apk add --update npm and whatever else is necessary? This would result in a smaller nginx image no? However, would I run into problems with package.json from the node stage in Dockerfile.prod or anything like that?
In summary, to use TravisCI to test a dockerized react app served with nginx, at what point should I install npm into my image? Does it happen as part of script in .travis.yml or does it happen in Dockerfile.prod? If it is recommened to npm run tests inside Dockerfile.prod, would I do that in the first stage (node) or the second (nginx)?
Thanks
EDIT: Not sure if this can be considered solved, but a user on Reddit recommended to simply RUN npm run test right before the RUN npm run build.

Resources