CLI Flask выдает «[Errno 2] Нет такого файла» при развертывании с помощью Docker - PullRequest
3 голосов
/ 25 марта 2019

Я слежу за курсом микро-услуг на testdriven.io.В этом курсе мне нужно развернуть приложение Flask с помощью Docker.Для запуска приложения я использую 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

Мой файл Docker:

# 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

Ответы [ 2 ]

1 голос
/ 08 апреля 2019

добавить werkzeug == 0.14.1 в require.txt может исправить ту же ошибку, что и в Windows. это похоже на ошибку werkzeug.

1 голос
/ 25 марта 2019

Когда вы выполняете скрипт, ядро ​​ищет интерпретатор, указанный в шебанге (#!). Местоположение интерпретатора извлекается, а затем запускается интерпретатор (например, 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.

Вы указали #!/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.

Чтобы избежать таких ситуаций, шебанги в скриптах обычно относятся не к самому интерпретатору (#!/usr/bin/python3), а к /usr/bin/env двоичному, который находит и выполняет интерпретатор:

#!/usr/bin/env python3

Когда вы запускаете python3 через env, последний выполняет поиск через PATH, поэтому он позволяет вашему шебангу не полагаться на конкретное местоположение 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()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...