When I migrated from lighttpd to nginx, I really missed the mod_simple_vhost, and was desperately looking for an alternative. But actually, it was simpler than expected.
Virtual hosts
The principle is simple: you have one (or more) domain names. For this blog,
we'll consider you own example.org
, with a few CNAME
like foobar.example.org
,
ihazcheezburger.example.org
and pikachu.example.org
.
The naive solution to handle them would be:
server {
server_name example.org;
location / {
root /srv/http/vhosts/example.org;
index index.html index.htm;
}
}
server {
server_name foobar.example.org;
location / {
root /srv/http/vhosts/foobar.example.org;
index index.html index.htm;
}
}
server {
server_name ihazcheezburger.example.org;
location / {
root /srv/http/vhosts/foobar.example.org;
index index.html index.htm;
}
}
server {
server_name pikachu.example.org;
location / {
root /srv/http/vhosts/pikachu.example.org;
index index.html index.htm;
}
}
And so forth. It gets quickly painful to maintain, and the risk of error increases. Let's see how we can avoid this.
root my $vpath
Here is the (incomplete) trick:
server {
server_name _;
set $vpath /srv/http/vhosts/$host;
if (!-d $vpath) {
set $vpath /srv/http/vhosts/example.org;
}
root $vpath;
}
$host
contains the requested host. We check if a directory exists for this
domain in the /srv/http/vhosts
directory. If not, we serve the default one,
which is example.org
here.
And finally, root
selects the corresponding vhost directory.
Your tree will look like this:
% ls -l /srv/http/vhosts
drwxr-xr-x 4 ubitux ubitux 4.0K Aug 13 15:24 example.org
drwxr-xr-x 5 ubitux ubitux 4.0K Aug 15 2009 foobar.example.org
drwxr-xr-x 3 ubitux ubitux 4.0K Aug 13 15:24 ihazcheezburger.example.org
drwxr-xr-x 2 ubitux ubitux 4.0K Jan 10 2010 pikachu.example.org
There is still one issue to solve: if you keep the configuration in this state,
you will notice the host is always _
. We can fix that with the
server_name_in_redirect
option:
server {
server_name _;
server_name_in_redirect off;
set $vpath /srv/http/vhosts/$host;
if (!-d $vpath) {
set $vpath /srv/http/vhosts/example.org;
}
root $vpath;
}