Skip to main content
Advertisement

Apache VirtualHost Configuration

Apache's VirtualHost allows a single server to handle multiple domains or ports. It is equivalent to Nginx's server block. This chapter covers name-based, IP-based, and port-based configurations, as well as multi-domain SSL using SNI.


VirtualHost Basic Structure

<VirtualHost IP:port>
ServerName domain
DocumentRoot /path/to/webroot
...
</VirtualHost>

Using * for the IP address means "accept requests on this port from any IP address."


Name-Based VirtualHost

Differentiates requests on the same IP and port by the domain name in the Host header.

Ubuntu Configuration

# /etc/apache2/sites-available/example.com.conf
<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
DocumentRoot /var/www/example.com
ServerAdmin webmaster@example.com

<Directory /var/www/example.com>
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
</Directory>

ErrorLog ${APACHE_LOG_DIR}/example.com.error.log
CustomLog ${APACHE_LOG_DIR}/example.com.access.log combined
</VirtualHost>
sudo a2ensite example.com.conf
sudo apache2ctl configtest && sudo systemctl reload apache2

Port-Based VirtualHost

# /etc/apache2/ports.conf
Listen 80
Listen 8080

<VirtualHost *:80>
ServerName example.com
DocumentRoot /var/www/main
</VirtualHost>

<VirtualHost *:8080>
ServerName example.com
DocumentRoot /var/www/admin
<Directory /var/www/admin>
Require ip 127.0.0.1 10.0.0.0/8
</Directory>
</VirtualHost>

HTTP → HTTPS Redirect

# HTTP — redirect to HTTPS
<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</VirtualHost>

# HTTPS — serve content
<VirtualHost *:443>
ServerName example.com
DocumentRoot /var/www/example.com
SSLEngine on
SSLCertificateFile /etc/ssl/certs/example.com.crt
SSLCertificateKeyFile /etc/ssl/private/example.com.key
<Directory /var/www/example.com>
AllowOverride All
Require all granted
</Directory>
</VirtualHost>

SSL VirtualHost and SNI

With SNI (Server Name Indication), you can use different SSL certificates per domain on a single IP:443 port.

<VirtualHost *:443>
ServerName site1.com
DocumentRoot /var/www/site1
SSLEngine on
SSLCertificateFile /etc/ssl/certs/site1.com.crt
SSLCertificateKeyFile /etc/ssl/private/site1.com.key
</VirtualHost>

<VirtualHost *:443>
ServerName site2.com
DocumentRoot /var/www/site2
SSLEngine on
SSLCertificateFile /etc/ssl/certs/site2.com.crt
SSLCertificateKeyFile /etc/ssl/private/site2.com.key
</VirtualHost>

Default VirtualHost

The first VirtualHost in the list becomes the default for unmatched requests.

# 000-default.conf — loaded first due to leading "000" in filename
<VirtualHost *:80>
ServerName _default_
DocumentRoot /var/www/default
<Directory /var/www/default>
Require all denied
</Directory>
</VirtualHost>

Managing Virtual Hosts (Ubuntu)

sudo a2ensite example.com.conf    # Enable
sudo a2dissite example.com.conf # Disable
sudo apache2ctl -S # Summary of all virtual hosts

Production Example: SPA + API Proxy

<VirtualHost *:443>
ServerName app.example.com
DocumentRoot /var/www/react-app/build

SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/app.example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/app.example.com/privkey.pem

<Directory /var/www/react-app/build>
Options -Indexes
AllowOverride None
Require all granted
FallbackResource /index.html # SPA routing support
</Directory>

<FilesMatch "\.(js|css|png|jpg|gif|ico|woff2)$">
Header set Cache-Control "max-age=31536000, public, immutable"
</FilesMatch>

ProxyPreserveHost On
<Location "/api/">
ProxyPass http://127.0.0.1:8080/api/
ProxyPassReverse http://127.0.0.1:8080/api/
</Location>
</VirtualHost>

Summary

VirtualHost TypeDifferentiatorKey Setting
Name-basedHost header (ServerName)<VirtualHost *:80> + ServerName
Port-basedlisten portListen 8080 + <VirtualHost *:8080>
SSL/SNIServerName + certificateDifferent cert per domain on same port
Default serverNo matchAdd 000 prefix to filename for first loading
Advertisement