Ubuntu in Production: Virtual Hosts
The second post of series Ubuntu in Production: Setting up a baseline virtual host configuration.
Virtual hosts are the bread and butter of Apache. They allow you to run multiple websites off of one web server as well as customize settings for each site.
Setup:
In Ubuntu, virtual hosts are setup to work by default. Any file you add to /etc/apache2/sites-enabled will be read.
By convention, Ubuntu uses two directories for virtual hosts. /etc/apache2/sites-available and /etc/apache2/sites-enabled. Sites-enabled contains symlinks to sites-available. In this way, you can have configurations for sites saved in sites-available, but disabled (By removing the symlink from the sites-enabled directory).
Jumping ahead a bit:
Let's say you have a virtual host configuration (test.com.conf) setup in /etc/apache2/sites-available/test.com.conf. This is not yet enabled.
$ sudo a2ensite test.com.conf #Create symlink in sites-enabled to test.com.conf in sites-available
$ sudo service apache2 reload #Reload apache config so it's aware of new virtual host
Now, let's disable that:
$ sudo a2dissite test.com.conf #Remove symlink
$ sudo service apache2 reload
So, now we know how to enable or disable a virtual host. Now let's go over some useful configurations.
Virtual Host Config Files
Your best bet for a starting place is to copy Apache's default /etc/apache/sites-available/default. (Note that I like to make my files with the extension ".conf" - That's not necessary).
$ sudo cp /etc/apache2/sites-available/default /etc/apache2/sites-available/test.com.conf
Here's what's in there.
<VirtualHost *:80>
ServerAdmin webmaster@localhost
DocumentRoot /var/www
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
<Directory /var/www/>
Options Indexes FollowSymLinks MultiViews
AllowOverride None
Order allow,deny
allow from all
</Directory>
ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
<Directory "/usr/lib/cgi-bin">
AllowOverride None
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
Order allow,deny
Allow from all
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
LogLevel warn
CustomLog ${APACHE_LOG_DIR}/access.log combined
Alias /doc/ "/usr/share/doc/"
<Directory "/usr/share/doc/">
Options Indexes MultiViews FollowSymLinks
AllowOverride None
Order deny,allow
Deny from all
Allow from 127.0.0.0/255.0.0.0 ::1/128
</Directory>
</VirtualHost>
There's a ton of defaults in here that we don't need for every virtual host we create. Most of them are server setup that should be global and isn't needed for specific vhosts. Remove these form test.com.conf.
# Globally (server-wide) follow symlinks and ignore .htaccess files
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
# Sets up CGI
ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
<Directory "/usr/lib/cgi-bin">
AllowOverride None
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
Order allow,deny
Allow from all
</Directory>
# Sets up apache docs, available via localhost
Alias /doc/ "/usr/share/doc/"
<Directory "/usr/share/doc/">
Options Indexes MultiViews FollowSymLinks
AllowOverride None
Order deny,allow
Deny from all
Allow from 127.0.0.0/255.0.0.0 ::1/128
</Directory>
We're left with a bare-bones starting place for our vhost:
<VirtualHost *:80>
ServerAdmin webmaster@localhost
DocumentRoot /var/www
<Directory /var/www/>
Options Indexes FollowSymLinks MultiViews
AllowOverride None
Order allow,deny
allow from all
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
LogLevel warn
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
Now, let's make some changes specific to test.com.
<VirtualHost *:80>
ServerAdmin webmaster@localhost
ServerName test.com
ServerAlias www.test.com
DocumentRoot /var/www/test.com/public_html
<Directory /var/www/test.com/public_html/>
Options -Indexes
AllowOverride All
Order allow,deny
allow from all
</Directory>
ErrorLog ${APACHE_LOG_DIR}/test.com-error.log
# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
LogLevel warn
CustomLog ${APACHE_LOG_DIR}/test.com-access.log combined
</VirtualHost>
What was done?
- ServerName and ServerAlias: Let Apache know the ServerName to check for (test.com) with ServerName. ServerAlias tells apache to listen to other domains and point them to this virtual host as well. The "www" subdomain isn't really necessary here, but illustrates that you could have "stage.test.com" point to the same web files if you wanted.
- DocumentRoot: Change to suit your needs. I often have a "public_html" directory which is the web root. Then I can encapsulate related files which stay behind the web-root within the sites directory. (site.com directory, with site.com/public_html directory as the web-root)
- Options -Indexes:: -Index stops people from being able to go to a directory and see files listed in there. Instead they see a Forbidden error. Stops users view all your files in your /images directory, for instance.
- AllowOverride: Set to "all" to allow htaccess files in your virtual host directory (And sub-directories)
- ErrorLog, CustomLog: Create log files specifically for your domain, so they don't get mixed in with traffic / errors from other sites running on the server.
So, this is a good place to start for virtual host config files. I have a script which creates a virtualhost and enables it in bash and python flavors: https://gist.github.com/2710970
Usage:
$ sudo vhost -s test.com -d /var/www/test.com/public_html
$ sudo service apache2 reload
comments powered by Disqus
