Apache Virtual Host Containers in Separate Files

1. Introduction

With the size of the Apache configuration file what it is, it can be easier to find and change a virtual host container (configurations) if the settings are in separate files.

 This isn’t strictly recommended by the upstream documentation, but is a common manual extension to make the system more manageable.

 All manual extensions to your system should be documented for future reference.

 There are several places that virtual host source files can be put. This is a complex topic with several major points of view and is not fully addressed in this document.

2. Usual Practice: conf.d/

The most common location for discrete virtual host configuration files is /etc/httpd/conf.d/. The config files can be named to reflect the website(s) to which they refer, provided they don’t conflict with configuration files of existing or future modules. The matching content can be placed under /var/www/ or /var/www/html/ in sub-directories, such as /var/www/example.com/ or/var/www/html/example.com/.
This has the advantage that the parent directories are already created and SELinux is familiar through rule inheritance, as to how to handle access rights. The packaging system leverages this, of course, by dropping the php.conf file into that configurartion directory such that after a package based install of php, and a restart of the webserver, PHP parsed pages ‘just work’
Though placing a vhost configuration file in a directory full of non-vhost related matter, such as: php.conf and mailman.conf, initially appears an out of order jumble, upon closer reading of the documentation, from Apache HTTP Server Version 2.2 – Configuration Sections, we see that: “Most containers are evaluated for each request.”
So, Apache applies the virtual host directives after all non-vhost related stanzas, regardless of the seeming alphabetical sort order position in the configuration file, or in a merged directory full of such config files, in the matter processed.
This is largely a settled area of Systems Administration, such that the most recent documentation from upstream does not appear to include a ‘System Administration Guide’ in the CentOS 5 series. The System Administration Guide from CentOS 4, Chapter 24. Apache HTTP Server Configuration covers the matter in greater depth.

3. Virtual Host Files

Virtual Host container files can be placed in the configuration directory directly or by link. The name must end with .conf to be included. If using links, make sure to update the SELinux properties of the actual file.

3.1. Example

The file should contain the configuration items specific to this host. An example.conf could be…
# file: /etc/http/conf.d/example.conf
# vhost: example.org *.example.org

ServerName example.org
ServerAlias *.example.org
ServerAdmin webmaster@example.org
ErrorLog /var/log/httpd/example.err
CustomLog /var/log/httpd/example.log combined
DocumentRoot /var/www/example.org

Order allow,deny
Allow from all

Of course, a virtual host configuration file may refer to more than one URL or DNS result as a single file tree.
[userid@webhost conf.d]$ cat example.conf 
### two domain vhost sites handled here:
### example.com and example.org
### the .COM

ServerAdmin webmaster@example.com
DocumentRoot /var/www/html/example.com/public_html/
ServerName example.com
ServerAlias www.example.com
ErrorLog logs/example.com-error_log
TransferLog logs/example.com-access_log
AccessFileName .htaccess

### the .ORG

ServerAdmin webmaster@example.org
DocumentRoot /var/www/html/example.org/public_html/
ServerName example.org
ServerAlias www.example.org
ErrorLog logs/example.org-error_log
TransferLog logs/example.org-access_log
AccessFileName .htaccess

This file sets up the two domains, one the .com and the other the .org. As to each, it would provide the same content at the bare domain name, and also at the www when used either way in a URL for a web browser, which is usually the desired result, but of course possibly differing content between the two TLD variations as the content down the file tree specified.

4. Virtual Host Inclusion

There might be times when it is desirable to disable a virtual host. Since the include in /etc/httpd/conf/httpd.conf specifies *.conf, it is possible to hide a virtual host by changing the configuration file name.

4.1. Disable Virtual Host

Virtual hosts can be disabled by renaming the file so it doesn’t match the *.conf file specification. Adding a disabled extension is one way.
mv --verbose /etc/httpd/conf.d/example.conf /etc/httpd/conf.d/example.conf.disabled
If less typing is desired, it can be shortened:
mv -v /etc/httpd/conf.d/example.conf{,_}

4.2. Enable Virtual Host

Virtual hosts can be re-enabled by removing the extra.
To remove the disabled flag:
mv --verbose /etc/httpd/conf.d/example.conf.disabled /etc/httpd/conf.d/example.conf
For the shorter version:
mv -v /etc/httpd/conf.d/example.conf{_,}

 Enabling or disabling a virtual host using this method will not take effect until the web server is restarted.

5. Restart Apache

To make your changes take effect, restart Apache. Using the graceful option ensures that existing processes are allowed to finish serving the current page, reducing the chance of disrupting a user’s browsing experience.
service httpd graceful

 Thanks for the graceful suggestion, Filipe. And the pointer to Apache section interpretation.

6. Optional: vhost.d/ method

6.1. Disclaimer

 This section advocates an alternate approach that is outside of the strict, minimalist configuration used by many CentOS system administrators. Like any manual extension of your CentOSsystem, an update of the distribution could render your system broken.

Another location for virtual host container files is a new directory, /etc/httpd/vhost.d/ for example, and adding a vhost.conf file in conf.d/ to tell apache where they are. This segregates the virtual host container files from the module configuration files. This approach allows for easier backups of virtual host configuration changes and removes the possible chance of the different types of files having conflicting names.

6.2. Create Directory

Creating the directory with the same SELinux attributes as /etc/httpd/conf.d/…
mkdir --context=system_u:object_r:httpd_config_t /etc/httpd/vhost.d

6.3. Update SELinux Properties

Verifying the SELinux properties is as simple as…
ls -lZ /etc/httpd
and should return something similar to…
drwxr-xr-x  root root system_u:object_r:httpd_config_t conf
drwxr-xr-x root root system_u:object_r:httpd_config_t conf.d
lrwxrwxrwx root root system_u:object_r:httpd_log_t logs -> ../../var/log/httpd
lrwxrwxrwx root root system_u:object_r:httpd_modules_t modules -> ../../usr/lib/httpd/modules
lrwxrwxrwx root root system_u:object_r:httpd_config_t run -> ../../var/run
drwxr-xr-x root root system_u:object_r:httpd_config_t vhost.d
Since /etc/httpd/vhost.d/ is under /etc/httpd/, it should inherit any policy changes made to /etc/httpd/ and should survive a file system relabel.

6.4. Create New Virtual Host Configuration File

Let Apache know about the virtual host configurations location by creating a new configuration file in conf.d/.
echo "Include vhost.d/*.conf" >>/etc/httpd/conf.d/vhost.conf
Change the context to make sure Apache is allowed to read it
chcon --reference /etc/httpd/conf.d/README /etc/httpd/conf.d/vhost.conf

 Thanks, BrianMathis, for the conf.d/vhost.conf suggestion.

7. Optional: Configuration File Prefix

Naming the files with a prefix, like vhost-, might be more intuitive for others, might make the TLD more visible and would group the active and non-active virtual hosts.

 This method only works with an additional include directive in /etc/httpd/conf/httpd.conf.

 This can be combined with creating a new configuration file in conf.d/ to avoid modifying the distributed httpd.conf.

7.1. Include Directive

Instead of including files that end in .conf, include files that start with vhost-:
echo "Include conf.d/vhost-*" >>/etc/httpd/conf/httpd.conf
or, if using vhost.d/ method:
echo "Include vhost.d/vhost-*" >>/etc/httpd/conf/httpd.conf

7.2. Disable Virtual Host

Add _ to the beginning of a virtual host file name to prevent its inclusion:
mv -v /etc/httpd/conf.d/{,_}vhost-example.org
or, if using vhost.d/ method:
mv -v /etc/httpd/vhost.d/{,_}vhost-example.org

7.3. Enable Virtual Host

Remove the _ from the beginning of a virtual host file name to allow its inclusion:
mv -v /etc/httpd/conf.d/{_,}vhost-example.org
or, if using vhost.d/ method:
mv -v /etc/httpd/vhost.d/{_,}vhost-example.org

 Enabling or disabling a virtual host using this method will not take effect until the web server is restarted.

Control Default Apache Virtual Host

1. Introduction

When running multiple websites on a server as virtual hosts, there might occasionally be an issue somewhere, like a typo in a host configuration. The result might be that the first virtual host’s content would be displayed instead of the desired content. Since the website owner gets rather upset, it is not desirable. It’d be better to see a generic page.

2. Problem

When looking for the appropriate virtual host to use for a specific request, Apache goes through them in the ‘nix sort order they are defined. If it gets to the end, without a match, it uses the first virtual host.

3. Solution

Add a generic virtual host that is used instead of the current first one.

4. Virtual Host using httpd.conf

Adding the virtual host container to the end of the /etc/httpd/conf/httpd.conf file is the most obvious method for adding virtual hosts.
If inserting as the first host, put the container after the NameVirtualHost:80 line and before any other virtual host containers.
If adding a catch all virtual host at the end, make sure there are no containers after it because they won’t be available.

5. Virtual Host Files

A second method of adding virtual host containers to the Apache configuration is by using virtual host files. This is described in more detail in ApacheVhostDir.
If inserting as first host, name the file something that shows first in a directory listing, like 0Default.conf.
If adding a catch all virtual host, name the file something that will always be listed last, like zDefault.conf.

6. First Virtual Host

As a first virtual host, the ServerName should be something specific that is not actually used. It can be as simple as:

ServerName fail

7. Last Virtual Host

As a catch all virtual host, it should match everything. This can done with:

ServerAlias *

8. Restart Apache

To make your changes take effect, restart Apache.
service httpd graceful