Emergency server help: get in touch

DirectAdmin Custom Document Root for One Domain (Laravel public Folder, Tested)

Set a custom document root such as a Laravel public folder for one DirectAdmin domain, keep subdomains on their own folders, and verify it. Tested on DirectAdmin 1.712.

Published Updated 5 min read

Short answer: In DirectAdmin 1.712, set a DirectAdmin custom document root for a domain with a custom HTTPD entry such as |*if SUB=""| |?DOCROOT=/home/USER/domains/example.com/public_html/app/public| |*endif|. The SUB="" condition matters: without it every subdomain of the domain is served from the same folder too. Domain pointers follow the new root, and the change survives da build rewrite_confs.

Laravel, Symfony and many other frameworks want the web server to serve only their public folder, so the rest of the application (including .env) is never reachable from a browser. DirectAdmin has no per-domain “document root” field for the main domain, but a DirectAdmin custom document root is possible: the custom HTTPD configuration can override the |DOCROOT| token. We tested the override, its side effects on subdomains and pointers, and how long it takes to apply.

Before you start

  • Create the target folder first and give it to the user. If the folder does not exist, Apache only warns and the site returns 404.
  • Know whether the domain has subdomains or domain pointers (aliases). Both are affected, as shown below.
  • Keep copies of what you are about to change, so you can compare and undo (commands below).
mkdir -p /home/USER/domains/example.com/public_html/app/public
chown -R USER:USER /home/USER/domains/example.com/public_html/app
U=/usr/local/directadmin/data/users/USER
cp -p $U/httpd.conf /root/httpd.conf.USER.before
grep -n "DocumentRoot" $U/httpd.conf
[ -e $U/domains/example.com.cust_httpd ] && cp -p $U/domains/example.com.cust_httpd /root/example.com.cust_httpd.before

Set the DirectAdmin custom document root

As admin, open Custom HTTPD Configurations, choose the domain and add the lines below to the editable box. DirectAdmin stores them in /usr/local/directadmin/data/users/USER/domains/example.com.cust_httpd; in our test we wrote that file directly (owner diradmin:diradmin), which has the same effect.

|*if SUB=""|
|?DOCROOT=/home/USER/domains/example.com/public_html/app/public|
|*endif|

|?DOCROOT=...| sets the token that every virtual host template uses for DocumentRoot. |*if SUB=""| limits the change to the main domain. Then rewrite the user’s web server config:

da taskq --run "action=rewrite&value=httpd&user=USER"
httpd -t && systemctl reload httpd

The rewrite queues an Apache reload, which ran about a minute later on our server. Until then Apache kept serving the old folder. Reloading yourself applies it immediately, and the && makes sure Apache is only reloaded when httpd -t passes.

What else the override changes

SituationWhat we saw on DirectAdmin 1.712
Line without |*if SUB=""|The subdomain blog.example.com was also served from app/public (the DirectAdmin 1.710 changelog warns about this)
Line inside |*if SUB=""|Only the main domain changed; the subdomain kept its own folder
Domain pointer (alias) on the domainThe pointer’s virtual hosts got the same custom DocumentRoot
HTTP and HTTPSBoth virtual hosts changed; both served the new folder after the reload
da build rewrite_confsRan in 2.8 seconds, restarted Apache, the custom root stayed
|SDOCROOT| in a custom entryStill rendered the standard public_html path, not the override

If a subdomain needs its own custom root, use its name in the condition, for example |*if SUB="api"|.

Verify

grep -A3 "ServerAlias www.example.com" /usr/local/directadmin/data/users/USER/httpd.conf | grep DocumentRoot
echo "<?php echo 'docroot-ok';" > /home/USER/domains/example.com/public_html/app/public/check.php
curl -s https://example.com/check.php
rm /home/USER/domains/example.com/public_html/app/public/check.php

Each DocumentRoot line for the domain should show app/public and the request should print docroot-ok. Also check that files outside public are not served: a request for /.env should return 404, because that path now maps inside public.

Undo it

Remove only these three lines in Custom HTTPD Configurations; any other custom entries for the domain stay. Or, from the shell, put back the copy you saved before you started (if there was no .cust_httpd file then, delete the one you created). Then rewrite and reload as before:

U=/usr/local/directadmin/data/users/USER
cp -p /root/example.com.cust_httpd.before $U/domains/example.com.cust_httpd   # or: rm $U/domains/example.com.cust_httpd
da taskq --run "action=rewrite&value=httpd&user=USER"
httpd -t && systemctl reload httpd
grep -n "DocumentRoot" $U/httpd.conf     # compare with the copy in /root/httpd.conf.USER.before

The domain goes back to public_html. The app folder and its files are not touched.

How we tested

  • Server: DirectAdmin 1.712 on AlmaLinux 9.8 with Apache 2.4 (CustomBuild), Let’s Encrypt staging certificates, 19–20 October 2026.
  • Domain with one alias pointer and one subdomain; custom entry written with and without |*if SUB=""|; each step checked in the generated httpd.conf, with httpd -t and with HTTP and HTTPS requests.
  • 21 October 2026: the backup, gated reload and undo commands above re-run as published on the same server.
  • Not tested: nginx, nginx with Apache behind it, OpenLiteSpeed and LiteSpeed. With nginx in front, static files are served by nginx, which has its own custom configuration, so check it separately.
  • Related: the DOCROOT token change in DirectAdmin 1.710 and www.sub.example.com not working after 1.710.

FAQ

Does a domain pointer use the custom document root too?

Yes. On our 1.712 server the alias pointer’s HTTP and HTTPS virtual hosts got the same custom DocumentRoot as the domain.

Why did my subdomains start showing the main site?

The custom |?DOCROOT=| line applies to every virtual host of the domain, subdomains included. Wrap it in |*if SUB=""| and rewrite the config.

Why does the new document root not work straight away?

The rewrite only queues an Apache reload. On our server it ran about a minute later; run httpd -t and systemctl reload httpd to apply it at once.

Does the custom document root survive DirectAdmin updates?

It survived da build rewrite_confs, which regenerates every user’s config. We did not test a DirectAdmin version update itself.

At a glance

DirectAdmin Custom Document Root for One Domain (Laravel public Folder, Tested) summary card: In DirectAdmin 1.712, set a DirectAdmin custom document root for a domain with a custom HTTPD entry such as |*if SUB=""| |?DOCROOT=/home/USER/d…
In short: In DirectAdmin 1.712, set a DirectAdmin custom document root for a domain with a custom HTTPD entry such as |*if SUB=""| |?DOCROOT=/home/USER/domains/example.com/public_html/app/public| |*endif|. The SUB="" condit…

Share this guide

Free website test

Is your website set up right?

Check SSL, security headers, redirects, robots.txt, sitemap, llms.txt and security.txt in one test. It takes about 30 seconds.