Configuring Apache Virtual Hosts On RHEL 9
Apache virtual hosts let one RHEL 9 server deliver several websites while using a single public IP address. Each site can have its own domain name, document root, logs, access rules, and TLS configuration, which makes this arrangement practical for agencies, internal applications, and small hosting environments.
The method below uses name-based virtual hosting with the httpd package. It suits Australian deployments where several .com.au or .au domains may share infrastructure in Sydney, Melbourne, Brisbane, or another data-centre location.
Plan Hostnames And Directory Layout
Start by deciding which domain names Apache will serve. In this example, the site is example.com.au, with files stored under /var/www/example.com.au/public_html. Keeping each website in its own directory makes permissions, backups, and later migrations easier.
Create the directory and a test page:
sudo mkdir -p /var/www/example.com.au/public_html
sudo tee /var/www/example.com.au/public_html/index.html > /dev/null <<'EOF'
<!doctype html>
<html>
<head><title>Example Australia</title></head>
<body><h1>Apache virtual host is working</h1></body>
</html>
EOF
Australian businesses commonly operate across AEST, ACST, and AWST, so include the correct timezone in application settings and log analysis rather than assuming the server’s local clock matches every customer. A .com.au domain should also have accurate DNS records and registration details before production testing begins.
Install And Enable Apache
Install Apache and the utilities needed for service management and SELinux policy administration:
sudo dnf install -y httpd policycoreutils-python-utils
sudo systemctl enable --now httpd
RHEL uses /etc/httpd for Apache configuration. Unlike Debian-based systems, it does not normally provide sites-available and sites-enabled directories by default; files placed in /etc/httpd/conf.d/ are loaded automatically. Administrators comparing web servers can also review this Nginx guide before choosing which service best fits their environment.
Permit web traffic through the host firewall:
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload
Opening HTTPS at this stage is useful even if the certificate will be added later. Australian customers often expect secure connections for account portals, payments, and forms, while organisations handling personal information should consider their obligations under the Privacy Act 1988.
Create The Virtual Host Configuration
Create a dedicated configuration file:
sudo vi /etc/httpd/conf.d/example.com.au.conf
Add the following content:
<VirtualHost *:80>
ServerName example.com.au
ServerAlias www.example.com.au
DocumentRoot /var/www/example.com.au/public_html
<Directory /var/www/example.com.au/public_html>
AllowOverride None
Options -Indexes +FollowSymLinks
Require all granted
</Directory>
ErrorLog /var/log/httpd/example.com.au-error.log
CustomLog /var/log/httpd/example.com.au-access.log combined
</VirtualHost>
ServerName identifies the primary hostname, while ServerAlias accepts an additional name. Separate access and error logs make it easier to investigate one site without searching through every request handled by the server.
Check the configuration before restarting Apache:
sudo apachectl configtest
sudo systemctl reload httpd
A result of Syntax OK confirms that Apache can parse the file. A reload normally applies changes without interrupting existing connections, which is preferable during Australian business hours when customers may be accessing the site.
Apply SELinux And File Permissions
RHEL 9 commonly runs SELinux in enforcing mode. Apache needs the correct security context on the document root, even when ordinary Unix permissions appear correct:
sudo semanage fcontext -a -t httpd_sys_content_t \
'/var/www/example.com.au/public_html(/.*)?'
sudo restorecon -Rv /var/www/example.com.au/public_html
Give directories and files sensible ownership and modes:
sudo chown -R root:apache /var/www/example.com.au
sudo find /var/www/example.com.au -type d -exec chmod 0755 {} \;
sudo find /var/www/example.com.au -type f -exec chmod 0644 {} \;
If an application must write uploads or cache files, label only that specific directory with an appropriate writable SELinux type, such as httpd_sys_rw_content_t. Avoid disabling SELinux or making the entire document root writable, since that increases the impact of a compromised web application.
Point DNS And Test Requests
Create an A record for example.com.au pointing to the server’s public IPv4 address. Add an AAAA record only when IPv6 is correctly routed and protected by the firewall. For local testing before DNS changes propagate, add a temporary entry to /etc/hosts on the test workstation.
Test the site by sending the expected hostname:
curl -I http://example.com.au
curl -H 'Host: example.com.au' http://127.0.0.1
If the default Apache page appears, check for a typo in ServerName, confirm the request reaches the intended IP address, and inspect the virtual host list:
sudo httpd -S
sudo tail -f /var/log/httpd/example.com.au-error.log
DNS caching can make changes appear slower across Australian offices and mobile networks. Use dig example.com.au from more than one network, and remember that a low DNS TTL helps planned migrations but does not instantly invalidate every cached response.
Select A Maintainable Hosting Pattern
Name-based virtual hosts are usually the best option when multiple domains share one IPv4 address. IP-based hosting remains useful when a legacy application requires a dedicated address or when network policy separates services. TLS certificates can cover several names, but each hostname must still resolve to the server and be represented correctly in the certificate.
| Hosting pattern | Suitable use | Main requirement |
|---|---|---|
| Name-based | Several websites on one address | Correct Host header and DNS |
| IP-based | Legacy software or isolated services | Multiple server IP addresses |
| HTTP plus HTTPS | Public production websites | Port 80 redirect and valid TLS |
| Internal hostname | Office or private application | Internal DNS or managed hosts file |
Keep configuration in source control and record changes with the deployment date, hostname, and rollback steps. A lightweight project planning resource can help teams track DNS changes, certificate renewals, backups, and approval tasks without mixing operational notes into Apache files.
Practical Recommendations
- Use one configuration file and one log pair per website.
- Validate with
apachectl configtestbefore every reload. - Keep SELinux enforcing and label application write directories narrowly.
- Redirect HTTP to HTTPS after confirming the certificate and application work.
- Back up
/etc/httpd, web content, DNS records, and custom firewall rules.
After the first site responds correctly, create a second test hostname and repeat the process, beginning with /etc/httpd/conf.d/ and ending with curl -H 'Host: ...' before changing public DNS.