Archive for July, 2010

Hash Ring fork

Saturday, July 10th, 2010

Amir Salihefendic‘s hash_ring module is awesome, but it doesn’t install cleanly with pip (dies with ez_setup import error) and spews some deprecation warning on Python 2.6+ (md5 module deprecated in favour of hashlib.)

In order to keep my deployment recipe sane, I’ve decided to fork the project on github.

Now, all you need is the following in requirements.txt:

-e git://github.com/wil/hash_ring.git#egg=hash-ring

Nginx + Django + FastCGI + SSL

Saturday, July 10th, 2010

My favourite method for deploying Django sites in production is with Nginx at the frontend talking FastCGI to a dedicated Django process (either flup or supervisord) via a UNIX or TCP socket.

There are two recurring issues that I keep running into costing hours of fruitless Googling. Hopefully, this will help others:

  • SCRIPT_NAME is evil! At least it’s useless in Django, and if present as a FastCGI parameter, Django will trip that away from your request URI and you’re almost certainly going to get / no matter what URI you navigate to! So, save SCRIPT_NAME for your PHP stuff, and leave it out of the parts where you expect to be talking to Django.
    If you have include fastcgi_params in your nginx.conf, make sure it’s not hiding behind the fastcgi_params file.
  • If you want SSL to work, i.e. for Django to know that it is serving in https mode, and to build proper Location header for redirects, you need to include the following in the appropriate section of your nginx.conf:

    fastcgi_param HTTPS on;

    Obviously, if you’re running both plain and SSL version, you shouldn’t be sharing that section or Django will just thinking that it is in SSL mode even when it’s not.

httpd exited on signal 11 – solved

Sunday, July 4th, 2010

tl;dr

It’s probably mod_php, and try recompiling PHP without zend_multibyte. If you have WITH_MULTIBYTE=true in /var/db/ports/php5/options, change it to WITHOUT_MULTIBYTE=true and rebuild the port.

Long Story

The Apache 2.2 processes on my FreeBSD box keep dying intermittently, with messages such as:


Jul 3 08:08:37 yama kernel: pid 13526 (httpd), uid 80: exited on signal 10
Jul 3 08:25:58 yama kernel: pid 33050 (httpd), uid 80: exited on signal 11

I’ve googled around and tried various extensions.ini reordering tricks without luck. Eventually, I figured out how to get Apache to dump core. First, you need to tell Apache where to dump core by adding the CoreDumpDirectory directive to your httpd.conf. Restart apache.

Then, check to make sure that the kern.coredump and kern.sugid_coredump sysctl variables are set to 1. Because Apache calls setuid and setgid to the configured user after listening on port 80 (privileged port), FreeBSD by default will refuse to dump core on segfaults. Setting kern.sugid_coredump will make it do so.


$ sysctl kern.coredump
kern.coredump: 1
$ sysctl kern.sugid_coredump
kern.sugid_coredump: 0
$ sudo sysctl kern.sugid_coredump=1
kern.sugid_coredump: 0 -> 1

Of course, you’d also need to make sure that your ulimit doesn’t prevent it from dumping core:


$ ulimit -c
unlimited

Great! Now wait for Apache to segfault (or, if you have a reproducible test case, hit it!)

You should now find httpd.core in the directory that you configured in httpd.conf (in my case, it is /tmp.)

Do the usual gdb stuff:


$ gdb /tmp/httpd.core /usr/local/bin/httpd

In my case, I found zend_multibyte_read_script near the top of the stack, so it’s pretty clear that PHP is to blame.
Did I mention that I abhor PHP? Someday I will get rid of it entirely!

This led me to more googling and found that I may have accidentally enabled Zend Multibyte support (well, its purpose is not very well documented and I just assumed that since I do lots of i18n work, it’ll come in handy. Okay so it’s my fault after all but it still shouldn’t crash!)

Changing WITH_MULTIBYTE=true to WITHOUT_MULTIBYTE=true in /var/db/ports/php5/options and rebuilding the port made the problem go away.

Hopefully, the above will help someone in a similar situation.