CLI Flask выдает «OSError: [Errno 8] Exec format error» при запуске через docker-compose - PullRequest
24 голосов
/ 21 марта 2019

Я запускаю приложение Flask с Custom Script .Или, в любом случае, пытаюсь.

Я нахожусь на Windows 10, и приложение должно запускаться в контейнере Docker Linux с командой:

docker-compose up api

Docker-compose равен version 1.23.2.В файле docker служба api запускается с помощью команды:

command: python manage.py run --host "0.0.0.0" --with-threads

При попытке запуска я вижу исключение

OSError: [Errno 8] Exec format error: '/api/manage.py'

Сначала я думал, что это будетСтрашные окончания строк Windows, приходите за мной еще раз, но запуск dos2unix на всех моих исходных файлах не решил проблему.

Как мне избежать этой ошибки?


manage.py

    import click
    from flask.cli import FlaskGroup

    from my_app_api import create_app


    def create_my_app(info):
        return create_app()


    @click.group(cls=FlaskGroup, create_app=create_my_app)
    def cli():
        pass


    if __name__ == "__main__":
        cli()

Полный возврат

api_1          | Traceback (most recent call last):
api_1          |   File "manage.py", line 22, in <module>
api_1          |     cli()
api_1          |   File "/usr/local/lib/python3.6/site-packages/click/core.py", line 764, in __call__
api_1          |     return self.main(*args, **kwargs)
api_1          |   File "/usr/local/lib/python3.6/site-packages/flask/cli.py", line 380, in main
api_1          |     return AppGroup.main(self, *args, **kwargs)
api_1          |   File "/usr/local/lib/python3.6/site-packages/click/core.py", line 717, in main
api_1          |     rv = self.invoke(ctx)
api_1          |   File "/usr/local/lib/python3.6/site-packages/click/core.py", line 1137, in invoke
api_1          |     return _process_result(sub_ctx.command.invoke(sub_ctx))
api_1          |   File "/usr/local/lib/python3.6/site-packages/click/core.py", line 956, in invoke
api_1          |     return ctx.invoke(self.callback, **ctx.params)
api_1          |   File "/usr/local/lib/python3.6/site-packages/click/core.py", line 555, in invoke
api_1          |     return callback(*args, **kwargs)
api_1          |   File "/usr/local/lib/python3.6/site-packages/click/decorators.py", line 64, in new_func
api_1          |     return ctx.invoke(f, obj, *args, **kwargs)
api_1          |   File "/usr/local/lib/python3.6/site-packages/click/core.py", line 555, in invoke
api_1          |     return callback(*args, **kwargs)
api_1          |   File "/usr/local/lib/python3.6/site-packages/flask/cli.py", line 438, in run_command
api_1          |     use_debugger=debugger, threaded=with_threads)
api_1          |   File "/usr/local/lib/python3.6/site-packages/werkzeug/serving.py", line 988, in run_simple
api_1          |     run_with_reloader(inner, extra_files, reloader_interval, reloader_type)
api_1          |   File "/usr/local/lib/python3.6/site-packages/werkzeug/_reloader.py", line 332, in run_with_reloader
api_1          |     sys.exit(reloader.restart_with_reloader())
api_1          |   File "/usr/local/lib/python3.6/site-packages/werkzeug/_reloader.py", line 176, in restart_with_reloader
api_1          |     exit_code = subprocess.call(args, env=new_environ, close_fds=False)
api_1          |   File "/usr/local/lib/python3.6/subprocess.py", line 287, in call
api_1          |     with Popen(*popenargs, **kwargs) as p:
api_1          |   File "/usr/local/lib/python3.6/subprocess.py", line 729, in __init__
api_1          |     restore_signals, start_new_session)
api_1          |   File "/usr/local/lib/python3.6/subprocess.py", line 1364, in _execute_child
api_1          |     raise child_exception_type(errno_num, err_msg, err_filename)
api_1          | OSError: [Errno 8] Exec format error: '/api/manage.py'

Ответы [ 4 ]

39 голосов
/ 21 марта 2019

Похоже, у вашего api / manage.py нет шебанга ( [Википедия]: Шебанг (Unix) ), поэтому стандартный (текущий) командный процессор ( shell - обычно bash ) пытается запустить его, что (очевидно) не удается.

Чтобы исправитьпроблема, добавьте shebang (в начале файла, убедившись, что ваш редактор добавляет конец строки в стиле Nix ( \ n , 0x0A , LF )):

  • По умолчанию Python установка:

    #!/usr/bin/env python
    
    • Вариант (указать Python 3 явно):

      #!/usr/bin/env python3
      
  • Пользовательские Python Установка:

    #!/full/path/to/your/custom/python/executable
    

Обратите внимание, что вам также необходимы права доступа exec для файла (chmod +x api/manage.py).

Пример:

[cfati@cfati-5510-0:/cygdrive/e/Work/Dev/StackOverflow/q055271912]> ~/sopr.sh
*** Set shorter prompt to better fit when pasted in StackOverflow (or other) pages ***

[prompt]> ls
code0.py  code1.py
[prompt]>
[prompt]> cat code0.py
print("This is:", __file__)

[prompt]> python3 -c "import os, subprocess;subprocess.Popen(os.path.join(os.getcwd(), \"code0.py\")).communicate()"
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/usr/lib/python3.6/subprocess.py", line 709, in __init__
    restore_signals, start_new_session)
  File "/usr/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: '/cygdrive/e/Work/Dev/StackOverflow/q055271912/code0.py'
[prompt]>
[prompt]> cat code1.py
#!/usr/bin/env python3

print("This is:", __file__)

[prompt]> python3 -c "import os, subprocess;subprocess.Popen(os.path.join(os.getcwd(), \"code1.py\")).communicate()"
This is: /cygdrive/e/Work/Dev/StackOverflow/q055271912/code1.py


Другим способом было бы запустить последователя-переводчикаd по имени файла, но я не знаю, как это сделать из Flask - на самом деле это потребует исправления Werkzeug ( _reloader.py : _get_args_for_reloading ), но это был бы просто неудачный обходной путь ( gainarie ) - см. ниже.

@ EDIT0 :

Глядя на ответ @ AxelGrytt, выясняется, что это известная проблема: [GitHub]: pallets / werkzeug - 0.15.0 вызывает OSError: [Errno 8] Ошибка формата Exec: в Docker для Windows (хм, представлен в тот же день, что и этот вопрос (и через 2 дня после выпуска) :)).

Итак, то, что я сказал выше, правильно, но стоит упомянуть, что есть другой способисправления: удаление разрешения exec для файла:

chmod -x api/manage.py

По мнению Werkzeug авторов, отныне это желаемое поведение (также относится к v 0.15.2 ):

  • Файл с exec permission set, должен также иметь shebang
  • Файл без a shebang , не должен имеет разрешение exec
28 голосов
/ 22 марта 2019

Это новое поведение в Werkzeug 0.15. Понижение до Werkzeug 0.14.1 может работать, но 0.14 больше не поддерживается, поэтому вам будет лучше исправить проблему с вашим файлом, как описано в других ответах.

7 голосов
/ 23 апреля 2019

Если вы отключите режим отладки (не передавайте debug=True или не установите FLASK_DEBUG=0), перегрузчик не будет использоваться, и поэтому эта проблема не возникнет.Компромисс в том, что у вас больше нет перегрузчика.

if __name__ == "__main__":
    connexion_app.run(host="0.0.0.0", port=constants.API_PORT, debug=True)

Желательно исправить это, убедившись, что файлы, помеченные как исполняемые, имеют строку интерпретатора, например #!/usr/bin/env python3 (из https://stackoverflow.com/a/55272071).

2 голосов
/ 19 апреля 2019

Ответ @CristiFati работал для меня с 1 дополнительным шагом:

Я также должен был исправить EOL с \r\n до \n.


Извините, я не понимаюне хватает баллов, чтобы добавить комментарий и открыть новый ответ ...

...