Werkzeug: 0.15.0 导致 OSError: [Errno 8] Exec format error: in Docker for Windows

创建于 2019-03-21  ·  19评论  ·  资料来源: pallets/werkzeug

新的 0.15.0 不在 Docker for Windows 中运行。 没有在其他平台上尝试过 Docker。

Flask 的最小示例。

应用程序.py

from flask import Flask

app = Flask(__name__)


@app.route('/')
def hello_world():
    return 'Hello, world!'

if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0')

Dockerfile

FROM python:3-onbuild
COPY . /usr/src/app
CMD ["python", "app.py"]

要求.txt

# Werkzeug==0.14.1
Flask

运行docker build -t flask_test .然后docker run flask_test
容器中的错误:

λ docker run flask_test
 * Serving Flask app "app" (lazy loading)
 * Environment: production
   WARNING: Do not use the development server in a production environment.
   Use a production WSGI server instead.
 * Debug mode: on
 * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
 * Restarting with stat
Traceback (most recent call last):
  File "app.py", line 11, in <module>
    app.run(debug=True, host='0.0.0.0')
  File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 943, in run
    run_simple(host, port, self, **options)
  File "/usr/local/lib/python3.6/site-packages/werkzeug/serving.py", line 988, in run_simple
    run_with_reloader(inner, extra_files, reloader_interval, reloader_type)
  File "/usr/local/lib/python3.6/site-packages/werkzeug/_reloader.py", line 332, in run_with_reloader
    sys.exit(reloader.restart_with_reloader())
  File "/usr/local/lib/python3.6/site-packages/werkzeug/_reloader.py", line 176, in restart_with_reloader
    exit_code = subprocess.call(args, env=new_environ, close_fds=False)
  File "/usr/local/lib/python3.6/subprocess.py", line 267, in call
    with Popen(*popenargs, **kwargs) as p:
  File "/usr/local/lib/python3.6/subprocess.py", line 709, in __init__
    restore_signals, start_new_session)
  File "/usr/local/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: '/usr/src/app/app.py

取消注释requirements.txt中的第一行,它在重建后可以正常运行。

最有用的评论

做了同样的教程,发现同样的问题。 这为我修好了。

我在app.py脚本的顶部添加了以下 shebang

#!/usr/local/bin/python3

然后导致权限问题。 然后我在 CMD 之前将以下内容添加到我的Dockerfile

RUN chmod 644 app.py

所有19条评论

嗨,同样的问题。 经测试

  • Centos 7.4 与 python 3.6
  • Mac OSX 10.14.3 和 python 3.7

这是由 _reloading.py 中_get_args_for_reloading()的变化引起的。

给定上面名为 app.py 的文件中的代码,其中 cwd() 为/home/user/Projects/test/

_get_args_for_reloading()产生以下结果:

使用0.14.1

['/home/user/.virtualenvs/test-ChRUEUMK/bin/python', 'app.py']

0.15.0

['/home/user/Projects/test/app.py']

在路径前添加/home/user/.virtualenvs/test-ChRUEUMK/bin/python确实可以解决问题。

@shinuza检查 app.py 是否可执行,如果是 - 设置 chmod 644 app.py。 或者第二种方法,在 app.py 顶部添加 shebang,例如 #!/usr/bin/env python

@shinuza那里https://github.com/pallets/werkzeug/blob/0.15.x/src/werkzeug/_reloader.py#L90第 90-94 行“'/home/user/.virtualenvs/test-ChRUEUMK/bin /python'" 如果 app.py 可执行,则被删除。
和 OSError: [Errno 8] Exec format error: '/usr/src/app/app.py 发生是因为 app.py 没有 shebang 行 (https://stackoverflow.com/questions/27606653/oserror-errno- 8-执行格式错误)

@kamyanskiy我刚刚在阅读代码时发现了这一点,但错误应该和现在一样神秘。

此外,如果我明确运行python app.py ,那么子进程不应做出任何假设并改变我运行应用程序的方式。 即:使用具有共享文件夹的虚拟机使每个文件默认可执行。

@shinuza我不认为它是一个严重的错误,换句话说,它现在比以前更严格了。 所以我不应该在没有shebang的情况下拥有可执行的app.py,这没有意义。 其次,我不应该像“python app.py”那样使用shebang运行可执行文件。 但我同意,这对你和我来说可能是出乎意料的:) 要解决这个问题,只需将 shebang 添加到你的 app.py 中,我希望这会有所帮助。

如果将脚本标记为可执行,则应在顶部添加相应的解释器注释。 您可以使用pre-commitcheck-executables-have-shebangs钩子之类的工具来强制执行此操作。

如果您不打算让脚本直接可执行,而是需要python script.py ,那么您不应将其标记为可执行。

正如我所说,我同意这里的主要逻辑。 我不同意错误的处理方式以及错误消息难以理解的事实,除非您知道技术细节或阅读代码。 它至少应该记录在变更日志中。

我们无法控制来自 Linux 的错误消息。 更改日志中列出了我们更改了处理可执行文件的方式的事实:

如果 Python 文件被标记为可执行,则重新加载器不会将 Python 可执行文件添加到命令行。 这允许重新加载器在 NixOS 上工作。 #1242

使文件不可执行有效。 对我来说,shebang 线没有。 相反,我得到文件未找到错误。 那是我尝试的第一件事。

使用#!/usr/bin/env python3

λ docker run flask_test
 * Serving Flask app "app" (lazy loading)
 * Environment: production
   WARNING: Do not use the development server in a production environment.
   Use a production WSGI server instead.
 * Debug mode: on
 * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
 * Restarting with stat
: No such file or directory

我还认为进行仅适用于一个 Linux 发行版但破坏其余发行版的更改似乎并不理想。 使文件不可执行似乎是正确的解决方案,但这对我来说仍然感觉很糟糕。

@penner42试试 #!/usr/bin/env python

root<strong i="7">@4541ebd677e0</strong>:/usr/src/app# ls -la /usr/local/bin/python3
lrwxrwxrwx 1 root staff 9 Mar  4 23:40 /usr/local/bin/python3 -> python3.6
root<strong i="8">@4541ebd677e0</strong>:/usr/src/app# ls -la /usr/local/bin/python 
lrwxrwxrwx 1 root staff 7 Mar  4 23:40 /usr/local/bin/python -> python3

可能你在 python3 上没有符号链接

结果相同。 python3 符号链接在那里,只需从 shell 运行/usr/bin/env python3/usr/bin/env python即可。

FWIW,Docker 在构建时确实给出了这个警告。
SECURITY WARNING: You are building a Docker image from Windows against a non-Windows Docker host. All files and directories added to build context will have '-rwxr-xr-x' permissions. It is recommended to double check and reset permissions for sensitive files and directories.

使用flask run命令。

FROM python:3.7-alpine
WORKDIR /app
ENV FLASK_ENV development
ENV FLASK_APP example
EXPOSE 5000
RUN ["pip", "install", "flask"]
CMD ["flask", "run", "-h", "0.0.0.0"]
docker run --rm -p 5000:5000 -v $(pwd):/app flask/example:latest

https://docs.docker.com/compose/gettingstarted/上的教程是否曾经在 Windows 7 上工作?
这是最近的更改导致我在尝试运行示例时看到类似错误的原因:

$ docker-compose up
Creating composetest_web_1   ... done
Creating composetest_redis_1 ... done
Attaching to composetest_web_1, composetest_redis_1
redis_1  | 1:C 27 Mar 2019 17:29:12.746 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
redis_1  | 1:C 27 Mar 2019 17:29:12.746 # Redis version=5.0.4, bits=64, commit=00000000, modified=0, pid=1, just started
redis_1  | 1:C 27 Mar 2019 17:29:12.747 # Warning: no config file specified, using the default config. In order to specify a config file use redis-ser
ver /path/to/redis.conf
redis_1  | 1:M 27 Mar 2019 17:29:12.757 * Running mode=standalone, port=6379.
redis_1  | 1:M 27 Mar 2019 17:29:12.757 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to th
e lower value of 128.
redis_1  | 1:M 27 Mar 2019 17:29:12.758 # Server initialized
redis_1  | 1:M 27 Mar 2019 17:29:12.758 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issu
e add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
web_1    |  * Serving Flask app "app" (lazy loading)
web_1    |  * Environment: production
web_1    |    WARNING: Do not use the development server in a production environment.
web_1    |    Use a production WSGI server instead.
web_1    |  * Debug mode: on
web_1    |  * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
web_1    |  * Restarting with stat
web_1    | Traceback (most recent call last):
web_1    |   File "app.py", line 32, in <module>
web_1    |     app.run(host="0.0.0.0", debug=True)
web_1    |   File "/usr/local/lib/python3.4/site-packages/flask/app.py", line 943, in run
web_1    |     run_simple(host, port, self, **options)
web_1    |   File "/usr/local/lib/python3.4/site-packages/werkzeug/serving.py", line 988, in run_simple
web_1    |     run_with_reloader(inner, extra_files, reloader_interval, reloader_type)
web_1    |   File "/usr/local/lib/python3.4/site-packages/werkzeug/_reloader.py", line 332, in run_with_reloader
web_1    |     sys.exit(reloader.restart_with_reloader())
web_1    |   File "/usr/local/lib/python3.4/site-packages/werkzeug/_reloader.py", line 176, in restart_with_reloader
web_1    |     exit_code = subprocess.call(args, env=new_environ, close_fds=False)
web_1    |   File "/usr/local/lib/python3.4/subprocess.py", line 534, in call
web_1    |     with Popen(*popenargs, **kwargs) as p:
web_1    |   File "/usr/local/lib/python3.4/subprocess.py", line 856, in __init__
web_1    |     restore_signals, start_new_session)
web_1    |   File "/usr/local/lib/python3.4/subprocess.py", line 1464, in _execute_child
web_1    |     raise child_exception_type(errno_num, err_msg)
web_1    | OSError: [Errno 8] Exec format error
composetest_web_1 exited with code 1

做了同样的教程,发现同样的问题。 这为我修好了。

我在app.py脚本的顶部添加了以下 shebang

#!/usr/local/bin/python3

然后导致权限问题。 然后我在 CMD 之前将以下内容添加到我的Dockerfile

RUN chmod 644 app.py

请任何人都可以更新教程(https://docs.docker.com/compose/gettingstarted/)
添加

RUN chmod 644 app.py

在工具 0.15.5 中修复。

此页面是否有帮助?
0 / 5 - 0 等级