When working with the Apache HTTPD web server, it is essential to understand the concept of main server and virtual servers, along with the differences between them.
What is the main server ?
As an HTTP web server, the job of Apache is to serve incoming HTTP requests. This behaviour and functionality of the server can be configured via a bunch of settings. The way Apache has structured its configurations and internal working is that by default once it is installed on a machine and starts listening on an IP/Port interface, it starts serving any incoming HTTP requests on that interface based on whatever configuration is specified in its default configuration file.
This default or main configuration file represents the main server. We can call it the main server or the main server configuration, interchangeably.
What are virtual servers ?
Besides the main server configuration allowing us to serve incoming requests, we can add something called virtual servers in the form of vhosts or virtual hosts to it. This is accomplished by specifying the
<VirtualHost> directive inside the main server configuration only, which in itself contains a bunch of other configuration directives or settings.
Virtual hosts allows us to create multiple logical servers that can cater to requests on multiple or different network interfaces (IP addresses), ports and even for different domains as long as the DNS entries for those domains map to the machine’s IP address that is running
Using virtual hosts we are able to setup separate logical servers (on the same machine and within the same
httpd daemon) to serve traffic for separate websites, web apps, blogs, etc. and effectively separate clients or users as well. Inside the virtual host configuration we can override the default settings provided by the main server.
So how are they different again ?
They are both logical concepts and primarily driven by configurations. Precisely, the entire configuration appearing outside the
<VirtualHost> sections (one or more) denote the main server where as the lines inside
<VirtualHost> denote the virtual servers.
Essentially, the configuration directives specified for the main server or outside the virtual host blocks are treated as “defaults” or “base” on which the (configuration for) vhosts are built. Eventually when a request is matched with a virtual host, its configurations are merged with that of the main server to serve a request.
Why the term “server” ?
Because their jobs is to serve incoming requests based on whatever configuration settings have been applied.
What kind of configurations are we talking about ?
Looking at an example would be the best thing to do. Here’s the main server config (
apache2.conf) from one of my servers:
# Note: I've removed some parts since you just need to get an # idea and not go through tons of config lines $ cat /etc/httpd/conf/httpd.conf # # ServerRoot: The top of the directory tree under which the server's # configuration, error, and log files are kept. # ServerRoot "/etc/httpd" # # Listen: Allows you to bind Apache to specific IP addresses and/or # ports, instead of the default. See also the <VirtualHost> # directive. # # Change this to Listen on specific IP addresses as shown below to # prevent Apache from glomming onto all bound IP addresses. # #Listen 22.214.171.124:80 Listen 80 # # Dynamic Shared Object (DSO) Support # # To be able to use the functionality of a module which was built as a DSO you # have to place corresponding `LoadModule' lines at this location so the # directives contained in it are actually available _before_ they are used. # Statically compiled modules (those listed by `httpd -l') do not need # to be loaded here. # # Example: # LoadModule foo_module modules/mod_foo.so # Include conf.modules.d/*.conf # # If you wish httpd to run as a different user or group, you must run # httpd as root initially and it will switch. # # User/Group: The name (or #number) of the user/group to run httpd as. # It is usually good practice to create a dedicated user and group for # running httpd, as with most system services. # User apache Group apache # 'Main' server configuration # # The directives in this section set up the values used by the 'main' # server, which responds to any requests that aren't handled by a # <VirtualHost> definition. These values also provide defaults for # any <VirtualHost> containers you may define later in the file. # # All of these directives may appear inside <VirtualHost> containers, # in which case these default settings will be overridden for the # virtual host being defined. # # # ServerAdmin: Your address, where problems with the server should be # e-mailed. This address appears on some server-generated pages, such # as error documents. e.g. [email protected] # ServerAdmin [email protected] # # ServerName gives the name and port that the server uses to identify itself. # This can often be determined automatically, but we recommend you specify # it explicitly to prevent problems during startup. # # If your host doesn't have a registered DNS name, enter its IP address here. # #ServerName www.example.com:80 # # Deny access to the entirety of your server's filesystem. You must # explicitly permit access to web content directories in other # <Directory> blocks below. # <Directory /> AllowOverride none Require all denied </Directory> # # Note that from this point forward you must specifically allow # particular features to be enabled - so if something's not working as # you might expect, make sure that you have specifically enabled it # below. # # # DocumentRoot: The directory out of which you will serve your # documents. By default, all requests are taken from this directory, but # symbolic links and aliases may be used to point to other locations. # DocumentRoot "/var/www/html" # # Relax access to content within /var/www. # <Directory "/var/www"> AllowOverride None # Allow open access: Require all granted </Directory> # Further relax access to the default document root: <Directory "/var/www/html"> # # Possible values for the Options directive are "None", "All", # or any combination of: # Indexes Includes FollowSymLinks SymLinksifOwnerMatch ExecCGI MultiViews # # Note that "MultiViews" must be named *explicitly* --- "Options All" # doesn't give it to you. # # The Options directive is both complicated and important. Please see # <http://httpd.apache.org/docs/2.4/mod/core.html#options> # for more information. # Options Indexes FollowSymLinks # # AllowOverride controls what directives may be placed in .htaccess files. # It can be "All", "None", or any combination of the keywords: # Options FileInfo AuthConfig Limit # AllowOverride None # # Controls who can get stuff from this server. # Require all granted </Directory> # # DirectoryIndex: sets the file that Apache will serve if a directory # is requested. # <IfModule dir_module> DirectoryIndex index.html </IfModule> # # ErrorLog: The location of the error log file. # If you do not specify an ErrorLog directive within a <VirtualHost> # container, error messages relating to that virtual host will be # logged here. If you *do* define an error logfile for a <VirtualHost> # container, that host's errors will be logged there and not here. # ErrorLog "logs/error_log" # # LogLevel: Control the number of messages logged to the error_log. # Possible values include: debug, info, notice, warn, error, crit, # alert, emerg. # LogLevel warn # Supplemental configuration # # Load config files in the "/etc/httpd/conf.d" directory, if any. IncludeOptional conf.d/*.conf
The config above says a bunch of things:
- Apache or
httpdwill run on port
80of all network interfaces on the machine.
- It will run as
- Any incoming request will be served from
DocumentRoot "/var/www/html"if there is no matching VirtualHost block since this is the config for the main server.
- In the last line, it includes or loads other configuration files as well –
IncludeOptional conf.d/*.conf. This way we can break a large config files into multiple relevant chunks which are easier to manage.
- … a lot of other things.
Now if I had to create a virtual server or basically a virtual host, I could do it inside the same file above. But for the sake of separation and better clarity I’d create a separate file for the virtual server at
conf.d/codingshower.conf. We can see that
conf.d/ is loaded inside the main config above, hence all our configurations there will automatically get loaded by Apache. This is how my virtual host at
conf.d/codingshower.conf would look like:
<VirtualHost *:80> ServerName codingshower.com ServerAdmin [email protected] DocumentRoot /home/codingshower/html <Directory /home/codingshower/html> AllowOverride All Require all granted </Directory> </VirtualHost>
With that configuration, we’ve successfully created a virtual host or a virtual server that will now serve all incoming requests and the main server won’t be used anymore. Most of the configuration directives that are not specified in the block above, will be inherited from the main server as default values.
If required, we can add more virtual hosts to the same configuration file, different files under
conf.d/ or inside the main config itself. It is a good idea to put virtual hosts in separate files and include them inside the main server config. The default Apache installations generally follow that.
Where do I find the existing configuration files though ?
If you want to know where you can find these config files on different operating systems (Ubuntu, Debian, CentOS, Fedora, FreeBSD, macOS), I’ve created a reference for that. This reference will show you where to find both, the main server and virtual host configuration files.