Django and Lighttpd configuration for smooth SSL

I use and prefer Lighttpd for serving my Django applications. Tonight I worked out a nearly perfect configuration which allows me to serve the app through fastcgi in both http, and SSL-enabled https. The media files are directly served by Lighty, without hitting the django backend at all, for maximum speed.

Better yet, this configuration allows me to directly serve the media files through ssl without having to get a separate certificate for the web server. Lastly, it serves both “www” and “non-www” versions of the domain, automatically redirecting “www” traffic.

The Commented Lighttpd Configuration


server.modules = ("mod_rewrite", "mod_redirect", "mod_alias",
    "mod_access", "mod_fastcgi", "mod_accesslog" )

server.document-root = "/www/static/"

# set up the fastcgi server on 11666
fastcgi.server = ( "/tribe.fcgi" =>
  ((
	"check-local" => "disable",
	"host" => "127.0.0.1",
	"port" => 11666,
	"min-proces" => 4,
	"max-load-per-proc" => 3,
	"broken-scriptfilename" => "enable",
  )),
)

# strip "www" - redirecting to non-www
$HTTP["host"] =~ "www\.ebooktribe\.com(.*)" {
    url.redirect = ( "^/(.*)" => "http://ebooktribe.com/$1" )
}

# serve ebooktribe.com, both static and dynamic
$HTTP["host"] == "ebooktribe.com" {
    server.bind = "75.126.217.231"

    # here we are mapping /media/ for admin media
    # and /static/ for the standard media_url
    alias.url = (
       "/media/" => "/usr/local/pythonlibs/django/django/contrib/admin/media/",
       "/static/" => "/www/media.ebooktribe/",
    )

    # this is key.  We use rewrite-once to trap out the media and static urls
    # so that they don't get sent to the fastcgi server.
    # the last rewrite rule here acts as a trap, collecting all the urls not
    # caught be previous rules
    url.rewrite-once = (
        "^(/media.*)$" => "$1",
        "^(/static.*)$" => "$1",
        "^/favicon\.ico$" => "/static/favicon.ico",
        "^(/.*)$" => "/tribe.fcgi$1",
    )

    server.errorlog = "/wwww/logs/ebooktribe.error.log"
    accesslog.filename = "/www/logs/ebooktribe.access.log"
}

# here is where I bind the ssl server to "secure.ebooktribe.com" on my
# reserved IP address.
$SERVER["socket"] == "75.126.217.230:443" {
    ssl.engine = "enable"
    ssl.pemfile = "/etc/lighttpd/ebooktribe.com/secure.ebooktribe.com.pem"
    ssl.ca-file = "/etc/lighttpd/ebooktribe.com/secure.ebooktribe.com.crt"
    server.name = "secure.ebooktribe.com"
    server.document-root = "/www/static"
    server.errorlog = "/webapps/logs/ebooktribe-ssl.error.log"
    accesslog.filename = "/webapps/logs/ebooktribe-ssl.access.log"

    alias.url = (
       "/media/" => "/usr/local/pythonlibs/django/django/contrib/admin/media/",
       "/static/" => "/www/media.ebooktribe/",
    )

    url.rewrite-once = (
        "^(/media.*)$" => "$1",
        "^(/static.*)$" => "$1",
        "^/favicon\.ico$" => "/static/favicon.ico",
        "^(/.*)$" => "/tribe.fcgi$1",
    )
}

accesslog.filename = "/www/logs/access.log"
static-file.exclude-extensions = ( ".php", ".pl", ".fcgi" )
server.username = "lighttpd"
server.groupname = "devel"
server.errorlog = "/www/logs/lighttpd.error.log"
index-file.names = ("index.html")