Новая версия 0.15.0 не работает в Docker для Windows. Не пробовал Docker на других платформах.
Минимальный пример с Flask.
app.py
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello, world!'
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0')
Докерфайл
FROM python:3-onbuild
COPY . /usr/src/app
CMD ["python", "app.py"]
требования.txt
# Werkzeug==0.14.1
Flask
Запустите docker build -t flask_test .
а затем docker run flask_test
.
Ошибка в контейнере:
λ docker run flask_test
* Serving Flask app "app" (lazy loading)
* Environment: production
WARNING: Do not use the development server in a production environment.
Use a production WSGI server instead.
* Debug mode: on
* Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
* Restarting with stat
Traceback (most recent call last):
File "app.py", line 11, in <module>
app.run(debug=True, host='0.0.0.0')
File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 943, in run
run_simple(host, port, self, **options)
File "/usr/local/lib/python3.6/site-packages/werkzeug/serving.py", line 988, in run_simple
run_with_reloader(inner, extra_files, reloader_interval, reloader_type)
File "/usr/local/lib/python3.6/site-packages/werkzeug/_reloader.py", line 332, in run_with_reloader
sys.exit(reloader.restart_with_reloader())
File "/usr/local/lib/python3.6/site-packages/werkzeug/_reloader.py", line 176, in restart_with_reloader
exit_code = subprocess.call(args, env=new_environ, close_fds=False)
File "/usr/local/lib/python3.6/subprocess.py", line 267, in call
with Popen(*popenargs, **kwargs) as p:
File "/usr/local/lib/python3.6/subprocess.py", line 709, in __init__
restore_signals, start_new_session)
File "/usr/local/lib/python3.6/subprocess.py", line 1344, in _execute_child
raise child_exception_type(errno_num, err_msg, err_filename)
OSError: [Errno 8] Exec format error: '/usr/src/app/app.py
Раскомментируйте первую строку в requirements.txt
, и после перестроения она заработает правильно.
Привет, такая же проблема здесь. Протестировано на
Это вызвано изменениями в _get_args_for_reloading()
в _reloading.py.
Учитывая приведенный выше код в файле с именем app.py, cwd() равно /home/user/Projects/test/
_get_args_for_reloading()
дает следующее:
С 0.14.1
:
['/home/user/.virtualenvs/test-ChRUEUMK/bin/python', 'app.py']
С 0.15.0
['/home/user/Projects/test/app.py']
Добавление /home/user/.virtualenvs/test-ChRUEUMK/bin/python
к пути действительно решает проблему.
@shinuza проверьте, является ли app.py исполняемым, если да - установите chmod 644 app.py. Или второй способ, добавьте shebang поверх app.py, например #!/usr/bin/env python
@shinuza там https://github.com/pallets/werkzeug/blob/0.15.x/src/werkzeug/_reloader.py#L90 строки 90-94 "'/home/user/.virtualenvs/test-ChRUEUMK/bin /python'" был удален, если исполняемый файл app.py.
и OSError: [Errno 8] Ошибка формата Exec: '/usr/src/app/app.py произошло, потому что app.py не имеет строки shebang (https://stackoverflow.com/questions/27606653/oserror-errno- 8-exec-ошибка формата)
@kamyanskiy Я только что понял это, прочитав код, но ошибка должна быть такой же загадочной, как и сейчас.
Кроме того, если я явно запускаю python app.py
, то подпроцесс не должен делать никаких предположений и изменять способ запуска приложения. то есть: работа с виртуальной машиной с общей папкой делает все файлы исполняемыми по умолчанию.
@shinuza Я не думаю, что это критическая ошибка, другими словами, теперь она немного строже, чем раньше. Так что у меня не должно быть исполняемого файла app.py без shebang, это не имеет смысла. И во-вторых, я не должен запускать исполняемый файл с помощью shebang, такого как «python app.py». Но я согласен, возможно это было неожиданно для вас, как и для меня :) В качестве обходного пути просто добавьте shebang в ваш app.py, надеюсь, это поможет.
Если вы помечаете скрипт как исполняемый, вы должны добавить соответствующий комментарий интерпретатора вверху. Вы можете использовать такой инструмент, как хук pre-commit check-executables-have-shebangs
, чтобы обеспечить это.
Если вы не хотите, чтобы скрипт был непосредственно исполняемым, и вместо этого хотите потребовать python script.py
, то вам не следует помечать его как исполняемый.
Как я уже сказал, я согласен с основной логикой здесь. Я не согласен с тем, как обрабатываются ошибки, а также с тем фактом, что сообщение об ошибке непонятно, если вы не знаете технических деталей или не читаете код. По крайней мере, это должно быть задокументировано в журнале изменений.
У нас нет контроля над сообщением об ошибке, которое исходит от Linux. Тот факт, что мы изменили способ обработки исполняемых файлов, указан в журнале изменений:
Перезагрузчик не будет добавлять исполняемый файл Python в командную строку, если файл Python помечен как исполняемый. Это позволяет перезагрузчику работать на NixOS. №1242
Сделать файл не исполняемым работает. Линия shebang не для меня. Вместо этого я получаю сообщение о том, что файл не найден. Это было первое, что я попробовал.
С #!/usr/bin/env python3
:
λ docker run flask_test
* Serving Flask app "app" (lazy loading)
* Environment: production
WARNING: Do not use the development server in a production environment.
Use a production WSGI server instead.
* Debug mode: on
* Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
* Restarting with stat
: No such file or directory
Я также думаю, что изменение, которое работает только в одном дистрибутиве Linux, но ломает остальные, не кажется идеальным. Сделать файлы неисполняемыми кажется правильным решением, но мне это все еще кажется сломанным.
@penner42 попробуйте #!/usr/bin/env python
root<strong i="7">@4541ebd677e0</strong>:/usr/src/app# ls -la /usr/local/bin/python3
lrwxrwxrwx 1 root staff 9 Mar 4 23:40 /usr/local/bin/python3 -> python3.6
root<strong i="8">@4541ebd677e0</strong>:/usr/src/app# ls -la /usr/local/bin/python
lrwxrwxrwx 1 root staff 7 Mar 4 23:40 /usr/local/bin/python -> python3
вероятно, у вас нет символической ссылки на python3
Тот же результат. Символическая ссылка python3 есть, и работает просто запуск /usr/bin/env python3
или /usr/bin/env python
из оболочки.
FWIW, Docker выдает это предупреждение при сборке.
SECURITY WARNING: You are building a Docker image from Windows against a non-Windows Docker host. All files and directories added to build context will have '-rwxr-xr-x' permissions. It is recommended to double check and reset permissions for sensitive files and directories.
Используйте команду flask run
.
FROM python:3.7-alpine
WORKDIR /app
ENV FLASK_ENV development
ENV FLASK_APP example
EXPOSE 5000
RUN ["pip", "install", "flask"]
CMD ["flask", "run", "-h", "0.0.0.0"]
docker run --rm -p 5000:5000 -v $(pwd):/app flask/example:latest
Работал ли учебник на https://docs.docker.com/compose/gettingstarted/ в Windows 7?
Является ли это недавнее изменение причиной того, что я вижу аналогичную ошибку при попытке запустить пример:
$ docker-compose up
Creating composetest_web_1 ... done
Creating composetest_redis_1 ... done
Attaching to composetest_web_1, composetest_redis_1
redis_1 | 1:C 27 Mar 2019 17:29:12.746 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
redis_1 | 1:C 27 Mar 2019 17:29:12.746 # Redis version=5.0.4, bits=64, commit=00000000, modified=0, pid=1, just started
redis_1 | 1:C 27 Mar 2019 17:29:12.747 # Warning: no config file specified, using the default config. In order to specify a config file use redis-ser
ver /path/to/redis.conf
redis_1 | 1:M 27 Mar 2019 17:29:12.757 * Running mode=standalone, port=6379.
redis_1 | 1:M 27 Mar 2019 17:29:12.757 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to th
e lower value of 128.
redis_1 | 1:M 27 Mar 2019 17:29:12.758 # Server initialized
redis_1 | 1:M 27 Mar 2019 17:29:12.758 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issu
e add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
web_1 | * Serving Flask app "app" (lazy loading)
web_1 | * Environment: production
web_1 | WARNING: Do not use the development server in a production environment.
web_1 | Use a production WSGI server instead.
web_1 | * Debug mode: on
web_1 | * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
web_1 | * Restarting with stat
web_1 | Traceback (most recent call last):
web_1 | File "app.py", line 32, in <module>
web_1 | app.run(host="0.0.0.0", debug=True)
web_1 | File "/usr/local/lib/python3.4/site-packages/flask/app.py", line 943, in run
web_1 | run_simple(host, port, self, **options)
web_1 | File "/usr/local/lib/python3.4/site-packages/werkzeug/serving.py", line 988, in run_simple
web_1 | run_with_reloader(inner, extra_files, reloader_interval, reloader_type)
web_1 | File "/usr/local/lib/python3.4/site-packages/werkzeug/_reloader.py", line 332, in run_with_reloader
web_1 | sys.exit(reloader.restart_with_reloader())
web_1 | File "/usr/local/lib/python3.4/site-packages/werkzeug/_reloader.py", line 176, in restart_with_reloader
web_1 | exit_code = subprocess.call(args, env=new_environ, close_fds=False)
web_1 | File "/usr/local/lib/python3.4/subprocess.py", line 534, in call
web_1 | with Popen(*popenargs, **kwargs) as p:
web_1 | File "/usr/local/lib/python3.4/subprocess.py", line 856, in __init__
web_1 | restore_signals, start_new_session)
web_1 | File "/usr/local/lib/python3.4/subprocess.py", line 1464, in _execute_child
web_1 | raise child_exception_type(errno_num, err_msg)
web_1 | OSError: [Errno 8] Exec format error
composetest_web_1 exited with code 1
Сделал тот же учебник и обнаружил ту же проблему. Это исправило это для меня.
Я добавил следующий шебанг в начало своего скрипта app.py
#!/usr/local/bin/python3
Что затем вызвало проблемы с разрешением. Затем я добавил следующее в свой Dockerfile
перед CMD
RUN chmod 644 app.py
Пожалуйста, любой может обновить учебник (https://docs.docker.com/compose/gettingstarted/)
добавить
RUN chmod 644 app.py
Изменения в руководстве по Docker Compose, предложенные в https://github.com/docker/docker.github.io/pull/8609.
Исправлено в инструменте 0.15.5.
Самый полезный комментарий
Сделал тот же учебник и обнаружил ту же проблему. Это исправило это для меня.
Я добавил следующий шебанг в начало своего скрипта
app.py
#!/usr/local/bin/python3
Что затем вызвало проблемы с разрешением. Затем я добавил следующее в свой
Dockerfile
перед CMDRUN chmod 644 app.py