当通过docker-compose运行时,Flask CLI抛出“ OSError:[Errno 8] Exec格式错误” [英] Flask CLI throws 'OSError: [Errno 8] Exec format error' when run through docker-compose

查看:77
本文介绍了当通过docker-compose运行时,Flask CLI抛出“ OSError:[Errno 8] Exec格式错误”的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用自定义脚本运行Flask应用程序 。

I'm running a Flask application with a Custom Script. Or trying to, anyway.

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

I'm on Windows 10 and the application ought to run in a linux Docker container with the command:

docker-compose up api

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

Docker-compose is version 1.23.2. In the dockerfile, the api service runs via the command:

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

尝试启动,我看到异常

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

我最初以为这将是可怕的Windows Line Ends,再次来找我,但是运行我所有源文件上的 dos2unix 都不能解决问题。

I initially thought this would be the Dreaded Windows Line Endings, come for me once more, but running dos2unix on all my source files has not resolved the problem.

如何避免此错误?

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'


推荐答案

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

Looks like your api/manage.py doesn't have a shebang ([Wikipedia]: Shebang (Unix)), so the default (current) command processor (a shell - typically bash) is attempting to run it, which (obviously) fails.

要更正此问题,请添加 shebang (在文件的开头,请确保您的编辑器添加 Nix 样式行结尾( \n 0x0A LF )):

To correct the problem, add a shebang (at the beginning of the file, making sure that your editor adds the Nix style line ending (\n, 0x0A, LF)):


  • 默认 Python 安装:

  #!/usr/bin/env python



  • Variant(请指定 Python 3 显式地):

      #!/usr/bin/env python3
    



  • 自定义 Python 安装:

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



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

    Note that you also need exec permissions on the file (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
    code00.py  code01.py
    [prompt]>
    [prompt]> cat code00.py
    print("This is:", __file__)
    
    [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'
    [prompt]>
    [prompt]> cat code01.py
    #!/usr/bin/env python3
    
    print("This is:", __file__)
    
    [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 ),但这只是一个me脚的解决方法( gainarie ) -见下文。

    Another way would be to run the interpreter followed by the file name, but I don't know how to do it from Flask - actually that would require patching Werkzeug (_reloader.py: _get_args_for_reloading), but that would be just a lame workaround (gainarie) - see below.

    查看@AxelGrytt的答案,结果发现这是一个已知问题: [GitHub]:pallets / werkzeug -0.15.0导致OSError:[Errno 8] Exec格式错误:在适用于Windows的Docker中(嗯,与该问题在同一天(以及发行后2天)提交:))。

    Looking at @AxelGrytt's answer, it turns out it's a known issue: [GitHub]: pallets/werkzeug - 0.15.0 causes OSError: [Errno 8] Exec format error: in Docker for Windows (hmm, submitted in the same day as this question (and 2 days after the release) :) ).

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

    So, what I have stated above is correct, but it is worth mentioning that there is another way of fixing it: removing the exec permission for the file:

    chmod -x api/manage.py
    

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

    According to Werkzeug authors, from now on, this is desired behavior (also applies to v0.15.2):


    • 带有 exec的文件 em>权限集,应该也有一个 shebang

    • 一个文件没有一个 shebang 不应该设置 exec 权限

    • A file with exec permission set, should also have a shebang
    • A file without a shebang, shouldn't have the exec permission set

    这篇关于当通过docker-compose运行时,Flask CLI抛出“ OSError:[Errno 8] Exec格式错误”的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆