3

I'm building a Django/React app using docker-compose, and I'd like it to reload my apps when a change is made, so far I've tried adding CHOKIDAR_USEPOLLING, adding npm-watch to my package.json, but it doesn't seem to be able to detect changes in the host file.

Ideally I don't want to have to run docker-compose up --build every time I make a change since it's making development tedious.

edit: I should mention that the apps both reload running outside of docker (npm start (cra default) and python manage.py runserver) as expected.

Changes are detected inside the container, but the react app will not rebuild.

I'm using Windows 10 also.

Is there something wrong with my files or something else I should be doing here?

docker-compose.yml

version: "3.9"
   
services:
  db:
    container_name: db
    image: postgres
    volumes:
      - ./data/db:/var/lib/postgresql/data
    environment:
      - POSTGRES_DB=postgres
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres
  backend:
    container_name: backend
    build: ./backend
    command: python manage.py runserver 0.0.0.0:8000
    volumes:
      - .:/core
    ports:
      - "8000:8000"
    depends_on:
      - db
  frontend:
    container_name: frontend
    build: ./frontend
    command: npm start
    volumes:
      - './frontend:/app/'
      - '/frontend/node_modules'
    ports:
      - "3000:3000"
    environment:
      - CHOKIDAR_USEPOLLING=true
    depends_on:
      - backend
    # Enable interactive terminal (crucial for react container to work)
    stdin_open: true 
    tty: true

backend Dockerfile

FROM python:3 
ENV PYTHONUNBUFFERED=1
WORKDIR /code/
COPY requirements.txt /code/
RUN pip install -r requirements.txt
COPY . /code/

frontend Dockerfile

FROM node:16

WORKDIR /app/

COPY package*.json /app/

RUN npm install

COPY . /app/

EXPOSE 3000

CMD ["npm", "start"]
Danielle
  • 117
  • 2
  • 11
  • What is the `npm start` command? Are you reloading your server on code changes? By mounting the directory with your code as a volume it should sync with the container. – Corey Nov 24 '21 at 11:34
  • npm start is the default from create-react-app (react-scripts start) – Danielle Nov 24 '21 at 11:38
  • I don't know how to get it to reload, that's a big part of my problem. I've tried searching but no luck – Danielle Nov 24 '21 at 11:39
  • I should mention that the apps both reload running outside of docker (npm start (cra default) and python manage.py runserver) as expected, just not inside containers – Danielle Nov 24 '21 at 11:41
  • Either of these any use? https://stackoverflow.com/questions/46223173/reloading-code-in-a-dockerized-node-js-app-with-docker-compose or https://www.freecodecamp.org/news/how-to-enable-live-reload-on-docker-based-applications/ – JohnXF Nov 24 '21 at 11:51
  • do you want to reload the container when you change the code inside the container or outside(host)???. – S.Sachith Nov 24 '21 at 12:54
  • @JohnXF no neither of those helped – Danielle Nov 24 '21 at 13:53
  • I want to reload from host changes, it doen't seem good practice to edit the container code @S.Sachith – Danielle Nov 24 '21 at 13:54
  • you can use nodemon --watch with exec to run a command when something change I think with react but I don't know if nodemon working with django @Danielle – S.Sachith Nov 25 '21 at 03:48

1 Answers1

2

Instead of copying you should mount volumes directly to the folder where you run the code on your docker image. In that way your code changes will be reflected in your app.

Example in docker-compose.yml:

volumes:
      - "local_source_destination:/server_source_destination"

In your frontend docker-compose-yml you have:

    volumes:
  - '.:/frontend/app'

but in your Dockerfile your have

COPY . /app/

So it seems like your are mixing up where to mount your volume. Make sure '.' is where your root of your code folder is or change it accordingly.

Try something like:

 volumes:
  - '.:/app'

As that seems to be the location your server wants your code to be.

If your code is correctly mounted to the right destination it might be that you are not running your watch script from inside the docker container. Try running:

docker exec -itw source_destination_in_container your_container_name command_to_run_watch
sitick
  • 86
  • 8
  • I've actually tried changing the volumes to that, and it wont even run like that without the COPY lines – Danielle Nov 24 '21 at 13:58
  • What is it that won't run? docker or the application? – sitick Nov 24 '21 at 14:01
  • I have changed that, but it still doesn't fix the issue of me having to rebuild on every change – Danielle Nov 24 '21 at 14:08
  • Try changing something in your code and then see if that change is reflected in your container. If it is changed on your docker container I would suspect that you are not running what should listen to changes on your docker container but on your local machine. – sitick Nov 24 '21 at 14:11
  • That is part of the problem, docker-compose is running the same start commands I run outside of the container, the ones outside of a container do detect changes, but I can't get those to transfer to a container whilst docker is running – Danielle Nov 24 '21 at 16:07
  • If you manage to mount your code onto the container with a volume and make sure it is mounted in the right place it should be reflecting your changes onto the docker image. If you use the COPY command in a docker image it will just copy the code over at build time and not reflect your changes. – sitick Nov 25 '21 at 08:02
  • It does reflect the changes if I look inside the code on the container, but it doesn't reflect that in the browser. I'm using the base create-react-app and changing the text but it doesn't change unless I rebuild the image. I don't really understand how to get around using COPY commands since the image will not run without them – Danielle Nov 25 '21 at 16:09
  • So you want hot reloading? Or just a watch to build on changes? Here you have a good explanation of using volumes instead of copy: https://olshansky.medium.com/hot-reloading-with-local-docker-development-1ec5dbaa4a65 – sitick Nov 26 '21 at 09:06
  • 1
    Yes, hot reload is what I want. I tried making the changes in the volume but it doesn't seem to make a difference. The code change is reflected in the container but not in the browser/build – Danielle Nov 26 '21 at 12:18
  • https://stackoverflow.com/questions/44643045/running-development-server-with-create-react-app-inside-of-a-docker-container this is somewhat similar to your problem. – sitick Nov 26 '21 at 14:53