LINUX.ORG.RU

Docker (начала)

 


0

2

Привет, ЛОР. С наступившим! Пусть он принесет меньше кринжа и бугуртов, больше флекса и чила.

Осваиваю контейнеры, чтобы всем говорить о том, насколько они не нужны. Упёрся в как будто бы простую проблему, но решить её не получается. Делаю по старому туториалу и , полагаю, что до сих пор должно работать.

Есть приложение на питоне: my_module.py

from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'Connected as volume!\n'

и testapp.py

from my_module import app as application


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

Собираю образ. Dockerfile

FROM python:3.4

RUN pip install Flask==0.10.1 https://github.com/unbit/uwsgi/archive/uwsgi-2.0.zip#egg=uwsgi
Workdir /app
Copy app /app

CMD ["uwsgi","--http", "0.0.0.0:9000", "--wsgi-file", "/app/testapp.py", "--callable",\
"app", "--stats", "0.0.0.0:9001"]

Образ создается без ошибок, всё красиво. Запускаю образ

docker run --rm -d -p 9000:9000 -p 9001:9001 testapp

и теперь ожидаю, что на портах 9000 и 9001 локалхоста будет ответ от WSGI, однако там Internal server error. То есть сам сервер работает, но питоновский скрипт нет. В логах контейнера вижу:

*** Operational MODE: single process ***
unable to find "application" callable in file /app/testapp.py
unable to load app 0 (mountpoint='') (callable not found or import error)

Соответственно, при запросах к серваку, ругается, что питоновской проги не найдено

--- no python application found, check your startup logs for errors ---

Полагаю, что именно в этом и заключается проблема, но как её победить не знаю и прошу помощи. Кстати, разнести скрипт на основной и модуль мне подсказал гугол ( если модуль прям в основную программу запихнуть - тоже не работает), типа WSGI ожидает увидеть моё application в качестве переменной.

Щито делать то (ну кроме самовыпила с лора)?

★★

Последнее исправление: SpaceRanger (всего исправлений: 2)

Не специалист по uwsgi, но:

  1. Flask это уже вебсервер. Не совсем понимаю, зачем uwsgi когда можно поменять application.run(debug=True,host='0.0.0.0') на application.run(debug=True,host='0.0.0.0',port=9000) и получить то же самое, запуская python testapp.py. Тогда в докерфайле последняя строка будет CMD ["python", "testapp.py"]
  2. Если нужно именно uwsgi, то нужно менять параметры для запуска, так как uwsgi --http :9000 testapp.py возвращает uwsgi: option `--http' is ambiguous, да и почти все остальные параметры тоже не валидны.
Mr_Alone ★★★★★
()
Ответ на: комментарий от Mr_Alone
  1. Верно, фласк это вебсервер. НУ так автор книги захотел, чтобы был еще и uwsgi. И на этом примере построена не малая часть примеров с объяснениями. Поэтому беру то, что дают.
  2. Так а на что менять то? я с wsgi столкнулся впервые в жизни, собственно говоря.
SpaceRanger ★★
() автор топика
Ответ на: комментарий от SpaceRanger

1) Раз автор так захотел, значит напиши автору и спроси, чо делать и как пофиксить. Либо нужно найти обновлённое издание этой книги, которое соответствует действительности.
2) Я привёл пример в первом шаге, что делать и как запустить проект. Если не устраивает - читай мануал какие параметры нужно передать к uwsgi для запуска. Я точно с этим разбираться не буду.

Mr_Alone ★★★★★
()
Ответ на: комментарий от Mr_Alone

Flask это уже вебсервер.

Обычно встроенные веб-серверы предназначены для отладки, и их нельзя выставлять в Интернет напрямую. Но у меня опыта с Flask почти нет. Однако, думаю, что и в нём всё точно так же.

Для выставление в Интернет и требуются связующее ПО типа uwsgi, gunicorn, и т.д., которое подключается между фреймворком с одной стороны, и nginx (или другим веб-сервером) с другой стороны.

Поэтому, для разработки и деплоя используются разные Dockerfile, или конфигурации docker-compose с разными cmd/entrypoint (тут уже можно по-разному сделать: несколько docker-compose файлов, или профили в docker-compose).

emorozov
()

unable to find «application» callable in file /app/testapp.py

WSGI требует определенный интерфес, экспортируемый твоей программой. Он не просто запускает твой testapp.py, а ищет в нем точку входа — функцию application.
Тебе нужно ее определить так:

def application(environ, start_response):

urxvt ★★★★★
()
Ответ на: комментарий от urxvt

Спасибо за наводку! Вот так работает, но без callable в ключах запуска

CMD ["uwsgi","--http", "0.0.0.0:9000", "--wsgi-file", "/app/testapp.py"]
def application(env, start_response):                                                                                                                         
        start_response('200 OK', [('Content-Type','text/html')])                                                                                              
        return [b"Hello World"]

Однако мой изначальный скрипт чёт не желает рабоать с полным CMD

CMD ["uwsgi","--http", "0.0.0.0:9000", "--wsgi-file", "/app/testapp.py", "--callable", "app", "--stats", "0.0.0.0:90001"]

Пробовал и так

import my_module


def application(environ, start_response):
    my_module.app.run(debug=True,host='0.0.0.0')

и так

import my_module


def application(environ, start_response):
    start_response('200 OK', [('Content-Type','text/html')])
    return my_module.app.run(debug=True,host='0.0.0.0')

Также обнаружил, что если в исполняемый скрипт положить только это

from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'Connected as volume!\n'

то с полной списком комманд (callable) всё отлично исполняется…странно это всё

SpaceRanger ★★
() автор топика
Последнее исправление: SpaceRanger (всего исправлений: 1)