Я пытаюсь запустить сервер 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 хоста с каталогом контейнера.
Любые предложения по шагу, который мне здесь не хватает, приветствуются!
Проблема в stackoverflow.com/questions/44342741/… заключалась в том, что они использовали команду COPY, а не том, чтобы сопоставить каталог src хоста с каталогом контейнера. В результате получается статический контейнер, который не связан со средой хоста, т. е. если вы измените код хоста, код в контейнере останется прежним, поэтому я описал присоединение к контейнеру, чтобы убедиться, что это работает.
На основе вашего примера я изменил смонтированный путь с /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, как и в производственной среде, которую я развертываю в этом месте, но тогда мне нужно, чтобы код был только статическим. Может быть, есть системная служба, защищающая контент или что-то подобное?
Я считаю, что защита системных сервисов менее актуальна. Это потому, что изменение пути на /var/local/app
все еще работает. Я думаю, что это больше связано с механизмом обнаружения изменений файлов Flask в отношении ссылочных путей, поскольку каталоги по умолчанию /usr
и /usr/local
содержат папку src
. Использование /usr/app
или /usr/local/app
приведет к сбою горячей перезагрузки. К сожалению, я не смог найти соответствующих ссылок; У меня есть только результаты экспериментов. Я надеюсь, что они будут полезны.
Этот вопрос похож на: Автоматическая перезагрузка сервера flask в Docker. Если вы считаете, что это другое, отредактируйте вопрос, поясните, чем он отличается и/или как ответы на этот вопрос не помогают решить вашу проблему.