Flexible vhost lighty config
September 25th, 2006
I've been trying to get a nice, flexible, solution for automagically configuring vhosts and subdomains. Here's my latest effort:
Subversion: http://svn.ardes.com/ardes/srv/local/etc/lightttpd
The solution is to meet the following desiderata:
- Flexible: no enforcing of a particular lighty/rails setup for a particular vhost,
- Flexible: no enforcing of a particular directory layout, and I want it to work for vhosts and subdomains, or a mixture of the two,
- Flexible: I want a solution which is compatible with serving only some sites with lighty (via ProxyPass in Apache),
- Set and forget: I don't want to have to edit my main lighttpd.conf file every time I add or remove a site.
- Encapsulated: I want the config files for a site to reside in that site's directory.
How to
Assumptions
I'm using a plesk system, and wanted to make it compatible with that. But the following should work with any site layout you want. Here's an example site layout:
/var/www/vhosts/example.com /var/www/vhosts/example.com/subdomains/blog
You want to serve both of the above using lighty, just static content from example.com, and a railsy blog from the blog.example.com subdomain.
Requirements and setup
First you need to get a copy of hosts.conf.rb. You should put this in your /etc/lighttpd directory and make it executable.
Then edit your lighttpd.conf file so that contains the line:
include_shell "/etc/lighttpd/hosts.conf.rb"
This will replace all of your host conditionals that configure your vhosts and subdomains. The configuration now goes into small files in the site directories (default is conf/lighttpd.conf, but this is configurable). Also, a var called host-root is set to the current path.
In /var/www/vhosts/example.com/conf/lighttpd.conf:
server.document-root = var.host-root + "/httpdocs"
In /var/www/vhosts/example.com/subdomains/blog/conf/lighttpd.conf:
var.rails-root = var.host-root + "/rails/typo"
var.fcgi-min-procs = 2
var.fcgi-max-procs = 4
include "rails.conf" # this script does all the rails stuff and should be
# placed in /etc/lighttpd
See rails.conf for the details of the above include script
Test
Now test this by running hosts.conf.rb from the command line. You should see the following output:
$HTTP["host"] =~ "(^|www\.)example\.com" {
var.host-root = "/var/www/vhosts/example.com"
server.document-root = var.host-root
}
$HTTP["host"] == "blog.example.com" {
var.host-root = "/var/www/vhosts/ardes.com/subdomains/gtd"
var.rails-root = var.host-root + "/rails/typo"
var.fcgi-min-procs = 2
var.fcgi-max-procs = 4
include "rails.conf" # this script does all the rails stuff and should be
# placed in /etc/lighttpd
}
Notice the the vhost is configured to catch www.example.com and example.com. Notice also that you don't have to edit the main /etc/lighttpd.conf file. The idea being: you can add and remove conf files to vhost and subdomain paths, and when lighty is restarted, they'll automatically be picked up by the hosts.conf.rb script!
So once you've got the output of hosts.conf.rb working the way you like it, you should restart lighty.
A glitch
At this point, I encountered a small problem with lighttpd 1.4.11. It complained that SHELL wasn't set when I tried to use
the 'include_shell' directive (kinda essential). This is no problem if you're manually starting lighty, but I'm using the init.d script. So I simply had to add the followng to /etc/init.d/lighttpd.
export SHELL=/bin/sh
Restart lighty and test!
Other configurations
If you want to do this with a different layout, you just need to edit the config section of hosts.conf.rb. The syntax is quite flexible, here's the config for the above setup:
Config = {
:vhost => {
:path => '/var/www/vhosts/:vhost:',
:host => '(^|www\.):vhost:'
},
:subdomain => {
:path => '/var/www/vhosts/:vhost:/subdomains/:subdomain:',
:match => '==',
:host => ':subdomain:.:vhost:'
}
}
The :path string can contain as many named variables as you like, they are surrounded by colons (e.g. :vhost:). The script simply searches the filesystem with these as glob wildcards. However the values are captured and stored by name for use in the host regexp specification. This is what makes it so easy to configure (the www example above is a good starting point).
Roundup
This is my first foray into lighty configuration. Please improve on this offering, or let me know if it doesn't work for you.
Aaron Says:
Thanks for this awesome combination of scripts. I was pulling my hair out when lighttpd was acting like it didn't know anything about my subdomains... Come to find out I forgot to make the hosts ruby script executable. Lighttpd didn't complain about nothing coming back from the include shell so it was hard to debug.June 10th, 2007 at 01:59 PM
Ian Says:
Hi Aaron, glad you found this helpful. Thanks for the tip about making sure the include_shell scripts are executable - will add it to the article.June 10th, 2007 at 02:00 PM