Apache HTTP Server course

Apache sites-available Directory and Virtual Host Configuration

Learn how Debian and Ubuntu Apache use sites-available and sites-enabled to manage virtual hosts, default sites, activation, validation, reloads, and troubleshooting.

On Debian- and Ubuntu-style systems, Apache stores per-site virtual-host configuration files in /etc/apache2/sites-available. These files describe websites that Apache could serve, but a file is not active merely because it exists in this directory.

To serve a site, place its configuration in sites-available, enable it so Apache loads it through /etc/apache2/sites-enabled, validate the configuration, and reload Apache.

What the sites-available Directory Does

/etc/apache2/sites-available is a Debian-family Apache layout convention. It holds available per-site configuration files, usually with names ending in .conf. Each file commonly contains one or more VirtualHost definitions.

Think of this directory as a library of configuration candidates. Apache does not normally activate every file stored there. The enabled configuration is represented separately in /etc/apache2/sites-enabled.

Debian and Ubuntu organize Apache configuration into directories such as sites-available, sites-enabled, conf-available, and conf-enabled. Other operating systems, packages, containers, or source-built Apache installations may use different directories and include paths. Always inspect the configuration for the specific installation instead of assuming this layout exists everywhere.

Related Apache directories

PathPurposeWhether it makes a site activeTypical contents
/etc/apache2/sites-availableStores available virtual-host definitions.No, not by itself.Files such as example.test.conf and 000-default.conf.
/etc/apache2/sites-enabledContains enabled site references loaded by the Debian/Ubuntu include structure.Yes, when Apache successfully loads the configuration.References to files in sites-available.
/etc/apache2/ports.confDefines listening ports, such as HTTP port 80 and HTTPS port 443.No; it controls listening, not a complete site definition.Listen directives.
/var/www/htmlCommon default document root.No; it is content, not site activation.Default HTML files and other web content.

For broader configuration structure, see Apache2 configuration files, conf-available, and conf-enabled.

What Is an Apache Virtual Host?

A virtual host is an independently configured website or endpoint served by one Apache installation. One server can host multiple sites, each with its own document root, hostname, logs, access rules, TLS settings, redirects, proxy behavior, or application settings.

A typical HTTP request arrives at an IP address and port. Apache then examines the requested hostname, normally supplied in the HTTP Host header, and selects the matching name-based virtual host. For HTTPS, the TLS Server Name Indication value also helps Apache select the certificate and secure virtual host before the encrypted HTTP request is processed.

In name-based virtual hosting, several hostnames can share the same IP address and port:

example.test       -> /var/www/example.test
shop.example.test  -> /var/www/shop.example.test

The hostnames must resolve to the server, and the request must reach the address and port used by the virtual host. If no enabled virtual host matches the hostname, Apache uses the default virtual host for that address and port.

Contents of a Virtual-Host File

A virtual-host definition is enclosed in a VirtualHost container. The address-and-port binding in the opening tag tells Apache which incoming listener the definition applies to. The common form <VirtualHost *:80> means the host applies to port 80 on the server's available addresses.

<VirtualHost *:80>
    ServerName example.test
    ServerAlias www.example.test
    DocumentRoot /var/www/example.test

    <Directory /var/www/example.test>
        Require all granted
    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/example.test-error.log
    CustomLog ${APACHE_LOG_DIR}/example.test-access.log combined
</VirtualHost>

Common directives

DirectivePurposeExample useCommon mistake
VirtualHostGroups settings for a particular address and port.<VirtualHost *:80>Using a port Apache does not listen on, or leaving the container unclosed.
ServerNameSets the primary hostname for the site.ServerName example.testUsing a hostname that does not match the request.
ServerAliasAdds other hostnames handled by the same virtual host.ServerAlias www.example.testForgetting an alternate hostname or DNS record.
DocumentRootSets the filesystem directory from which primary content is served.DocumentRoot /var/www/example.testPointing to a nonexistent or unintended directory.
DirectorySets access control and behavior for a filesystem location.<Directory /var/www/example.test>Using a URL path instead of a filesystem path.
Require all grantedAllows access under Apache 2.4 authorization rules.Place it inside the applicable Directory block.Assuming it fixes Unix filesystem permissions.
ErrorLogSpecifies where this virtual host's errors are recorded.${APACHE_LOG_DIR}/example.test-error.logUsing a directory Apache cannot write to.
CustomLogSpecifies the access log and its format..../example.test-access.log combinedMisplacing the log format or confusing access and error logs.

A Directory block applies to a filesystem path, including the document root. Require all granted authorizes Apache to serve the resource, but the operating system must also allow Apache to traverse parent directories and read files.

Site files may also contain redirects, reverse-proxy rules, TLS configuration, rewrite rules, and PHP or application-specific settings when the relevant modules and application design require them. Keep unrelated global settings in the appropriate Apache configuration files where possible.

The Default Virtual Host

Debian and Ubuntu commonly provide a file named 000-default.conf. Its usual purpose is to provide a fallback HTTP virtual host. A simplified version might look like this:

<VirtualHost *:80>
    DocumentRoot /var/www/html

    <Directory /var/www/html>
        Require all granted
    </Directory>
</VirtualHost>

The conventional default document root is /var/www/html, although an administrator can change it. The default host receives requests for its address and port when no more specific enabled host matches the requested hostname.

The 000- prefix is meaningful because enabled configuration files are commonly loaded in lexical order. Numeric naming causes this file to be considered before names such as example.test.conf. The exact result still depends on the enabled files, address and port bindings, and Apache's virtual-host selection rules.

Do not remove or disable the default site automatically. If you disable it, make sure another suitable virtual host is enabled to handle unmatched requests.

How sites-enabled Activates a Site

/etc/apache2/sites-enabled contains the site entries that Apache loads through the standard Debian/Ubuntu configuration hierarchy. An enabled entry normally refers to a source file in sites-available, commonly through a symbolic link created by a helper command.

This separation lets you keep a site definition available without serving it. Enabling or disabling a site changes the loaded set without requiring deletion of the source file.

Safe Site Configuration Workflow

  1. Create or edit a descriptive file in /etc/apache2/sites-available, such as example.test.conf.
  2. Set the correct ServerName, any ServerAlias values, the DocumentRoot, access rules, and logs.
  3. Check that the document-root directory exists and that Apache can traverse and read it.
  4. Enable the site with a2ensite.
  5. Validate the complete Apache configuration before reloading.
  6. Reload Apache so workers apply the valid configuration.
  7. Test using the intended hostname, not only the server's IP address.
  8. Keep configuration under version control or make a backup before significant changes.

Enable a site

sudo a2ensite example.test.conf
sudo apachectl configtest
sudo systemctl reload apache2

a2ensite activates the named configuration by creating the appropriate enabled reference. It does not guarantee that the configuration is syntactically valid, that DNS is correct, or that Apache has already applied the change. A successful syntax check should precede the reload.

Disable a site

sudo a2dissite example.test.conf
sudo apachectl configtest
sudo systemctl reload apache2

a2dissite removes the enabled reference but normally leaves the source file in sites-available. Disabling 000-default.conf can change how unmatched requests are handled, so confirm that another deliberate fallback virtual host is enabled first.

Validation and Inspection Commands

GoalCommandResultFollow-up action
Enable a sitesudo a2ensite example.test.confCreates or activates the enabled reference.Run apachectl configtest, then reload.
Disable a sitesudo a2dissite example.test.confRemoves the enabled reference.Validate and reload.
Validate configurationsudo apachectl configtestChecks syntax and loadability; successful output commonly says Syntax OK.Fix reported file and line errors before reload.
List loaded virtual hostssudo apachectl -SShows loaded virtual hosts, bindings, ordering, and configuration sources.Check hostname matching and the default host.
Reload Apachesudo systemctl reload apache2Applies valid configuration without a full stop and start.Test the site and inspect logs if needed.
Check service statussudo systemctl status apache2Shows service state and recent failure information.Read the journal for more detail.

Syntax checking detects misspelled directives, malformed containers, invalid contexts, missing included files, and other load-time problems. It cannot prove that the correct hostname resolves to this server or that application behavior is correct.

sudo apachectl -S
sudo systemctl status apache2
sudo journalctl -u apache2 -b

For log formats and log locations, see Apache access and error logs. For HTTPS-specific virtual hosts, see configuring SSL on Apache.

Troubleshooting Common Problems

The file exists but the site is not served

  • The site may not be enabled.
  • Apache may not have been reloaded.
  • The request hostname may not match ServerName or ServerAlias.
  • DNS or the local hosts file may point to another server.

Check the enabled entry, run sudo apachectl -S, confirm name resolution, and test with the expected hostname and Host header.

Apache refuses to reload

  • A directive may be misspelled or invalid in its context.
  • A VirtualHost or Directory block may not be closed.
  • A required module or included file may be unavailable.
  • A filesystem path may be malformed.

Run sudo apachectl configtest and follow the reported filename and line number. Then inspect sudo journalctl -u apache2 -b and the Apache error log.

The default site appears instead of the intended site

  • The hostname does not match the intended ServerName or ServerAlias.
  • The intended site is disabled.
  • The request reaches a different address or port.
  • The fallback virtual host is handling an unmatched hostname.

Use apachectl -S to inspect mappings and default selection. You can inspect the HTTP hostname sent by a client with:

curl -H 'Host: example.test' http://SERVER_IP/

Also verify DNS records and any reverse proxy or load-balancer routing.

The site returns 403 Forbidden

  • The Directory block may not authorize access.
  • Unix ownership or execute permissions may prevent Apache from traversing the path.
  • Another access-control rule may deny the request.

Review authorization rules, check permissions on the document root and every parent directory, and read the site-specific error log.

The site returns 404 Not Found

  • DocumentRoot may point to the wrong directory.
  • The expected index file may be absent.
  • An alias, rewrite rule, or application router may change the requested path.

Confirm the document-root contents, inspect DirectoryIndex and rewrite settings, and review the access and error logs.

Exam-Relevant Notes

  • sites-available stores candidates; sites-enabled represents active site references.
  • Creating a file in sites-available does not activate it.
  • a2ensite enables a site, while a2dissite disables it without normally deleting the source file.
  • Run apachectl configtest before reloading.
  • Use apachectl -S to inspect loaded virtual hosts, bindings, ordering, and default selection.
  • The Host header is central to HTTP name-based virtual-host matching.
  • Require all granted controls Apache authorization; it does not replace Unix filesystem permissions.
  • 000-default.conf commonly provides the fallback site and often uses /var/www/html.

To build a complete site from scratch, continue with creating a new Apache virtual host. You can also review the sites-enabled directory and the ports.conf file.