Werkzeug: 0.15.0 вызывает OSError: [Errno 8] Ошибка формата Exec: в Docker для Windows

Созданный на 21 мар. 2019  ·  19Комментарии  ·  Источник: pallets/werkzeug

Новая версия 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 , и после перестроения она заработает правильно.

Самый полезный комментарий

Сделал тот же учебник и обнаружил ту же проблему. Это исправило это для меня.

Я добавил следующий шебанг в начало своего скрипта app.py

#!/usr/local/bin/python3

Что затем вызвало проблемы с разрешением. Затем я добавил следующее в свой Dockerfile перед CMD

RUN chmod 644 app.py

Все 19 Комментарий

Привет, такая же проблема здесь. Протестировано на

  • Centos 7.4 с питоном 3.6
  • Mac OSX 10.14.3 с питоном 3.7

Это вызвано изменениями в _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.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги