How to Change the Default Apache Document Root

How to change the default Apache document root

Every time I set up a new deployment pipeline, I end up moving Apache’s document root away from the default /var/www/html — either to match a build output path, a dedicated partition, or a directory structure that supports multiple sites cleanly. It’s a simple change on paper, but I’ve hit the same handful of gotchas often enough that I wanted to write down exactly how I do it.

What Is the Document Root?

The DocumentRoot directive tells Apache which directory on disk maps to the root URL path (/) for a given virtual host. A request for https://example.com/about.html resolves to <DocumentRoot>/about.html on disk.

Prerequisites

  • Apache installed and running
  • Root or sudo access
  • The new target directory ready (or about to be created)
  • Whether SELinux is enforcing on my system (RHEL/CentOS), since that changes the steps I need

I check my current document root first:

apachectl -S | grep -i "port 80"
grep -r DocumentRoot /etc/apache2/sites-enabled/    # Debian/Ubuntu
grep -r DocumentRoot /etc/httpd/conf.d/              # RHEL/CentOS

Step 1: Create the New Directory

sudo mkdir -p /var/www/mysite

I always drop in a test file to confirm the change later:

echo "<h1>New document root is working</h1>" | sudo tee /var/www/mysite/index.html

Step 2: Set Correct Ownership and Permissions

sudo chown -R www-data:www-data /var/www/mysite      # Debian/Ubuntu
sudo chown -R apache:apache /var/www/mysite            # RHEL/CentOS

sudo chmod -R 755 /var/www/mysite

Wrong ownership is, hands down, the most common cause of a “403 Forbidden” I run into right after moving a document root.

Step 3: Update the Virtual Host Configuration

Debian/Ubuntu — I edit the relevant site config, typically /etc/apache2/sites-available/000-default.conf:

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

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

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

RHEL/CentOS — I edit /etc/httpd/conf/httpd.conf or a file under /etc/httpd/conf.d/:

DocumentRoot "/var/www/mysite"

<Directory "/var/www/mysite">
    Options -Indexes +FollowSymLinks
    AllowOverride All
    Require all granted
</Directory>

I always remember the <Directory> block — changing DocumentRoot alone isn’t enough. Apache needs explicit access permission for the new path, or it returns 403 Forbidden even with the filesystem permissions set correctly.

Step 4: Test Configuration and Restart

sudo apachectl configtest
sudo systemctl restart apache2      # or httpd on RHEL

I verify with a quick curl:

curl -I http://localhost/

SELinux Considerations (RHEL/CentOS/Fedora)

On RHEL-based systems with SELinux enforcing, moving the document root outside /var/www blocks Apache from serving files even with correct Unix permissions, because the new directory doesn’t yet have the right SELinux context.

I check SELinux status:

getenforce

Then apply the correct context:

sudo semanage fcontext -a -t httpd_sys_content_t "/var/www/mysite(/.*)?"
sudo restorecon -Rv /var/www/mysite

If semanage isn’t installed:

sudo dnf install policycoreutils-python-utils

I verify the context:

ls -Zd /var/www/mysite

I want to see httpd_sys_content_t in the output.

Moving the Document Root to a Custom Partition

For sites storing a lot of user-uploaded content, I’ve put the document root on a separate mounted volume:

sudo mkdir -p /mnt/webdata/mysite
sudo chown -R www-data:www-data /mnt/webdata/mysite

I update /etc/fstab so the volume mounts automatically at boot, then point DocumentRoot at the mounted path as above. SELinux contexts still apply even on a separate mount, so I don’t skip that step.

Real-World Use Cases

  • Standardizing deployment paths to match a CI/CD pipeline’s expected output directory.
  • Separating application code from static content, with the document root pointing only at a public/ subdirectory (common with PHP frameworks like Laravel).
  • Hosting multiple sites, each with its own document root under a shared parent.
  • Using a dedicated storage volume for high-capacity or high-I/O sites.

Mistakes I’ve Made

  • Changing DocumentRoot but forgetting the matching <Directory> block, ending up staring at a 403 Forbidden.
  • Wrong file ownership after copying files in as root, leaving root-owned files Apache’s less-privileged user can’t read.
  • Forgetting SELinux context on RHEL-based systems, getting 403 Forbidden despite everything else looking right.
  • Leaving the old default document root’s <Directory> block still granting broad access to a directory nobody uses anymore.
  • Skipping apachectl configtest before restarting, which caused downtime once over a syntax typo.

Security Best Practices

  • I never set the document root to a directory containing sensitive files (.git, .env, backups, configs) unless I’ve explicitly denied those specific files via <FilesMatch> rules.
  • Options -Indexes stays on to prevent directory listing of the new root.
  • I stick to least privilege on file ownership — no chmod -R 777 shortcuts.
  • For framework projects with a public/ folder convention, I always point DocumentRoot there, never at the project root, so source code and secrets stay out of reach.

Performance Considerations

  • If I’m moving to network-attached or remote storage, I benchmark I/O latency first — NFS-backed document roots can add noticeable latency under high request volume.
  • Local SSD-backed storage is my preference over network storage for the document root on high-traffic sites.
  • I make sure the new path doesn’t cross filesystem boundaries that complicate FollowSymLinks or Options behavior.

Troubleshooting

403 Forbidden after changing DocumentRoot I check three things in order: filesystem permissions (ls -l), the <Directory> access block for the new path, and SELinux context on RHEL-based systems (ls -Zd).

404 Not Found for all pages I confirm the new directory actually has the expected files and that DocumentRoot points to the correct absolute path — typos happen more often than I’d like to admit.

Old site still loads instead of the new one I make sure I edited the config file that’s actually enabled (a2ensite on Debian/Ubuntu) and reloaded Apache; multiple virtual host files can conflict if I’m not careful.

FAQs

Do I need to restart Apache or is a reload enough? A reload (systemctl reload apache2) is usually enough for DocumentRoot changes and avoids dropping active connections, though a full restart works too.

Can different virtual hosts have different document roots on the same server? Yes — each <VirtualHost> block can define its own DocumentRoot. It’s the standard way I host multiple sites on one Apache instance.

Will changing the document root affect existing .htaccess rules? .htaccess files are read from the directory they physically live in, so as long as I move them along with the site files, they keep working, provided AllowOverride is still enabled for that directory.

Summary and Key Takeaways

  • Changing the document root means updating DocumentRoot, the matching <Directory> access block, filesystem ownership/permissions, and — on RHEL-based systems — the SELinux context.
  • A 403 Forbidden after this change is almost always permissions or access control, not a DNS or network issue.
  • Framework-based apps should point the document root at their public/ directory, never the project root.
  • I always run apachectl configtest before reloading or restarting Apache.

References

  • Apache DocumentRoot Directive: https://httpd.apache.org/docs/current/mod/core.html#documentroot
  • Apache Directory Directive: https://httpd.apache.org/docs/current/mod/core.html#directory
  • Red Hat SELinux and Apache Guide: https://access.redhat.com/documentation/
Total
1
Shares

Leave a Reply

Previous Post
How to configure Apache to use a custom error page

How to Configure Apache to Use a Custom Error Page

Next Post
How to configure Apache to use a different log file format

How to Configure Apache to Use a Different Log File Format

Related Posts