Отладка 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 хоста с каталогом контейнера.

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

Этот вопрос похож на: Автоматическая перезагрузка сервера flask в Docker. Если вы считаете, что это другое, отредактируйте вопрос, поясните, чем он отличается и/или как ответы на этот вопрос не помогают решить вашу проблему.

x3l51 25.08.2024 23:56

Проблема в stackoverflow.com/questions/44342741/… заключалась в том, что они использовали команду COPY, а не том, чтобы сопоставить каталог src хоста с каталогом контейнера. В результате получается статический контейнер, который не связан со средой хоста, т. е. если вы измените код хоста, код в контейнере останется прежним, поэтому я описал присоединение к контейнеру, чтобы убедиться, что это работает.

JSDevGuy 27.08.2024 03:52
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
2
50
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 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.

Спасибо, что посмотрели на это, я согласен, что это странно. Я использовал /usr/local/app, как и в производственной среде, которую я развертываю в этом месте, но тогда мне нужно, чтобы код был только статическим. Может быть, есть системная служба, защищающая контент или что-то подобное?

JSDevGuy 27.08.2024 03:58

Я считаю, что защита системных сервисов менее актуальна. Это потому, что изменение пути на /var/local/app все еще работает. Я думаю, что это больше связано с механизмом обнаружения изменений файлов Flask в отношении ссылочных путей, поскольку каталоги по умолчанию /usr и /usr/local содержат папку src. Использование /usr/app или /usr/local/app приведет к сбою горячей перезагрузки. К сожалению, я не смог найти соответствующих ссылок; У меня есть только результаты экспериментов. Я надеюсь, что они будут полезны.

Yu Wei Liu 27.08.2024 06:19

Другие вопросы по теме