python windows docker flask docker-compose

python - Flask CLI lanza ''OSError:[Errno 8] Error de formato de ejecución'' cuando se ejecuta a través de docker-compose



windows (4)

Este es un nuevo comportamiento en Werkzeug 0.15. La reducción a Werkzeug 0.14.1 puede funcionar, pero 0.14 ya no es compatible, por lo que será mejor que corrija el problema con su archivo como se describe en las otras respuestas.

Estoy ejecutando una aplicación Flask con un script personalizado . O intentarlo, de todos modos.

Estoy en Windows 10 y la aplicación debería ejecutarse en un contenedor Docker de Linux con el comando:

docker-compose up api

Docker-compose es la version 1.23.2 . En el archivo docker, el servicio api ejecuta a través del comando:

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

Mientras trata de arrancar, veo la excepción.

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

Inicialmente pensé que estos serían los Finales de Línea Dreaded de Windows, venga por mí una vez más, pero ejecutar dos2unix en todos mis archivos de origen no ha resuelto el problema.

¿Cómo puedo evitar este error?

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()

Traceback completo

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''


La respuesta de @CristiFati me funcionó con 1 paso adicional:

También tuve que corregir el EOL de /r/n a /n .

Lo siento, no tengo suficientes puntos para agregar un comentario y tengo que abrir una nueva respuesta ...


Parece que su api / manage.py no tiene un shebang ( [Wikipedia]: Shebang (Unix) ), por lo que el procesador de comandos predeterminado (actual) (un shell - normalmente bash ) está intentando ejecutarlo, lo que (obviamente) falla

Para corregir el problema, agregue un shebang (al principio del archivo, asegurándose de que su editor agregue el final de la línea de estilo Nix ( / n , 0x0A , LF )):

  • Instalación predeterminada de Python :

    #!/usr/bin/env python

    • Variante (especifique Python 3 explícitamente):

      #!/usr/bin/env python3

  • Instalación personalizada de Python :

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

Tenga en cuenta que también necesita permisos de ejecución en el archivo ( chmod +x api/manage.py ).

Ejemplo:

[cfati@cfati-5510-0:/cygdrive/e/Work/Dev//q055271912]> ~/sopr.sh *** Set shorter prompt to better fit when pasted in (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//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//q055271912/code1.py


Otra forma sería ejecutar el intérprete seguido del nombre del archivo, pero no sé cómo hacerlo desde Flask ; en realidad, eso requeriría parchear Werkzeug ( _reloader.py : _get_args_for_reloading ), pero eso sería solo una solución poco convincente ( gainarie ) - ver más abajo.

@ EDIT0 :

Mirando la respuesta de @ AxelGrytt, resulta que es un problema conocido: [GitHub]: pallets / werkzeug - 0.15.0 hace que OSError: [Errno 8] Error de formato Exec: en Docker para Windows (hmm, enviado el mismo día que este Pregunta (y 2 días después del lanzamiento) :)).

Entonces, lo que he dicho anteriormente es correcto, pero vale la pena mencionar que hay otra forma de solucionarlo: eliminar el permiso exec para el archivo:

chmod -x api/manage.py

Según los autores de Werkzeug , a partir de ahora, este es el comportamiento deseado (también se aplica a v 0.15.2 ):

  • Un archivo con el permiso exec establecido, también debe tener un shebang
  • Un archivo sin un shebang , no debería tener el permiso exec establecido

Si deshabilita el modo de depuración (no pase debug=True o configure FLASK_DEBUG=0 ), el reloader no se utilizará y, por lo tanto, este problema no se producirá. La compensación es que ya no tienes el recargador.

if __name__ == "__main__": connexion_app.run(host="0.0.0.0", port=constants.API_PORT, debug=True)

Es preferible solucionar esto asegurando que los archivos marcados como ejecutables tengan una línea de intérprete, como #!/usr/bin/env python3 (de share ).