При запуске nginx + флешка python + python-daemon: апстрим отправил неподдерживаемую версию протокола FastCGI 91

Я использую Python Flask для запуска Python для веб-сайтов через FCGI с помощью nginx. Мой бэкэнд для fcgi настроен так:

#!/usr/bin/env python
import argparse, daemon, os
from flup.server.fcgi import WSGIServer
from fwd_msg import app

SOCKET_LOCATION = '/tmp/fingerprinter-fcgi.sock'

if __name__ == '__main__':
    # arg parse (and daemonize)
    arg_parser = argparse.ArgumentParser()
    arg_parser.add_argument('--daemon', action='store_true', default=False, help='Run as daemon')
    arg_parser.add_argument('--cwd', action='store', default='/', 
                            help='Full path of the working directory to which the process should change on daemon start.')
    arg_parser.add_argument('--uid', action='store', type=int, default=os.getuid(),
        help='The user ID ("UID") value and group ID ("GID") value to switch the process to on daemon start.')
    args = vars(arg_parser.parse_args())

    if args['daemon']:
        context = daemon.DaemonContext(working_directory=args['cwd'], uid=args['uid'])
        with context:
            WSGIServer(app, bindAddress=SOCKET_LOCATION).run()
    else:
        WSGIServer(app, bindAddress=SOCKET_LOCATION).run()

Если я запускаю WSGIServer без аргумента демона, он работает нормально.

Но если я запускаю его с аргументом daemon, я получаю эту ошибку в журнале nginx, в то время как любые запросы к серверу заканчиваются на "502 BAD GATEWAY":

2012/05/09 12:16:00 [error] 30895#0: *30 upstream sent unsupported FastCGI protocol version: 91 while reading response header from upstream, client: XXX.XXX.XXX.XXX, server: localhost, request: "POST / HTTP/1.1", upstream: "fastcgi://unix:/tmp/fingerprinter-fcgi.sock:", host: "XXX.XXX.XXX.XXX"

Есть идеи, почему это происходит и как это предотвратить?

1 ответ

Решение

Оказывается, что DaemonContext закрывает все открытые дескрипторы файлов, поэтому в основном должна быть функция, которая создает экземпляр WSGIServer вместе с приложением и всем, что может открыть дескриптор файла ВНУТРИ DaemonContext.

Также убедитесь, что рабочий каталог таков, что принадлежит пользователю или, по крайней мере, имеет разрешения, позволяющие пользователю с указанным UID писать туда (не рекомендуется).

Пример:

#!/usr/bin/env python
import argparse, daemon, os
from flup.server.fcgi import WSGIServer
from fwd_msg import app

SOCKET_LOCATION = '/tmp/fingerprinter-fcgi.sock'

def main():
    app = flask.Flask(__name__)
    @app.route('/', methods=['GET'])
    def index():
        pass # your actions here

if __name__ == '__main__':
    # arg parse (and daemonize)
    arg_parser = argparse.ArgumentParser()
    arg_parser.add_argument('--daemon', action='store_true', default=False, help='Run as daemon')
    arg_parser.add_argument('--cwd', action='store', default='/', 
                            help='Full path of the working directory to which the process should change on daemon start.')
    arg_parser.add_argument('--uid', action='store', type=int, default=os.getuid(),
        help='The user ID ("UID") value and group ID ("GID") value to switch the process to on daemon start.')
    args = vars(arg_parser.parse_args())

    if args['daemon']:
        context = daemon.DaemonContext(working_directory=args['cwd'], uid=args['uid'])
        with context:
            main()
    else:
        main()
Другие вопросы по тегам