web.py + lighttpd + matplotlib не работает

Я пытаюсь развернуть свое приложение web.py с помощью lighttpd. Это не работает, если импортировать matplotlib.

Это работает...

привет.ру:

#!/usr/bin/python

import web

# Say hello.
class Index:
    def GET(self): return 'hello web.py'
if __name__ == "__main__":
    app = web.application(('/*', 'Index'), globals())
    app.run()

/etc/init.d/lighttpd restart

Я захожу на свой сайт и вижу "hello web.py".

Но если я добавляю import matplotlib в hello.py и перезапускаю сервер, то при заходе на сайт получаю 500 - Internal Server Error.

Вот /var/log/lighttpd/error.log:

2010-12-24 00:17:31: (log.c.166) server started
2010-12-24 00:17:42: (mod_fastcgi.c.1734) connect failed: Connection refused on
unix:/tmp/fastcgi.socket-0
2010-12-24 00:17:42: (mod_fastcgi.c.3037) backend died; we'll disable it for 1 s
econds and send the request to another backend instead: reconnects: 0 load: 1
2010-12-24 00:17:43: (mod_fastcgi.c.2582) unexpected end-of-file (perhaps the fa
stcgi process died): pid: 4074 socket: unix:/tmp/fastcgi.socket-0
2010-12-24 00:17:43: (mod_fastcgi.c.3320) child exited, pid: 4074 status: 1
2010-12-24 00:17:43: (mod_fastcgi.c.3367) response not received, request sent: 9
53 on socket: unix:/tmp/fastcgi.socket-0 for /hello.py?, closing connection
2010-12-24 00:20:30: (server.c.1503) server stopped by UID = 0 PID = 4095
2010-12-24 00:20:30: (log.c.166) server started

-- Изменить --

Вот мой файл lighttpd.conf: http://pastebin.com/n6sG5z9K

Почти уверен, что это просто значение по умолчанию (за исключением того, что я установил server.document-root = "/var/www/hello/")

Вот мой fastcgi.conf:

server.modules   += ( "mod_fastcgi" )
server.modules   += ( "mod_rewrite" )

fastcgi.server = ( "/hello.py" =>
 (( "socket" => "/tmp/fastcgi.socket",
    "bin-path" => "/usr/bin/python /var/www/hello/hello.py",
    "max-procs" => 1,
   "bin-environment" => (
     "REAL_SCRIPT_NAME" => ""
   ),
   "check-local" => "disable"
 ))
 )

url.rewrite-once = (
   "^/favicon.ico$" => "/static/favicon.ico",
   "^/static/(.*)$" => "/static/$1",
   "^/(.*)$" => "/hello.py/$1",
 )

Какие-либо предложения?


person Jesse Aldridge    schedule 24.12.2010    source источник


Ответы (4)


Наткнулся на это сегодня (с Apache, но, вероятно, это будет точно такая же проблема). Я перенаправил stdout и stderr из сценария, чтобы посмотреть, что происходит, и проблема в том, что matplotlib пытается создать файл:

Traceback (most recent call last):
  File "/home/ec2-user/dlea/src/dla.py", line 24, in <module>
    import dbm
  File "/home/ec2-user/dlea/src/dbm.py", line 7, in <module>
    import matplotlib
  File "/usr/lib64/python2.6/site-packages/matplotlib/__init__.py", line 709, in <module>
    rcParams = rc_params()
  File "/usr/lib64/python2.6/site-packages/matplotlib/__init__.py", line 627, in rc_params
    fname = matplotlib_fname()
  File "/usr/lib64/python2.6/site-packages/matplotlib/__init__.py", line 565, in matplotlib_fname
    fname = os.path.join(get_configdir(), 'matplotlibrc')
  File "/usr/lib64/python2.6/site-packages/matplotlib/__init__.py", line 240, in wrapper
    ret = func(*args, **kwargs)
  File "/usr/lib64/python2.6/site-packages/matplotlib/__init__.py", line 439, in _get_configdir
    raise RuntimeError("Failed to create %s/.matplotlib; consider setting MPLCONFIGDIR to a writable directory for matplotlib configuration data"%h)
RuntimeError: Failed to create /var/www/.matplotlib; consider setting MPLCONFIGDIR to a writable directory for matplotlib configuration data

Поскольку он запускается от имени пользователя httpd (Apache), он пытается создать файл в каталоге /var/www/, который принадлежит пользователю root и недоступен для записи пользователем Apache.

Одно допустимое решение так же просто, как установить MPLCONFIGDIR во временный каталог перед импортом matplotlib:

import os
import tempfile
os.environ['MPLCONFIGDIR'] = tempfile.mkdtemp()
import matplotlib

Чтобы отследить проблему, я перенаправил stdout и stderr в какой-то файл журнала, чтобы увидеть, что происходит:

sys.stdout = open("/var/log/dla_stdout.txt", 'a')
sys.stderr = open("/var/log/dla_stderr.txt", 'a')

На самом деле я получил решение из этого другого вопроса StackOverflow: Matplotlib MPLCONFIGDIR: рассмотрите возможность установки MPLCONFIGDIR в доступный для записи каталог для данных конфигурации matplotlib

person jonbho    schedule 02.04.2013
comment
Это было так давно, что я не в состоянии проверить этот ответ, поэтому я просто предполагаю, что он правильный :) - person Jesse Aldridge; 05.04.2013

Я следовал этому рецепту: http://webpy.org/cookbook/fastcgi-lighttpd

Я пропустил ссылку вверху на эту тему: http://www.mail-archive.com/[email protected]/msg02800.html

В этой теме было решение. Я запускаю процесс python следующим образом:

/var/www/hello.py fastcgi 9080

а затем установите мой fastcgi.conf так:

 fastcgi.server = ( "/hello.py" =>
     ((
        "host" => "127.0.0.1",
        "port" => 9080,
        "check-local" => "disable"
    ))
 )

Тогда это работает. (Все еще не уверен, что все правильно настроил, но похоже все работает.)

person Jesse Aldridge    schedule 24.12.2010

Я исправляю проблему:

pip install flup

не нужно

/var/www/hello.py fastcgi 9080

моя система: amazon ec2, ubuntu 10.04
lighttpd: 1.4.26

person Lin Li    schedule 23.05.2012

Мое первое предположение состоит в том, что вы получаете ImportError, потому что matplotlib не был установлен должным образом, или его нет на PYTHONPATH, или какая-то другая сумасшедшая вещь. Единственный способ узнать наверняка — посмотреть на трассировку. Он показывает, что вы используете fastcgi, что означает, что код Python выполняется в другом процессе. Поэтому вы не можете найти трассировку в логах lighttpd.

Как вы запускаете процесс fastcgi? Трассировка была бы записана в его stderr. Вы также можете использовать supervisord. Он поддерживает перенаправление stderr в файл журнала и различные другие вещи, которые упрощают создание процессов демона.

person Jason Baker    schedule 24.12.2010
comment
Я просто запускаю lighttpd с включенным fastcgi. Я предполагаю, что lighttpd обрабатывает порождение процесса за кулисами? Я отредактировал свой вопрос, чтобы показать файл fast-cgi.conf. Это вообще помогает? Кроме того, я не совсем понимаю, как supervisord вписывается во все это... Извините, если я глуп, я все еще новичок в этом деле. - person Jesse Aldridge; 24.12.2010