Tag Archives: nginx

Building Nginx 0.9.5 on Debian Lenny

Nginx is available in Debian Lenny, but the version in stable is the old 0.6.x series. Perusio maintains a useful repository with development versions built for Lenny, but it requires libraries newer than those in stable.

UPDATED: fixed ‘build-essential’ – thank you Carlos

But it is easy enough to build a deb from the Perusio package which uses the stable libraries. Here are my notes. N.B. Editing the apt sources and installing packages needs root privileges.

First, add the Perusio repository to /etc/apt/sources.list:

cat >> /etc/apt/sources.list <<EOF
deb http://debian.perusio.net unstable/
deb-src http://debian.perusio.net unstable/
EOF

Update the apt-get index:

apt-get update

Install packaging tools (if they aren’t installed already):

apt-get install dpkg-dev
apt-get install fakeroot
apt-get install debhelper
apt-get install build-essential

Install headers for libaries required to build Nginx:

apt-get install autotools-dev libgeoip-dev libssl-dev libpcre3-dev zlib1g-dev

Now get the package source and build a deb installation package. This part can be done as a non-root user.

apt-get source nginx
cd nginx-0.9.5
dpkg-buildpackage -rfakeroot -uc -b

When I did this, the version in the repository was Nginx 0.9.5. The flag -uc says to not sign the changes file and -b says build a binary-only distribution. If you were cross-compiling, you can pass the -a flag to dpkg-buildpackage specifying the build architecture.

Assuming the build was successful, your new installation package will have been created in the parent directory (bloody hell Debian tools are unintuitive).

Here I built the deb on amd64. To install this I go:

dpkg -i ../nginx_0.9.5-perusio.1.0_amd64.deb

The advantage of building Nginx from Perusio’s repository rather than directly from the source is we get the hard work of conforming to the Debian layout for free.

Caching a Django app with Nginx + FastCGI

I just spent a stupid amount of time trying to figure why Nginx was failing to cache my Django app responses. The Django app is running as a FastCGI backend and I have Nginx using the fastcgi_cache directive to cache responses.

The answer is that Nginx since version 0.8.44 does not cache backend responses if they have a “Set-Cookie” header. This makes perfect sense because you don’t want a response which sets a cookie to be cached for subsequent requests, but I was stupid because I had totally forgotten that my Django app was using a POST form for all responses for non-authenticated clients (due to how Django’s CSRF middleware does its stuff).

The solution was to change the app so that it uses the GET method on the form in question, which in this case is fine from a security point-of-view.

The moral of this story is I should pay attention to my HTTP response headers and that I am badly short-sighted both figuratively and literally. With that fixed the site has gone from 15 requests per second to ~2000 requests per second!

Nginx and WordPress

My Nginx and WordPress configuration on Debian Linux 5 (Lenny). This has Nginx as the Web server using the fastcgi module to talk to php-cgi processes that run WordPress with pretty URLs.

The virtual private server I installed this on (from John Companies) has a 256 megabyte slice, so I figured a regular Apache + mod_php setup might be in trouble seeing as one of the sites I am running gets several thousand visits a day. Up to now I have always used Apache with mod_php to run WordPress, and anyway it is fun to learn how unfamiliar software works (Lotus Notes excepted).

On a side note, SysV run-levels and /etc/rcX.d directories are needlessly clever. sysv-rc-conf makes editing those easy.

server {
    listen   80;
    server_name  example.com;

    root   /home/david/example.com;
    index  index.php index.html index.htm;
    error_page   500 502 503 504  /50x.html;

    location / {

    }

    location = /50x.html {
        root   /var/www/nginx-default;
    }

    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    location ~ /\.ht {
        deny  all;
    }

    location /b/ {
        if (!-e $request_filename) {
            rewrite ^(.+)$ /b/index.php?q=$1 last;
        }
    }

    location ~ \.php$ {
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_index  index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }
}

# Rewrite www.example.com to example.com
server {
    listen 80;
    server_name www.example.com;
    rewrite ^ http://example.com$request_uri?;
}

This configuration is for WordPress installed under http://example.com/b/ on my server.