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

Criado em 21 mar. 2019  ·  19Comentários  ·  Fonte: pallets/werkzeug

O novo 0.15.0 não é executado no Docker para Windows. Não tentei o Docker em outras plataformas.

Exemplo mínimo com Flask.

app.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"]

requisitos.txt

# Werkzeug==0.14.1
Flask

Execute docker build -t flask_test . e depois docker run flask_test .
Erro no contêiner:

λ 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

Descomente a primeira linha em requirements.txt e ela será executada corretamente após a reconstrução.

Comentários muito úteis

Fiz o mesmo tutorial e encontrei o mesmo problema. Isso resolveu para mim.

Eu adicionei o seguinte shebang ao topo do meu script app.py

#!/usr/local/bin/python3

O que causou problemas de permissão. Em seguida, adicionei o seguinte ao meu Dockerfile antes do CMD

RUN chmod 644 app.py

Todos 19 comentários

Olá mesmo problema aqui. Testado em

  • Centos 7.4 com python 3.6
  • Mac OSX 10.14.3 com python 3.7

Isso é causado pelas alterações em _get_args_for_reloading() em _reloading.py.

Dado o código acima em um arquivo chamado app.py, com cwd() sendo /home/user/Projects/test/

_get_args_for_reloading() produz o seguinte:

Com 0.14.1 :

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

Com 0.15.0

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

Anexar /home/user/.virtualenvs/test-ChRUEUMK/bin/python ao caminho corrige o problema.

@shinuza verifique se app.py é executável, se sim - defina chmod 644 app.py. Ou segunda maneira, adicione shebang no topo do app.py como #!/usr/bin/env python

@shinuzahttps://github.com/pallets/werkzeug/blob/0.15.x/src/werkzeug/_reloader.py#L90 linhas 90-94 o "'/home/user/.virtualenvs/test-ChRUEUMK/bin /python'" foi removido se app.py executável.
e OSError: [Errno 8] Exec format error: '/usr/src/app/app.py aconteceu porque app.py não tem linha shebang (https://stackoverflow.com/questions/27606653/oserror-errno- 8-exec-formato-erro)

@kamyanskiy Acabei de descobrir isso lendo o código, mas o erro deve ser tão enigmático quanto agora.

Além disso, se eu executar explicitamente python app.py , o subprocesso não deverá fazer nenhuma suposição e alterar a maneira como executo o aplicativo. ou seja: trabalhar com uma máquina virtual com pasta compartilhada torna todos os arquivos executáveis ​​por padrão.

@shinuza Eu não acho que seja um bug crítico, em outras palavras, é um pouco mais rigoroso agora do que antes. Então eu não deveria ter app.py executável sem shebang, não faz sentido. E segundo, eu não deveria executar o executável com shebang como "python app.py". Mas eu concordo, provavelmente isso foi inesperado para você e para mim :) Para contornar basta adicionar shebang ao seu app.py, espero que isso ajude.

Se você marcar um script como executável, deverá adicionar um comentário de intérprete correspondente no início. Você pode usar uma ferramenta como o gancho check-executables-have-shebangs do pre-commit para impor isso.

Se você não pretende que um script seja executável diretamente e deseja exigir python script.py , você não deve marcá-lo como executável.

Como eu disse, concordo com a lógica principal aqui. Discordo da forma como o erro é tratado, bem como do fato de que a mensagem de erro é ininteligível, a menos que você conheça os detalhes técnicos ou leia o código. Deve pelo menos ser documentado no changelog.

Não temos controle sobre a mensagem de erro, que vem do Linux. O fato de termos mudado como os arquivos executáveis ​​são tratados está listado no changelog:

O recarregador não adicionará o executável Python à linha de comando se o arquivo Python estiver marcado como executável. Isso permite que o recarregador funcione no NixOS. #1242

Tornar o arquivo não executável funciona. A linha shebang não, para mim. Em vez disso, recebo erros de arquivo não encontrado. Essa foi a primeira coisa que tentei.

Com #!/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

Também acho que fazer uma mudança que funcione apenas em uma distribuição Linux, mas quebre o resto, não parece ideal. Tornar os arquivos não executáveis ​​parece a solução adequada, mas isso ainda parece quebrado para mim.

@penner42 tente #!/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

provavelmente você não tem link simbólico em python3

Mesmo resultado. O link simbólico python3 está lá, e apenas executar /usr/bin/env python3 ou /usr/bin/env python de um shell funciona.

FWIW, o Docker dá esse aviso ao compilar.
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.

Use o comando 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

O tutorial em https://docs.docker.com/compose/gettingstarted/ costumava funcionar no Windows 7?
Essa alteração recente é a causa pela qual vejo um erro semelhante ao tentar executar o exemplo:

$ 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

Fiz o mesmo tutorial e encontrei o mesmo problema. Isso resolveu para mim.

Eu adicionei o seguinte shebang ao topo do meu script app.py

#!/usr/local/bin/python3

O que causou problemas de permissão. Em seguida, adicionei o seguinte ao meu Dockerfile antes do CMD

RUN chmod 644 app.py

Por favor, qualquer um pode atualizar o tutorial (https://docs.docker.com/compose/gettingstarted/)
adicionar

RUN chmod 644 app.py

Alterações no tutorial do Docker Compose propostas em https://github.com/docker/docker.github.io/pull/8609.

Corrigido na Ferramenta 0.15.5.

Esta página foi útil?
0 / 5 - 0 avaliações