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
| Path | Purpose | Whether it makes a site active | Typical contents |
/etc/apache2/sites-available | Stores available virtual-host definitions. | No, not by itself. | Files such as example.test.conf and 000-default.conf. |
/etc/apache2/sites-enabled | Contains 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.conf | Defines listening ports, such as HTTP port 80 and HTTPS port 443. | No; it controls listening, not a complete site definition. | Listen directives. |
/var/www/html | Common 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
| Directive | Purpose | Example use | Common mistake |
VirtualHost | Groups settings for a particular address and port. | <VirtualHost *:80> | Using a port Apache does not listen on, or leaving the container unclosed. |
ServerName | Sets the primary hostname for the site. | ServerName example.test | Using a hostname that does not match the request. |
ServerAlias | Adds other hostnames handled by the same virtual host. | ServerAlias www.example.test | Forgetting an alternate hostname or DNS record. |
DocumentRoot | Sets the filesystem directory from which primary content is served. | DocumentRoot /var/www/example.test | Pointing to a nonexistent or unintended directory. |
Directory | Sets access control and behavior for a filesystem location. | <Directory /var/www/example.test> | Using a URL path instead of a filesystem path. |
Require all granted | Allows access under Apache 2.4 authorization rules. | Place it inside the applicable Directory block. | Assuming it fixes Unix filesystem permissions. |
ErrorLog | Specifies where this virtual host's errors are recorded. | ${APACHE_LOG_DIR}/example.test-error.log | Using a directory Apache cannot write to. |
CustomLog | Specifies the access log and its format. | .../example.test-access.log combined | Misplacing 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
- Create or edit a descriptive file in
/etc/apache2/sites-available, such asexample.test.conf. - Set the correct
ServerName, anyServerAliasvalues, theDocumentRoot, access rules, and logs. - Check that the document-root directory exists and that Apache can traverse and read it.
- Enable the site with
a2ensite. - Validate the complete Apache configuration before reloading.
- Reload Apache so workers apply the valid configuration.
- Test using the intended hostname, not only the server's IP address.
- 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
| Goal | Command | Result | Follow-up action |
| Enable a site | sudo a2ensite example.test.conf | Creates or activates the enabled reference. | Run apachectl configtest, then reload. |
| Disable a site | sudo a2dissite example.test.conf | Removes the enabled reference. | Validate and reload. |
| Validate configuration | sudo apachectl configtest | Checks syntax and loadability; successful output commonly says Syntax OK. | Fix reported file and line errors before reload. |
| List loaded virtual hosts | sudo apachectl -S | Shows loaded virtual hosts, bindings, ordering, and configuration sources. | Check hostname matching and the default host. |
| Reload Apache | sudo systemctl reload apache2 | Applies valid configuration without a full stop and start. | Test the site and inspect logs if needed. |
| Check service status | sudo systemctl status apache2 | Shows 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
ServerNameorServerAlias. - 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
VirtualHostorDirectoryblock 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
ServerNameorServerAlias. - 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
Directoryblock 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
DocumentRootmay 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-availablestores candidates;sites-enabledrepresents active site references.- Creating a file in
sites-availabledoes not activate it. a2ensiteenables a site, whilea2dissitedisables it without normally deleting the source file.- Run
apachectl configtestbefore reloading. - Use
apachectl -Sto inspect loaded virtual hosts, bindings, ordering, and default selection. - The
Hostheader is central to HTTP name-based virtual-host matching. Require all grantedcontrols Apache authorization; it does not replace Unix filesystem permissions.000-default.confcommonly 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.