繁体   English   中英

Flask CLI 在通过 docker-compose 运行时抛出 'OSError: [Errno 8] Exec format error'

[英]Flask CLI throws 'OSError: [Errno 8] Exec format error' when run through docker-compose

我正在运行带有自定义脚本的 Flask 应用程序。 或者尝试,无论如何。

我在 Windows 10 上,应用程序应该使用以下命令在 linux Docker 容器中运行:

docker-compose up api

Docker-compose 是version 1.23.2 在 dockerfile 中, api服务通过以下命令运行:

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

当它尝试启动时,我看到了异常

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

我最初认为这将是可怕的 Windows 行尾,再次来找我,但是在我所有的源文件上运行dos2unix并没有解决问题。

我怎样才能避免这个错误?


管理.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'

看起来您的api/manage.py没有shebang[Wikipedia]: Shebang (Unix) ),因此默认(当前)命令处理器( shell - 通常bash )正在尝试运行它,(显然)失败。

为了纠正这个问题,添加一个shebang (在文件的开头,确保你的编辑器添加了Nix样式的行尾( \n0x0ALF )):

  • 默认Python安装:

     #!/usr/bin/env python
    • 变体(明确指定Python 3 ):

       #!/usr/bin/env python3
  • 自定义Python安装:

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

请注意,您还需要对文件 ( chmod +x api/manage.py ) 具有exec权限。

例子:

 [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 ### [064bit prompt]> ls code00.py code01.py [064bit prompt]> [064bit prompt]> cat code00.py print("This is:", __file__) [064bit prompt]> python3 -c "import os, subprocess;subprocess.Popen(os.path.join(os.getcwd(), \"code00.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/code00.py' [064bit prompt]> [064bit prompt]> cat code01.py #!/usr/bin/env python3 print("This is:", __file__) [064bit prompt]> python3 -c "import os, subprocess;subprocess.Popen(os.path.join(os.getcwd(), \"code01.py\")).communicate()" This is: /cygdrive/e/Work/Dev/StackOverflow/q055271912/code01.py

另一种方法是运行解释器,后跟文件名,但我不知道如何从Flask执行它 - 实际上这需要修补Werkzeug_reloader.py : _get_args_for_reloading ),但这只是一个蹩脚的解决方法(增益) - 见下文。



更新#0

查看@AxelGrytt 的回答,原来这是一个已知问题: [GitHub]:pallets/werkzeug - 0.15.0 导致 OSError:[Errno 8] Exec 格式错误:在 Docker for Windows 中(嗯,与此在同一天提交问题(以及发布后 2 天):))。

所以,我上面说的是正确的,但值得一提的是,还有另一种修复方法:删除文件的exec权限:

chmod -x api/manage.py

根据Werkzeug作者的说法,从现在开始,这是期望的行为(也适用于v 0.15.2 ):

  • 具有exec权限集的文件也应该有一个shebang
  • 没有shebang的文件,不应设置exec权限

这是 Werkzeug 0.15 中的新行为。 降级到 Werkzeug 0.14.1 可能有效,但不再支持 0.14,因此您最好按照其他答案中的说明纠正文件问题。

如果禁用调试模式(不传递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 )。

@CristiFati 的答案为我工作了一个额外的步骤:

我还必须将 EOL 从\r\n更正为\n


抱歉,我没有足够的积分来添加评论并且必须打开一个新答案...

Werkzeug==0.15.4 有这个问题。

pip install --user Werkzeug==0.16

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM