There are many ways to skin this cat, so this blog post is going to look at some of the ways that you can help simplify Apache Virtual Host configuration on Linux by breaking things down into manageable self-contained chunks with bounded contexts, aka. all around a domain name which is what 99% of people will be aiming to do.
The difficulty with the official documentation for Apache Virtual Hosts is that it provides many different examples to follow, but gives very little contextual information around use case and instead goes very deep into the art of the possible without guiding you to where you should look. And I guess that’s fine to an extent for official documentation, but it’s also not very useful at the same time as different configurations require different levels of complexity.
So in this blog post we’re going to focus on the common setup for what the majority of use cases for Apache Virtual Hosts are and how you should probably set this up to make your life easy.
Firstly, it’s important to understand the situation we find ourselves in. Below is a basic hierarchy of layers where this sits. Naturally this is going to differ in reality for most situations, but conceptually in most cases, this tends to be the setup that is ultimately in place in one way or another with a few nuances along the way.
- Virtual Machine
- Apache / HTTPd
- Default Document Root
- Default httpd.conf
- example.com Document Root
- example.com httpd.conf
- another-example.com Document Root
- another-example.com httpd.conf
- Apache / HTTPd
Operating System Firewall
Keep an eye on this, this is one of the steps that causes a lot of confusion. People often start working at the Apache HTTPd layer, yet haven’t opened the correct ports on the Operating System Firewall. By default many modern operating systems are out of the box configured as a deny-all setup so are likely to block traffic before it’s even reached your Apache HTTPd installation, usually the default open ports are only port 22 for SSH access.
Remember, the layers of your system are essential to understand in detail to make your life easier debugging problems.
The operating system firewall is beyond the scope of this blog post, so we’ll cover this off in a subsequent blog post, but always keep this in mind.
Apache HTTPd Installation
When we install Apache HTTPd via tools such as Yum it will create folders, files and scripts throughout the system. The important ones being;
- /etc/httpd/ – For the configuration aspects of Apache HTTPd
- /var/www/html – For the files that need to be served to users accessing web applications
This is the basics.
For single website hosting this can be more than fine to work with out of the box with zero additional configuration. In reality, most Apache HTTPd installations are hosting many websites, essentially acting as a mini-reverse proxy inside the virtual machine to host multiple websites on the same virtual machine and ultimately the same underlying infrastructure.
Ok, so getting back to basics here. What is a Document Root? In simple terms, this is the home directory for a specific configuration. To put this into context, most people run Windows computers for personal and corporate use. In this example, your “Document Root” is the equivalent of “My Documents”.
So when User 1 logs into a Windows computer they go to “My Documents” and see their own files.
When User 2 logs into a Windows computer they go to “My Documents” and see their own files.
The concept of a Document Root is essentially the under-the-hood configuration that makes this possible.
So in the same way when we are hosting multiple websites this essentially allows us to direct example-one.com to /example-one/index.html, and example-two.com to /example-two/index.html.
Conceptually this is what we’re working with, despite the terminology and underlying configurations being fairly complex using lots of terms that aren’t familiar to 99.9% of us and having to search the web to gather these pieces of information.
So, let’s dig deeper…
Default Document Root – /var/www/html
The default Document Root that is created on Apache HTTPd installation usually lives at /var/www/html. You can confirm this on first installation if you setup Apache HTTPd and then try to access the IP address of the virtual machine. If you have no advanced configuration sitting in the way, you’ll see a successful page that shows a message confirming that Apache HTTPd has been successfully installed. Awesome
Domain Specific Document Root – /var/www/example.com/public_html
But, what if you want to host multiple websites using Apache HTTPd, you need to segment this into a separate Document Root for ease of management. Essentially two separate folders for two different domains;
- example-one.com > /var/www/example-one.com/public_html/index.html
- example-two.com > /var/www/example-two.com/public_html/index.html
Create a basic “Hello World” index.html file for Example One and Example Two so you can easily identify the two and you’re good to go.
You’ll notice that if you check these locations after initial setup that they don’t exist. You need to create these folders and files using Linux commands such as mkdir and nano index.html if you’re not too familiar with these commands. These commands are the equivalent on Windows of right clicking and selecting the Create Folder menu item and the Create File item respectively.
Here we have now created two separate folders, aka. Document Roots, that we can then use to configure the Apache HTTPd Configuration.
Apache HTTPd Configuration Files
Now that we’ve covered off the Document Roots which is where your files live, the next step is to cover off how to configure Apache HTTPd Virtual Hosts properly to ensure your hostnames can root to the correct Document Root.
Default HTTPd.conf – /etc/httpd/conf/httpd.conf
The default configuration file that comes out of the box with Apache HTTPd is located at /etc/httpd/conf/httpd.conf. This is the global single file that rules them all. What is important though is that this file can be added to and also extended or overridden. This is where things get interesting.
There are many way to skin a cat, and this is one example. Fundamentally there are two ways to extend the Apache HTTPd configuration, one of them is by extending this main configuration file. The other is what we’re going to cover off next.
While is it possible to extend the main Apache httpd.conf file, it’s generally bad practice to do so when you are configuring virtual hosts. Mainly because it makes things significantly more difficult to manage and maintain.
If you do want to add Virtual Hosts configuration to the primary httpd.conf file then you simply add these details;
CustomLog /etc/httpd/logs/mk1.contrado.cloud-access.log combined
Ultimately though, whatever you do in your httpd.conf file, can be over ruled by a separate domain specific configuration file. This is what we’re going to cover next.
It’s not best practice to add Virtual Hosts to your httpd.conf file as it keeps every single configuration bound to a single file which can cause problems with dependencies over time.
Domain Specific HTTPd.conf – /etc/httpd/conf.d/example.com.conf
So we’ve talked previously about adding the specific configuration to a separate Apache HTTPd configuration file which is what we’re going to look at next. Apache is a well-established and advanced piece of software which understands parent/child relationships. And this is the case with .conf files.
As we’ve seen earlier around how the core httpd.conf file is located and how the override is configured, let’s look at this;
- /etc/httpd/conf/httpd.conf – Default Apache HTTPD configuration file
- /etc/httpd/conf.d/example.com.conf – Domain specific Apache HTTPD configuration file
It’s not super complex in practice, while under the hood it clearly is. Ultimately it’s a simple scenario that if there is a domain specific configuration file then this takes priority over the general configuration file.
And all this is managed through the configuration of the Apache HTTPd Virtual Hosts syntax.
To manage this effectively, simply create a file using the command;
Then add in the exact same configuration details that we’ve outlined earlier;
CustomLog /etc/httpd/logs/mk1.contrado.cloud-access.log combined
What this essentially means is that Apache will take into account these additional configuration files and use them to override the default. This is all accomplished via the primary http.conf file mentioned earlier with the out of the box configuration of;
There is nothing specific to configure to make sure this is working.
Virtual Machine or Apache Level SSL Configuration via Let’s Encrypt
There are many way to ‘do’ SSL. In most legacy on-prem setups, you’ll tend to find that SSL is offloaded at the primary on-prem firewall and traffic is unencrypted from that point forward as traffic travels to the correct virtual machine with Apache or Nginx is running etc.
I’m not saying this is bad practice per say, because it works, but yeah, it’s often a very error prone setup with all eggs in one basket and all and often causes significant bottle necks as the primary firewall tends to be heavily restricted and any change is virtually impossible to make without weeks of discussions, planning, forms and more – for what is ultimately a 5 minute job in most cases to implement.
So, for the purpose of this blog post and to provide a full end to end setup, we’re going to assume that you’re using modern Let’s Encrypt technologies to generate your SSL certificates on the fly for free every few months automatically, from the virtual machine where your application lives.
If you need more information about Let’s Encrypt then we have covered off several blog posts on this topic over the years so search around the site, some of the core ones being;
- Claim Your Free SSL Certificates for HTTPS
- How to Use AutoSSL on WHM and cPanel for SSL Certificates
- How to Setup an Apache Tomcat Environment for Java on AWS Using EC2 in 15 Minutes
- How to Configure Let’s Encrypt on CentOS6 with cPanel and WHM (out of date operating system, but principles remain)
- How to Setup Let’s Encrypt on pfSense
- How to Setup Let’s Encrypt on AWS EC2 Using Amazon Linux 2
Why it’s important to mention this is because of the previous setups we’ve gone through.
We’ve not really covered security considerations for any of the above in this blog post as this is a significantly more in-depth discussion which has many nuances based on every individual setup, governance and controls.
For the purpose of this blog post, this has been to look at how to host multiple websites behind a properly configured Apache HTTPd Virtual Host setup for applications that you own, control and can trust 100%.
Things get significantly more complex for other applications when there are multi-tenancy considerations which is ultimately where software such as cPanel and WHM come into play, but that’s a topic for another time.
Hopefully this blog post has provided you with some insight on how to configure Apache Virtual Hosts using Document Roots and HTTPd.conf files and separate domain specific HTTPd configuration files to help make your life easy to manage and keep configurations segmented.
As with everything Apache and HTTPd related, everything is going to be specific to your individual use case so please treat this blog post as guidance not a rule. Take a look at your own set up and assess how any of this information may or may not apply to your specific setup.
Hope this helps.