Отладка Flask не выполняет горячую перезагрузку в контейнере докеров

Я пытаюсь запустить сервер Flask в контейнере докеров с включенной отладкой, чтобы иметь возможность горячей перезагрузки во время разработки и опробовать изменения. К сожалению, горячая перезагрузка не обнаруживает изменений, хотя я убедился, что файл изменился изнутри контейнера. Моя установка выглядит следующим образом:

Структура каталогов хоста

|
|- Src
|   |- app.py
|
|- docker-compose.yaml
|- Dockerfile
|- requirements.txt

Требования.txt

flask

Докерфайл

FROM python:3.11-slim

ENV DEBUG_COLOR=true

ENV PYTHONPATH=.

RUN mkdir /usr/local/app

WORKDIR /usr/local/app

COPY requirements.txt /usr/local/app

RUN pip install -r requirements.txt

CMD ["python", "app.py"]

docker-compose.yaml

services:

    test:
        build:
            dockerfile: ./Dockerfile
            context: .
        image: test:latest
        environment:
            - FLASK_DEBUG=1
        ports: ['3000:3000']
        volumes: [
            './src:/usr/local/app'
            ]
        command:
             python app.py

app.py

from flask import Flask

app = Flask(__name__)


@app.route('/')
def index():
    print('GET /, was called.')
    return 'Hello world.'

if __name__ == "__main__":
    app.run(host = '0.0.0.0', port = '3000')

Я могу запустить это из командной строки, используя docker compose up, и все будет построено и запустится так, как ожидалось, в результате чего будет получен результат:

Attaching to test-1
test-1  |  * Serving Flask app 'app'
test-1  |  * Debug mode: on
test-1  | WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
test-1  |  * Running on all addresses (0.0.0.0)
test-1  |  * Running on http://127.0.0.1:3000
test-1  |  * Running on http://172.18.0.2:3000
test-1  | Press CTRL+C to quit
test-1  |  * Restarting with stat
test-1  |  * Debugger is active!
test-1  |  * Debugger PIN: 582-087-710

Из этого я вижу, что отладчик работает и его следует перезапустить с помощью stat. Затем я могу посетить обслуживаемую страницу по адресу http://127.0.0.1:3000, и она соответствует ожидаемому Hello world!. Я также могу подключиться к работающему контейнеру и проверить содержимое app.py с помощью cat app.py.

Если я затем запущу редактор на хосте и изменю содержимое app.py, например, изменю возвращаемое сообщение на:

    return 'Hello test world.'

Я ожидаю, что отладчик обнаружит изменение и перезагрузит компьютер, однако он этого не делает. Я могу просмотреть содержимое app.py в контейнере и увидеть, что код изменился, но при посещении URL-адреса я все равно получаю обслуживание Hello world!.

Примечание. Это отличается от проблемы в Автоматическая перезагрузка сервера flask в Docker, где код был скопирован в контейнер и volumes не использовался для сопоставления src хоста с каталогом контейнера.

Любые предложения по шагу, который мне здесь не хватает, приветствуются!

🤔 А знаете ли вы, что...
Python позволяет создавать сценарии для автоматизации задач и обработки данных.


50
1

Ответ:

Решено

На основе вашего примера я изменил смонтированный путь с /usr/local/app на /project и установил debug=True. После этого Flask смог обнаружить изменения и снова выполнить горячую перезагрузку.

app.py

from flask import Flask

app = Flask(__name__)


@app.route('/')
def index():
    print('GET /, was called.')
    return 'Hello world.'

if __name__ == "__main__":
    app.run(host = '0.0.0.0', port = '3000', debug=True)

Докерфайл

FROM python:3.11-slim

ENV DEBUG_COLOR=true

ENV PYTHONPATH=.

#RUN mkdir /usr/local/app

WORKDIR /project

COPY requirements.txt /project

RUN pip install -r requirements.txt

# Declare it on either the `docker-compose.yml` or `Dockerfile`, don't need both.
# CMD ["python", "app.py"]

docker-compose.yml

services:
    test:
        build:
            dockerfile: ./Dockerfile
            context: .
        image: test:latest
        # Because it's not using command like `flask run` to launch the project, so it's not necessary either.
        #environment:
        #    - FLASK_DEBUG=1
        ports: ['3000:3000']
        volumes: [
            './src:/project'
            ]
        command:
             python app.py

После внесения изменений перестройте и запустите проект.

$ docker compose up --build

Это довольно странно. Несмотря на установку debug=True или использование docker compose --watch, горячая перезагрузка по-прежнему не работает, если я не изменю путь подключения с /usr/local/app на /project (что может быть связано с системным путем или путями обнаружения сторожевого таймера Flask).

Каталог /usr/local часто используется для установок на уровне системы, и события файловой системы могут не распространяться должным образом при монтировании томов в него в контейнере Docker.