Dockerized React app not recompiling code - reactjs

I'm trying to dockerize a basic CRA template created through npx create-react-app project-name, of which Dockerfile would look like:
FROM node:latest
WORKDIR /usr/src/client
COPY ./ ./
RUN npm install
EXPOSE 3000
CMD ["npm", "start"]
I've built the image by running docker build -t containername .
and then run it with docker run -it -p 3000:3000 containername
Everything works fine, the container runs successfully and I can see the webpage running on the browser.
Problem here is webpack hot reloading not working, causing the app to not recompile upon changes.
Same question was posed already here and here but sadly with unsuccessful results. Problem seems to appear for Windows users, but in my case I'm on Mac.
I've tried already:
Updating npm start script with CHOKIDAR_USEPOLLING=true react-scripts start
Adding EXPOSE 35729 as explained here
Any suggestion is highly appreciated, thank you in advance!

i think webpack server doesn't see any new changes, because you modify your local file, but container uses its copies in runtime, which was passed in build time. so you should mount your local dir to container.
i can suggest you use docker-compose to mount your work dir from host to container:
docker-compose.yml
version: '3.4'
services:
app:
build: ./
volumes:
- ./src:/usr/src/client
ports:
- 3000:3000 # HOST:CONTAINER
command: npm start
or maybe use -v $(pwd)/src:/app/src in run command docker run ...

Unbelievably, the issue was caused by the working directory naming.
In order to fix it, I simply had to change it from /usr/src/client to /app and it started recompiling, even though I have no clue of the why.
FROM node:latest
WORKDIR /app
COPY ./ ./
RUN npm install
EXPOSE 3000
CMD ["npm", "start"]

The following worked for me.
docker run -p 3000:3000 -v ${PWD}:/usr/app -e CHOKIDAR_USEPOLLING=true globoreactapp/latest
Run that on windows poweshell.
If you are using windows cmd, you may try,
docker run -p 3000:3000 -v %cd%:/usr/app -e CHOKIDAR_USEPOLLING=true globoreactapp/latest
And if you are running on some linux distro, you can try something like this.
docker run -p 3000:3000 -v -e CHOKIDAR_USEPOLLING=true $(pwd):/usr/app
So here specifying
-e CHOKIDAR_USEPOLLING=true
made the difference for me.
Also with docker-compose, you need to add the same environment variable. Mine looks as follows.
version: '3'
services:
redis-server:
image: 'redis'
node-app:
build:
context: ./globoappserver
ports:
- "9080:8080"
container_name: api-server
ui:
build:
context: ./globo-react-app-ui
environment:
- CHOKIDAR_USEPOLLING=true
ports:
- "7000:3000"
stdin_open: true
volumes:
- ./globo-react-app-ui:/usr/app

Related

React JS doesn't update in Docker compose

First of all, I am really new to dockers and everything that relates to it. I tried to use tutorials and instructions from web, but I see the answers from this question and I guess I don't have other options other than move to Linux completely (which I really don't want to do)
I have a docker-compose project with ASP.NET Core, Nginx and React. FrontEnd and BackEnd have their own dockerfile and dockerignore.
FrontEnd doesn't update code changes at all.
I tried to build only client service by using docker-compose build --no-cache but after two minutes of compiling I see that it didn't change anything.
Only possible solution for me is to delete docker-compose project and compile every service again. But it makes development so much difficult.
dockerfile:
FROM node:16-alpine
WORKDIR /app
ENV PATH /app/node_modules/.bin:$PATH
COPY ./package.json /app
RUN npm install
COPY . .
RUN npm run build
CMD ["npm", "start"]
docker-compose.yml (client service):
client:
image: client
build:
context: ./walletfrontend
dockerfile: Dockerfile
environment:
- WATCHPACK_POLLING=true
I tried to use WATCHPACK_POLLING=true as suggested in another question but I think it does nothing and I am not really sure why is it needed for.
UPDATE:
So I think I found a solution in this article:
https://shahmirprogrammer.medium.com/docker-with-react-changes-reflect-real-time-inside-a-container-f83acf208f8a
It really updates the changes in real time.
So my next goal is to change this strange command which I don't have a clue what it does to docker-compose equivalent:) :
docker run -d -p 3000:3000 -v /app/node_modules -v $(pwd):/app --name dockerized-react-app react-app-image:1
UPDATE #2:
So I think solution is to use volumes with correct path to my host machine:
volumes:
- /app/node_modules
- ./walletfrontend:/app
It's been almost a week and it was really difficult to find a solution for this. I hope this would help in the future for newbies like me
FROM node:16-alpine
WORKDIR /app
ENV PATH /app/node_modules/.bin:$PATH
COPY ./package.json /app
COPY . .
RUN npm install
RUN npm run build
CMD ["npm", "start"]
copy all the files before you run npm install.
a really useful tutorial on this can be found here
https://mherman.org/blog/dockerizing-a-react-app/
Dockerfile
# pull official base image
FROM node:13.12.0-alpine
# 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 ./
RUN npm install --silent
RUN npm install react-scripts#3.4.1 -g --silent
# add app
COPY . ./
# start app
CMD ["npm", "start"]
docker-compose.yml
version: '3.7'
services:
sample:
container_name: sample
build:
context: .
dockerfile: Dockerfile
volumes:
- '.:/app'
- '/app/node_modules'
ports:
- 3001:3000
environment:
- CHOKIDAR_USEPOLLING=true
that guide I just linked you also contains info on how to get your app production ready

How to point docker to run a React app and open in browser?

I am trying to run a docker on my React app but it does not connect. Actually I see it is up at address 0.0.0.0:3000, but does not open in a browser. I am new to docker and still figuring out in how it works. How can I connect and open the app?
docker-compose.yml
version: "3"
services:
node:
build: .
image: node:16
container_name: myapp
tty: true
stdin_open: true
command: bash
restart: always
working_dir: /app
volumes:
- ./:/app
ports:
- 3000:3000
Dockerfile
FROM node:16-alpine
WORKDIR /app
COPY package.json .
RUN npm install
COPY . .
CMD ["npm", "start"]
Running at port 3000
e810d9f622c0 node:16 "docker-entrypoint.s…" 5 minutes ago Up 5 minutes 0.0.0.0:3000->3000/tcp, :::3000->3000/tcp
Your docker-compose file contains a number of misunderstandings
When you have both build: and image: docker-compose will build an image based on your dockerfile and tag it with the name you give in image:. However, you name yours node:16 which is not a good idea since that could be mistaken for the official node image.
you have both tty: and stdin_open: set to true. If you want to run node, then there's no need to run it interactively.
Your command: overrides the CMD defined in the Dockerfile, so your npm start command is no longer run.
Setting work_dir: to /app is superfluous since the WORKDIR is already set to /app in the Dockerfile.
Mapping a volume to /app hides everything in the /app path in the docker image. You've probably added this to get hot reload. Doing it this way is not a good idea, since it makes evereything in your Dockerfile that builds the /app directory irrelevant.
That leaves us with
version: "3"
services:
node:
build: .
container_name: myapp
restart: always
ports:
- 3000:3000
Run that and you should be able to go to http://localhost:3000/ and see your app.

Next.js Docker Development Setting

I want to run my Next.js code using docker. Here is my code structure
When I build it, it returns success like this.
But, when I open it, I get this...
my docker.compose.yaml file contain this...
version: '3.8'
services:
web:
image: 'app'
ports:
- '3000:3000'
container_name: app-next
build:
context: web
dockerfile: Dockerfile
volumes:
- ./web:/usr/src/app
- /usr/src/app/node_modules
- /usr/src/app/.next
my Dockerfile contain this...
FROM node:12-alpine
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
COPY package*.json yarn.lock /usr/src/app/
RUN yarn install
EXPOSE 3000
CMD ["yarn", "dev"]
my browser console contain this...
Anyone can fix this?
Thanks

Dockerized react app differences between running the image with and without docker-compose

// Dockerfile
# pull base image
FROM node:10.15.1-alpine
# 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 ./yarn.lock ./
RUN yarn install
RUN yarn global add react-scripts#3.4.1 // not sure if this is even necessary
# add app
COPY . ./
# start app
CMD ["yarn", "start"]
Command I'm running to build it:
docker build -t matrix-fe:dev .
Command to run it:
docker run -it --rm -v ${PWD}:/app -v /app/node_modules -p 3000:3000 -e CHOKIDAR_USEPOLLING=true matrix-fe:dev
And then this is my composer yml:
version: '3.7'
services:
matrix-fe:
container_name: matrix-fe
build:
context: ./a-fe
dockerfile: Dockerfile
volumes:
- './a-fe:/app'
- '/app/node_modules'
ports:
- 3000:3000
environment:
- CHOKIDAR_USEPOLLING=true
Then to build and run it:
docker-compose up --build
Error I'm getting:
matrix-fe | yarn run v1.13.0
matrix-fe | $ react-scripts start
matrix-fe | It looks like you're trying to use TypeScript but do not have typescript installed.
matrix-fe | Please install typescript by running yarn add typescript.
matrix-fe | If you are not trying to use TypeScript, please remove the tsconfig.json file from your package root (and any TypeScript files).
matrix-fe |
Why is this happening? I can obviously try to also install typescript, but it is a dependency in package.json and should be installed, I also added node_modules to path. How is running the image with and without docker-compose different? Compose does create a different image called matrix_matrix-fe, but then Dockerfile hasn't changed. docker-compose.yml is in a top level folder, structure looks like this:
/matrix
/a-fe
./package.json
./Dockerfile
...
/a-be
./docker-compose.yml
Help me understand what's different, volumes are same, ENV variables are same, not seeing anything off.
Edit: forgot to mention that running the image without docker-compose doesn't output errors, it's working properly.

How to build and deploy ReactJs using docker-compose

I'm trying to make that every time a new change is made on the app I do not need to build the app, and then run the docker-compose file. What I'm trying to do is that when I change code in my application (ReactJs) to just go and run docker-compose file, so then docker-compose will build and run it using nginx.
Here's what my docker-compose.yml looks like:
version: '2'
services:
nginx:
image: 'bitnami/nginx:1.14.2'
ports:
- '80:8080'
volumes:
- ./build:/var/www/my-app
- ./nginx.conf:/opt/bitnami/nginx/conf/nginx.conf:ro
Right now with this code, I need to build the application myself running npm run build and then go and run the docker-compose file so it would take the changes.
I don't exactly know how to do it, so I assume I need to create a Dockerfile run npm run build and then call the bitmani/nginx:1.14.2 based on their docs: https://hub.docker.com/r/bitnami/nginx/
FROM node:8.7.0-alpine
RUN npm install
RUN npm run build
docker run --name nginx \
-v /path/to/my_vhost.conf:/opt/bitnami/nginx/conf/vhosts/my_vhost.conf:ro \
-v /path/to/nginx-persistence/nginx/conf/bitnami/certs:/bitnami/nginx/conf/bitnami/certs \
bitnami/nginx:latest
and in docker-compose.yml call build . instead of image: bitnami/nginx.
You should use a stage build for this. Your Dockerfile should look like this:
# Stage 1 - Building image
FROM node:8.7.0-alpine as node
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
# Stage 2 - Running image
FROM bitnami/nginx:1.14.2
COPY --from=node /usr/src/app/build /var/www/my-app
COPY ./nginx.conf /opt/bitnami/nginx/conf/nginx.conf
And your docker-compose:
version: '3.3'
services:
myApp:
image: myapp:1.0
container_name: my-app
build: .
ports:
- 80:8080
I adapted this from one of my projects so if you have any issues let me know and I'll check them.
I hope it helps.

Resources