![](/img/trans.png)
[英]Flask CLI throws 'OSError: [Errno 8] Exec format error' when run through docker-compose
[英]Flask CLI throws “[Errno 2] No such file” when deploying with docker
我正在关注testdriven.io上的微服务课程。 在本课程中,我需要使用Docker部署Flask应用程序。 要运行应用程序,我使用Flask-cli,它在启动时出现错误:
No such file or directory: '/usr/src/app/manage.py': '/usr/src/app/manage.py'
要部署容器,我使用Docker-compose。 我在Windows 10机器上运行该命令,并使用标准的Python图像( python:3.7.2-alpine
)。 我已经尝试更改文件的权限,但这没有帮助。
这就是我的撰写文件的样子:
version: '3.7'
services:
users:
build:
context: ./services/users
dockerfile: Dockerfile-dev
volumes:
- './services/users:/usr/src/app'
ports:
- 6001:6000
environment:
- FLASK_APP=project/__init__.py
- FLASK_ENV=development
- COMPOSE_CONVERT_WINDOWS_PATHS=1
我的码头文件:
# base image
FROM python:3.7.2-alpine
# set working directory
WORKDIR /usr/src/app
# add and install requirements
COPY ./requirements.txt /usr/src/app/requirements.txt
RUN pip install -r requirements.txt
# add app
COPY . /usr/src/app
# i tried to give it the right rights.. but it didn't help
RUN chmod +x /usr/src/app/manage.py
# run server
CMD python manage.py run -h 0.0.0.0
我的manage.py
文件将启动应用程序:
#!/usr/bin/python3
# services/users/manage.py
from flask.cli import FlaskGroup
from project import app
cli = FlaskGroup(app)
if __name__ == '__main__':
cli()
所以我希望这会启动应用程序并使其在端口6001上可用,但它会给我以下错误:
Successfully tagged testdriven-app_users:latest
Recreating testdriven-app_users_1 ... done
Attaching to testdriven-app_users_1
users_1 | * Serving Flask app "project/__init__.py" (lazy loading)
users_1 | * Environment: development
users_1 | * Debug mode: on
users_1 | * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
users_1 | * Restarting with stat
users_1 | Traceback (most recent call last):
users_1 | File "manage.py", line 11, in <module>
users_1 | cli()
users_1 | File "/usr/local/lib/python3.7/site-packages/click/core.py", line 764, in __call__
users_1 | return self.main(*args, **kwargs)
users_1 | File "/usr/local/lib/python3.7/site-packages/flask/cli.py", line 557, in main
users_1 | return super(FlaskGroup, self).main(*args, **kwargs)
users_1 | File "/usr/local/lib/python3.7/site-packages/click/core.py", line 717, in main
users_1 | rv = self.invoke(ctx)
users_1 | File "/usr/local/lib/python3.7/site-packages/click/core.py", line 1137, in invoke
users_1 | return _process_result(sub_ctx.command.invoke(sub_ctx))
users_1 | File "/usr/local/lib/python3.7/site-packages/click/core.py", line 956, in invoke
users_1 | return ctx.invoke(self.callback, **ctx.params)
users_1 | File "/usr/local/lib/python3.7/site-packages/click/core.py", line 555, in invoke
users_1 | return callback(*args, **kwargs)
users_1 | File "/usr/local/lib/python3.7/site-packages/click/decorators.py", line 64, in new_func
users_1 | return ctx.invoke(f, obj, *args, **kwargs)
users_1 | File "/usr/local/lib/python3.7/site-packages/click/core.py", line 555, in invoke
users_1 | return callback(*args, **kwargs)
users_1 | File "/usr/local/lib/python3.7/site-packages/flask/cli.py", line 771, in run_command
users_1 | threaded=with_threads, ssl_context=cert)
users_1 | File "/usr/local/lib/python3.7/site-packages/werkzeug/serving.py", line 988, in run_simple
users_1 | run_with_reloader(inner, extra_files, reloader_interval, reloader_type)
users_1 | File "/usr/local/lib/python3.7/site-packages/werkzeug/_reloader.py", line 332, in run_with_reloader
users_1 | sys.exit(reloader.restart_with_reloader())
users_1 | File "/usr/local/lib/python3.7/site-packages/werkzeug/_reloader.py", line 176, in restart_with_reloader
users_1 | exit_code = subprocess.call(args, env=new_environ, close_fds=False)
users_1 | File "/usr/local/lib/python3.7/subprocess.py", line 323, in call
users_1 | with Popen(*popenargs, **kwargs) as p:
users_1 | File "/usr/local/lib/python3.7/subprocess.py", line 775, in __init__
users_1 | restore_signals, start_new_session)
users_1 | File "/usr/local/lib/python3.7/subprocess.py", line 1522, in _execute_child
users_1 | raise child_exception_type(errno_num, err_msg, err_filename)
users_1 | FileNotFoundError: [Errno 2] No such file or directory: '/usr/src/app/manage.py': '/usr/src/app/manage.py'
testdriven-app_users_1 exited with code 1
添加werkzeug == 0.14.1到requirement.txt可以修复Windows上出现的相同错误。 它看起来像一个werkzeug bug。
执行脚本时,内核会查找shebang中指定的解释器( #!
)。 提取解释器的位置,然后启动解释器(例如python3
),执行脚本本身。 如果未找到解释器二进制文件,则执行失败并显示No such file or directory
( ENOENT
)错误(根据man 2 execve
):
ERRORS
<...>
ENOENT The file filename or a script or ELF interpreter does not exist,
or a shared library needed for the file or interpreter cannot be found.
你在shebang中指定了#!/usr/bin/python3
,但在你使用的基本图像中( python:3.7.2-alpine
) python3
二进制文件位于不同的位置:
$ docker run -it python:3.7.2-alpine sh
/ # which python3
/usr/local/bin/python3
因此,即使您的应用程序在您的主机本地工作(如果它是Windows,它甚至可能不关心shebang),它会在您将其移动到Docker容器时停止工作。
为了避免这种情况,脚本中的shebang通常不是指代解释器本身( #!/usr/bin/python3
),而是指向/usr/bin/env
binary,它找到并执行解释器:
#!/usr/bin/env python3
当您通过env
运行python3
,后者通过PATH
执行搜索,因此它允许您的shebang不依赖于python3
二进制文件的特定位置。
最后,您的脚本的正确版本如下:
#!/usr/bin/env python3
# services/users/manage.py
from flask.cli import FlaskGroup
from project import app
cli = FlaskGroup(app)
if __name__ == '__main__':
cli()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.