skip to Main Content

I am trying to set up React with docker, but for some reason I cannot get the hot reload to work. Currently, if I create a file it recompiles, but if I change something in a file it does not. Also, I didn’t change any packages or configuration files, the project was generated with npx create-react-app projectname --template typescript.

From researching this online I found out that I needed to add CHOKIDAR_USEPOLLING=true to a .env file, I tried this but it didn’t work, I tried placing the .env in all directories in case I placed it in the wrong one. I also added it to the docker-compose.yml environment.

In addition to this, I also tried downgrading react-scripts to 4.0.3 because I found this, that also didn’t work.

I also tried changing a file locally and then checking if it also changes inside the docker container, it does, so I’m pretty sure my docker related files are correct.

Versions

  • Node 16.14
  • Docker Desktop 4.5.1 (Windows)
  • react 17.0.2
  • react-scripts 5.0.0

Directory structure

project/
│   README.md
│   docker-compose.yml    
│
└───frontend/
    │   Dockerfile
    │   package.json
    │   src/
    │   ...

Dockerfile

FROM node:16.14-alpine3.14

WORKDIR /app

COPY package.json .
COPY package-lock.json .
RUN npm install 

CMD ["npm", "start"]

docker-compose.yml

services:
  frontend:
    build: ./frontend
    ports:
      - "3000:3000"
    volumes:
      - "./frontend:/app"
      - "/app/node_modules"
    environment:
      CHOKIDAR_USEPOLLING: "true"

9

Answers


  1. I had same issue once, This issue was in my Dockerfile The workdir was /var/app/ while in my docker-compose.yml I mounted current working directory to /var/app/frontend, I just removed that /frontend and works fine. please check yours. thanks

    Login or Signup to reply.
  2. The Dockerfile you have is great for when you want to package your app into a container, ready for deployment. It’s not so good for development where you want to have the source outside the container and have the running container react to changes in the source.

    What I do is keep the Dockerfile for packaging the app and only build that, when I’m done.

    When developing, I can often do that without a dockerfile at all, just by running a container and mapping my source code into it.

    For instance, here’s a command I use to run a node app

    docker run -u=1000:1000 -v $(pwd):/app -w=/app -d -p 3000:3000 --rm --name=nodedev node bash -c "npm install && npm run dev"
    

    As you can see, it just runs a standard node image. Let me go through the different parts of the command:

    -u 1000:1000 1000 is my UID and GID on the host. By running the container using the same ids, any files created by the container will be owned by me on the host.

    -v $(pwd):/app map the current directory into the /app directory in the container

    -w /app set the working directory in the container to /app

    -d run detached

    -p 3000:3000 map port 3000 in the container to 3000 on the host

    --rm remove the container when it exits

    -name=nodedev give it a name, so I can kill it without looking up the name

    at the end there’s a command for the container bash -c "npm install && npm run dev" which starts by installing any dependencies and then runs the dev script in the package.json file. That script starts up node in a mode, where it hot reloads.

    Login or Signup to reply.
  3. If you are on Windows and use react-scripts 5.x.x or above, CHOKIDAR_USEPOLLING is not working. Make changes your package.json instead in the following way:

        "scripts": {
        ...
        "start": "WATCHPACK_POLLING=true react-scripts start",
        ...
      }
    
    Login or Signup to reply.
  4. Polling wasn’t my issue — watching the docker output I saw it recompiled correctly. My problem was related to networking in the hot loader. I found that the browser is trying to open a websocket back to the node server to ws://localhost:3000/sockjs-node but whatever network settings are like on my computer, this wouldn’t route back to the docker container. I added

    WDS_SOCKET_HOST=127.0.0.1
    

    to the environment variables. After restarting, the browser successfully connects to ws://127.0.0.1:3000/sockjs-node and hot reloading works properly.

    This was tied to using a docker-compose solution similar to the original post. I was able to also make things with with a variation on the docker run approach, but it was much slower to launch.

    Login or Signup to reply.
  5. WSL Workaround for CRA 5.0+

    watch.js

    const fs = require('fs');
    const path = require('path');
    
    if (process.env.NODE_ENV === 'development') {
      const webPackConfigFile = path.resolve('./node_modules/react-scripts/config/webpack.config.js');
      let webPackConfigFileText = fs.readFileSync(webPackConfigFile, 'utf8');
    
      if (!webPackConfigFileText.includes('watchOptions')) {
        if (webPackConfigFileText.includes('performance: false,')) {
          webPackConfigFileText = webPackConfigFileText.replace(
            'performance: false,',
            "performance: false,nttwatchOptions: { aggregateTimeout: 200, poll: 1000, ignored: '**/node_modules', },"
          );
          fs.writeFileSync(webPackConfigFile, webPackConfigFileText, 'utf8');
        } else {
          throw new Error(`Failed to inject watchOptions`);
        }
      }
    }
    

    package.json

    "scripts": {
        "start": "node ./watch && react-scripts start",
    
    Login or Signup to reply.
  6. Make sure you use –legacy-watch tag in package.json file

    {
      "name": "history",
      "version": "1.0.0",
      "description": "",
      "main": "./src/index.js",
      "scripts": {
        "start": "node ./src/index.js",
        "start:dev": "nodemon --legacy-watch ./src/index.js"
      },
    Login or Signup to reply.
  7. I had the same issue, and my mistake was that I was editing on my local machine and was expecting code reload inside the docker container. Since 2 of them are at different locations – it will never work out and I had to restart the docker-compose again and again.

    Later I used the vscode command palette

    "Attach to Running Container…"

    option and the selected required container and cd into my code folder and made changes and live reload (or apply code changes on the refresh page) started working.

    This helped me solve one issue, the next issue is to use the local ssh-key inside the docker container such that I can do my git sync inside the container itself.

    Login or Signup to reply.
  8. Setting the NODE_ENV="development" in the Dockerfile enables the hot reload

    Login or Signup to reply.
  9. Consuming all sayed above I got worked version for Docker.

    So if you are used Docker compose file, just edit to your docker-compose.yml and add some enviroment:

    services:
      frontend: 
        environment:
          - WDS_SOCKET_HOST=127.0.0.1 
          - CHOKIDAR_USEPOLLING=true
          - WATCHPACK_POLLING=true 
        command: npm run start
    

    OR

    into packages.json:

    WDS_SOCKET_HOST=127.0.0.1 CHOKIDAR_USEPOLLING=true WATCHPACK_POLLING=true react-scripts start

    But this will be work only localy for development server. Into remote server this can’t be works.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search