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

Source: https://srvscripts.com/guides/directadmin-custom-document-root/
Updated: 2026-10-21
Publisher: srvScripts (https://srvscripts.com/)

**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`.

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…

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

| Situation | What 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 domain | The pointer’s virtual hosts got the same custom DocumentRoot |
| HTTP and HTTPS | Both virtual hosts changed; both served the new folder after the reload |
| da build rewrite_confs | Ran in 2.8 seconds, restarted Apache, the custom root stayed |
| |SDOCROOT| in a custom entry | Still 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 "
