httpd.conf is Apache's primary configuration file — but on any server hosting more than one website, most of the actual day-to-day configuration work happens in separate virtual host files, which httpd.conf is set up to include, rather than being edited directly for every site-specific change.
1. Where httpd.conf lives
# Debian/Ubuntu (Apache is typically split into many included files)
/etc/apache2/apache2.conf
# RHEL/CentOS/Fedora (closer to the traditional single-file layout)
/etc/httpd/conf/httpd.conf
The exact path and structure varies by distribution — Debian-based systems in particular split Apache's configuration across many smaller included files (sites-available/, mods-available/, conf-available/) rather than one large monolithic file, which is a genuinely different organizational philosophy from the more traditional single-file httpd.conf layout still common on RHEL-based systems.
2. What lives in the main config vs. a virtual host file
httpd.conf (or apache2.conf) typically holds server-wide settings — which modules load, global timeout and logging defaults, the base directory structure — while each individual website's specific configuration (its domain name, document root, and site-specific behavior) lives in its own separate virtual host file.
3. A basic virtual host
<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
DocumentRoot /var/www/example.com/public
ErrorLog ${APACHE_LOG_DIR}/example.com-error.log
CustomLog ${APACHE_LOG_DIR}/example.com-access.log combined
</VirtualHost>
A virtual host block is what actually lets one Apache server host multiple, entirely separate websites — ServerName is what Apache matches an incoming request's Host header against to decide which virtual host (and therefore which DocumentRoot) should handle that specific request.
4. Enabling a virtual host on Debian/Ubuntu
sudo nano /etc/apache2/sites-available/example.com.conf
sudo a2ensite example.com.conf
sudo systemctl reload apache2
a2ensite creates a symlink from sites-available into sites-enabled — Apache only actually loads virtual hosts from sites-enabled, so a config file can exist in sites-available without being active until explicitly enabled this way. This split makes it easy to temporarily disable a site (a2dissite) without deleting its configuration.
5. HTTPS virtual hosts
<VirtualHost *:443>
ServerName example.com
DocumentRoot /var/www/example.com/public
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
</VirtualHost>
A separate virtual host block, listening on port 443 instead of 80, is the standard pattern for HTTPS — many setups pair this with a plain port-80 virtual host that only redirects to the HTTPS version, rather than serving real content over an unencrypted connection at all.
6. Testing configuration before reloading
apachectl configtest
# or, on Debian/Ubuntu:
apache2ctl configtest
Running this before a reload catches a syntax error in a virtual host file before it takes down the running server — reloading Apache with a broken configuration file can stop it from restarting at all, so checking syntax first is genuinely worth the extra step, especially in production.
7. The .htaccess alternative — and why it's usually the slower choice
Directory-level .htaccess files allow some configuration overrides without touching the main server config at all, and are useful on shared hosting where root access to httpd.conf/virtual host files isn't available — but Apache checks for an .htaccess file on every single request when enabled for a directory, which adds real, measurable overhead compared to the same rules defined once in a virtual host block. On a server with full configuration access, virtual host-level configuration is both faster and the generally recommended approach.