問題描述
web.py + lighttpd + matplotlib 不工作 (web.py + lighttpd + matplotlib not working)
I'm trying to deploy my web.py app with lighttpd. It doesn't work if import matplotlib.
This works...
hello.py:
#!/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
I go to my site and see "hello web.py".
But if I add import matplotlib
to hello.py and restart the server, then when I go to the site I get a 500 ‑ Internal Server Error.
Here's /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
‑‑ Edit ‑‑
Here is my lighttpd.conf: http://pastebin.com/n6sG5z9K
Pretty sure it's just the default (except I set server.document‑root = "/var/www/hello/"
)
Here is my 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",
)
Any suggestions?
‑‑‑‑‑
參考解法
方法 1:
Stumbled into this today (with Apache, but it's likely to be exactly the same issue). I redirected stdout and stderr from the script to see what was happening, and the issue is that matplotlib is trying to create a file:
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
Since it's being run as user httpd (Apache), it tries to create the file in /var/www/, which is root‑owned, and not writeable by the Apache user.
One valid solution is as simple as setting the MPLCONFIGDIR to a temporary directory before importing matplotlib:
import os
import tempfile
os.environ['MPLCONFIGDIR'] = tempfile.mkdtemp()
import matplotlib
To track the issue, this is how I redirected stdout and stderr to some log file to see what was happening:
sys.stdout = open("/var/log/dla_stdout.txt", 'a')
sys.stderr = open("/var/log/dla_stderr.txt", 'a')
I actually got the solution from this other StackOverflow question: Setting Matplotlib MPLCONFIGDIR: consider setting MPLCONFIGDIR to a writable directory for matplotlib configuration data
方法 2:
I was following this recipe: http://webpy.org/cookbook/fastcgi‑lighttpd
I overlooked a link at the top to this thread: http://www.mail‑archive.com/webpy@googlegroups.com/msg02800.html
That thread had the solution. I run the python process like so:
/var/www/hello.py fastcgi 9080
and then set my fastcgi.conf
like so:
fastcgi.server = ( "/hello.py" =>
((
"host" => "127.0.0.1",
"port" => 9080,
"check‑local" => "disable"
))
)
Then it works. (Still not sure I've got everything configured properly, but things seem to be working.)
方法 3:
I fix the issue by:
pip install flup
don't need
/var/www/hello.py fastcgi 9080
my system is: amazon ec2, ubuntu 10.04 lighttpd: 1.4.26
方法 4:
My first guess is that you're getting an ImportError
because matplotlib
wasn't installed properly or isn't on the PYTHONPATH
or some other crazy thing. The only way to know for sure is to look at the traceback. It shows you're running fastcgi, which means that the python code is being executed in another process. Therefore, you can't find the traceback in the lighttpd logs.
How are you running the fastcgi process? The traceback would have been written to its stderr. You might also consider using supervisord. It has support for redirecting stderr to a log file and various other things that make creating daemon processes easier.
(by Jesse Aldridge、jonbho、Jesse Aldridge、Lin Li、Jason Baker)