我正在使用Custom Script运行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 Line Ends,请再来找我,但是在所有源文件上运行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'
答案 0 :(得分:27)
这是Werkzeug 0.15中的新行为。降级到Werkzeug 0.14.1也许可以,但是不再支持0.14,因此最好按照其他答案中所述纠正文件问题。
答案 1 :(得分:23)
看起来您的 api / manage.py 没有 shebang ([Wikipedia]: Shebang (Unix)),因此默认设置为(当前)命令处理器(一个 shell -通常是 bash )正在尝试运行它,(显然)失败了。
要解决此问题,请添加 shebang (在文件的开头,确保您的编辑器添加了 Nix 样式行的结尾( \ n , 0x0A )):
默认 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 *** [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
另一种方法是运行解释器,后跟文件名,但我不知道如何从 Flask 中执行操作-实际上,这需要修补 Werkzeug ( _reloader.py : _get_args_for_reloading ),但这只是一个me脚的解决方法( gainarie )-见下文。
@ EDIT0 :
看看@AxelGrytt的答案,结果发现这是一个已知问题:[GitHub]: pallets/werkzeug - 0.15.0 causes OSError: [Errno 8] Exec format error: in Docker for Windows(嗯,与这个问题在同一天提交:))。
所以,我上面所说的是正确的,但是值得一提的是,还有另一种修复方法:删除文件的 exec 权限:
chmod -x api/manage.py
根据 Werkzeug 作者,从现在开始,这是理想的行为(也适用于 v 0.15.2 ):
答案 2 :(得分:6)
如果禁用调试模式(请勿通过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)。
答案 3 :(得分:1)
@CristiFati的答案为我工作了另外1个步骤:
我还必须将EOL从\r\n
改成\n
。
对不起,我的积分不足,无法添加评论,必须打开新答案...
答案 4 :(得分:0)
Werkzeug == 0.15.4有这个问题。
pip install --user Werkzeug==0.16