Flask hot reload not working in docker, the log indicates otherwise

Question:

I run the following docker-compose.yml in PyCharm, which runs docker-compose up

version: '3'

services:
  posts:
    environment:
      FLASK_DEBUG: 1
    image: flask-blog-posts
    build:
      context: .
      dockerfile: 'posts/Dockerfile'
    ports:
      - "5001:5001"
  comments:
    environment:
      FLASK_DEBUG: 1
    image: flask-blog-comments
    build:
      context: .
      dockerfile: 'comments/Dockerfile'
    ports:
      - "5002:5002"

which in turn starts posts and comments services and the debugger is expected to detect changes in code and reload whenever this happens. Here’s the log for posts service:

* Debug mode: on
2022-09-22T17:17:44.094571019Z WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
2022-09-22T17:17:44.094599147Z  * Running on all addresses (0.0.0.0)
2022-09-22T17:17:44.094603187Z  * Running on http://127.0.0.1:5001
2022-09-22T17:17:44.094606086Z  * Running on http://172.18.0.3:5001
2022-09-22T17:17:44.094809796Z Press CTRL+C to quit
2022-09-22T17:17:44.096079648Z  * Restarting with stat
2022-09-22T17:17:44.498014077Z  * Debugger is active!
2022-09-22T17:17:44.499326875Z  * Debugger PIN: 643-209-648
2022-09-22T17:18:11.411390459Z 172.18.0.1 - - [22/Sep/2022 17:18:11] "GET / HTTP/1.1" 200 -
2022-09-22T17:18:13.610573254Z 172.18.0.1 - - [22/Sep/2022 17:18:13] "GET /favicon.ico HTTP/1.1" 404 -
2022-09-22T17:19:12.423894271Z 172.18.0.1 - - [22/Sep/2022 17:19:12] "GET / HTTP/1.1" 200 -

it clearly indicates that the debugger is active however, when I make changes in the corresponding app code, nothing happens and changes go undetected. The directory looks like the following:

├── README.md
├── comments
│   ├── Dockerfile
│   ├── __init__.py
│   └── app.py
├── docker-compose.yml
├── posts
│   ├── Dockerfile
│   ├── __init__.py
│   └── app.py
├── requirements.txt
├── static
└── templates

posts/app.py and comments/app.py contain the same code as below:

from flask import Flask

app = Flask(__name__)


@app.route('/')
def hello_world():
    return 'Hello world!'


if __name__ == '__main__':
    app.run()

and here’s both docker files which are pretty much the same as well except for the ports 5001 and 5002 for posts and comments respectively.

FROM python:3.10
COPY . .
RUN pip install -r requirements.txt
WORKDIR comments
CMD [ "flask", "run", "--host=0.0.0.0", "--port=5001"]

I need that whenever I make any changes in the code, it should reflect and reload accordingly. The current behavior: I make changes in any of app.pys, ex: change Hello world! to Hello earth!, if I refresh the page 50 times, I’ll still get Hello world. I tried rebuilding both containers, restarting docker, deleting configuration files, … nothing works.

Asked By: user20060069

||

Answers:

This is because your code is copied to a container & then that container is running the code. The changes you make are outside of container to your system. If you wish to let the changes reflect, you will need to add a volume in the file as below ::

version: '3'

services:
  posts:
    environment:
      FLASK_DEBUG: 1
    volumes:
      - .:/code
    image: flask-blog-posts
    build:
      context: .
      dockerfile: 'posts/Dockerfile'
    ports:
      - "5001:5001"
  comments:
    environment:
      FLASK_DEBUG: 1
    volumes:
      - .:/code
    image: flask-blog-comments
    build:
      context: .
      dockerfile: 'comments/Dockerfile'
    ports:
      - "5002:5002"

In this way, when you make changes to the ./local_path directory, they will reflect in the container.


Update – Adding exact changes for other files as well

posts & comments Dockerfiles –

FROM python:3.10
WORKDIR /code
COPY . .
RUN pip install -r requirements.txt
WORKDIR comments
CMD [ "flask", "run", "--host=0.0.0.0", "--port=5001"]
Answered By: iArc13

If the compose is running different services (app and rq, for instance) you need to set up the volumes on both, or it won’t work.

Answered By: ImanolUr