Recommended Free Tools
To move an Nginx web root, copy the site files to the new directory, change the active server block’s root directive, check any location-specific overrides, test the configuration, and reload Nginx. Keep the old directory until you have verified the home page, a nested asset, and an application route.
Need a server to try this on? Antihost offers Linux VPS plans with NVMe storage, full root access and a 14-day free trial.
A typical migration changes root /var/www/html; to something such as root /srv/my-site/html;. Nginx then maps each request URI beneath that filesystem directory. A 403 after the move usually means a parent directory cannot be traversed, a file is not readable by the worker account, a symlink target is inaccessible, or mandatory access control is blocking access.
As an Amazon Associate I earn from qualifying purchases.
What changes when you move the root?
Nginx’s root directive defines the filesystem base for a server or location. For a request such as /images/logo.svg, Nginx appends that URI to the configured root. With root /srv/my-site/html;, the expected file is therefore /srv/my-site/html/images/logo.svg.
The move affects only the path Nginx uses to find content. Your DNS records, domain name, listening port, TLS configuration, index directive, and application handlers can remain unchanged unless your site’s design requires otherwise. The important exception is a nested location block: a more-specific location can define its own root or alias and bypass the server-level setting.
#1 Best Overall
Before you start
- Have shell access with permission to read the current site and write the destination.
- Know which Nginx server block answers the hostname you are testing.
- Choose a destination on a mounted filesystem that will be available after reboot.
- Keep enough free space for a complete copy, including hidden files and symlink targets that live inside the site.
- Plan a short verification window. A reload applies the new configuration without intentionally stopping the running service, but a bad configuration must be corrected before it can be loaded.
Do not delete or rename the old root first. Keeping it intact provides an immediate rollback path and lets you compare a failing request with the previous layout.
1. Find the active configuration
Editing the wrong file is one of the most common causes of a move appearing to have no effect. Linux packages often use an /etc/nginx hierarchy, while source builds and other operating systems may use a different configuration path.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Ubuntu and Debian-style layouts
On Ubuntu, the default site is commonly enabled through /etc/nginx/sites-enabled/default, with the editable file in /etc/nginx/sites-available/. The enabled file may be a symlink. Inspect both the link and the server block before changing anything:
ls -l /etc/nginx/sites-enabled/
sudo sed -n '1,220p' /etc/nginx/sites-enabled/default
If your domain uses a separate file, search the enabled configuration for the hostname and current root:
sudo grep -RInE 'server_name|root[[:space:]]' /etc/nginx
Other installations
Ask the installed binary which configure arguments were compiled into it. The output includes the compiled configuration path:
nginx -V 2>&1 | awk -F: '/configure arguments/ {print $2}'
Use the reported --conf-path and any included files to trace the server block that is actually loaded. The file you edit must be included by the main configuration; an unused file in another directory will not change live traffic.
2. Create the destination and copy the site
The destination can be anywhere Nginx can access. Ubuntu’s server documentation demonstrates /srv/my-site/html as a valid web-root location:
Rank #2
sudo mkdir -p /srv/my-site/html
Copy the existing document-root contents, including dotfiles. The trailing /. form below means “copy the contents” rather than creating an extra html directory inside the destination:
sudo cp -a /var/www/html/. /srv/my-site/html/
The archive option preserves ordinary ownership, modes, timestamps, and symlinks. For a production site, also account for extended attributes and any deployment metadata your system uses. If a symlink points outside the old root, confirm that its target remains present and accessible from the new arrangement; copying the link does not copy its external target.
After copying, compare the trees and check for hidden files:
sudo find /var/www/html -maxdepth 2 -printf '%M %u:%g %p -> %ln' | sort | less
sudo find /srv/my-site/html -maxdepth 2 -printf '%M %u:%g %p -> %ln' | sort | less
The exact comparison command is optional; the essential check is that the destination contains the same entry point, asset directories, upload directories, and application files required by the site.
3. Make the new path traversable and readable
Nginx needs execute (traverse) permission on every parent directory and read permission on files it serves. The worker account also needs permission to follow symlinks and read the target directories. A directory can look readable while still producing 403 because one parent directory denies traversal.
Ubuntu’s basic example uses a recursive 755 mode for the sample web root:
sudo chmod -R 755 /srv/my-site/html
Use that only when it matches your security model. Recursive 755 grants read and traverse access broadly and may be inappropriate for private uploads, configuration files, or application data. A safer deployment commonly separates public files from secrets, assigns ownership deliberately, and grants write access only to the process that needs it. Do not place database passwords or private keys under a directory intended for direct HTTP serving.
Rank #3
Inspect the complete path when diagnosing access:
namei -l /srv/my-site/html/index.html
This shows permissions on each parent component. Check the Nginx worker account used by your distribution and make sure it can read the requested file. If your system enforces SELinux, AppArmor, or another mandatory-access-control policy, the policy may need to be updated for the new path. There is no single command that applies to every distribution; consult that operating system’s policy tooling and audit logs rather than disabling the control.
4. Change the server block
Open the active server-block file and replace the old root line. Keep the existing index directive and application handlers unless you have a separate reason to change them.
server {
listen 80;
server_name example.com www.example.com;
root /srv/my-site/html;
index index.html index.htm;
location / {
try_files $uri $uri/ =404;
}
}
The semicolon is required. Avoid changing unrelated directives during the migration; limiting the edit makes validation and rollback easier.
How the example resolves requests
| Request | Filesystem lookup with the example root | Result with try_files |
|---|---|---|
/ |
/srv/my-site/html/, then the configured index file |
Serves the index if present; otherwise follows the location’s normal directory handling |
/about.html |
/srv/my-site/html/about.html |
Serves the file when it exists |
/assets/app.css |
/srv/my-site/html/assets/app.css |
Serves the stylesheet when it exists |
/missing |
/srv/my-site/html/missing |
Returns 404 when neither a file nor directory exists |
5. Audit location, alias, and fallback rules
Changing the server-level root is not enough if a more-specific location supplies another path. Review every location block, especially those handling static assets, uploads, PHP or other application handlers, and single-page-application fallbacks.
Windows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallCrashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minuteSpecific locations can override the root
server {
root /srv/my-site/html;
location / {
try_files $uri $uri/ =404;
}
location /uploads/ {
root /var/lib/my-site;
}
}
In this example, a request for /uploads/photo.jpg is resolved under the location’s root rather than the server-level root. Decide whether that separate storage path is intentional. If it is not, remove or update the override.
try_files uses the current root or alias
try_files checks candidate paths using the root or alias in effect for that location. A fallback such as try_files $uri $uri/ /index.html; must point to an index file that exists in the new layout. If the fallback still names a file that was not copied, application routes will fail even though the home page works.
When alias is the right tool
root appends the complete request URI to its configured path. alias replaces the matching location prefix with the alias path. Use alias when the URI prefix should not appear in the filesystem path.
Rank #4
| Directive | URI-to-filesystem behavior | Typical use | Details to recheck |
|---|---|---|---|
root /srv/my-site/html; |
Appends the entire URI | Whole-site document root | Parent permissions, index handling, and nested location overrides |
location /images/ { alias /data/site-images/; } |
Replaces the matched /images/ prefix |
Mapping a URL prefix to a differently named directory | Trailing slashes, exact location matching, and whether the alias path is a file or directory |
Trailing-slash details matter with directory aliases. Test both the directory URL and a file beneath it, and keep the slash conventions consistent between the location and alias declarations. Do not replace a straightforward site-wide root with multiple aliases unless the URI-to-filesystem mapping genuinely requires it.
Do these 3 things before closing this tab:
1Scan for outdated or missing drivers - takes under a minute2Repair Windows errors before they cause bigger problems3Fix the driver behind crashes, sound loss and screen glitches6. Validate before reloading
Always test the complete configuration first:
sudo nginx -t
A successful test reports that the syntax is valid and the configuration test succeeded. If it fails, read the filename and line number in the error, correct that file, and run the test again. Do not reload a configuration that has not passed.
Once the test succeeds, reload Nginx:
sudo systemctl reload nginx
Use the equivalent service-manager command on systems that do not use systemd. Reloading applies the new workers while avoiding an intentional full stop. It does not copy files, repair permissions, or change a server block that is not included.
7. Verify real requests
Test more than the home page. A root move can leave one location or one asset directory pointing at the old tree.
- Request the site root and confirm the expected index document is returned.
- Request a representative nested static file, such as a stylesheet, image, or JavaScript bundle.
- Request an application route that depends on
try_filesor another fallback. - Check a path served by every special location, including uploads or API handlers.
- Confirm the response status, content, and redirects from the intended server block and hostname.
For a local check, send the correct Host header when several sites share an address:
The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →curl -I -H 'Host: example.com' http://127.0.0.1/
curl -I -H 'Host: example.com' http://127.0.0.1/assets/app.css
Use HTTPS and the public hostname when TLS, redirects, or a reverse proxy are part of the path. A successful response from localhost alone does not prove that the public virtual host selected the same server block.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Why Nginx returns 403 after the move
Parent directory traversal is denied
Every directory in /srv/my-site/html must be traversable by the Nginx worker account. Use namei -l on the exact file and correct the restrictive parent rather than granting broad permissions to the entire filesystem.
Best Value
The file or symlink target is unreadable
Check the mode and owner of the requested file. A copied symlink can point to an old location, a path outside the new root, or a target that the worker account cannot read. Confirm the target exists and test its permissions separately.
A mandatory-access-control rule rejects the new path
SELinux, AppArmor, or another policy can deny access even when Unix modes look correct. Inspect the relevant audit or denial logs and assign an approved label or profile rule for the new location. Do not assume that changing mode bits resolves a policy denial.
A directory has no index and listing is disabled
If a request ends at a directory and no configured index file exists, Nginx may reject it rather than list contents. Confirm that the destination contains the expected index file and that the index directive still names it.
When the old content is still served
The request selected another server block
Nginx chooses a server block using the listen address, port, and hostname. A test using an unexpected hostname can therefore reach a different root. Check server_name values and send the intended Host header while testing.
A nested location still points to the old path
Search for every root and alias, not just the first one you see. A more-specific location wins for matching requests and can continue serving a subset of files from the old directory.
A deployment symlink or mount still targets the old tree
Some deployments expose a stable path through a symlink or mounted release directory. Inspect the link target and mount arrangement. Update the deployment pointer deliberately, then retest the representative URLs.
Free tools Windows power users keep installed
One-click scans. No signup required.
The configuration was edited but not loaded
Run sudo nginx -t, reload successfully, and check the service status. If the reload failed, the running workers may still be using the prior configuration. A file outside the compiled or included configuration path has no effect.
Reading logs when a request fails
Nginx’s access and error logs are the first diagnostic tools when behavior is unexpected. The access log tells you which URI and status code were received; the error log often identifies permission failures, missing files, redirect loops, or an upstream problem.
sudo tail -f /var/log/nginx/access.log /var/log/nginx/error.log
Log locations can be customized in the configuration, so use the paths declared by your active access_log and error_log directives. Reproduce one failing request while watching the logs, then correlate its timestamp and URI with the filesystem path you expect Nginx to use.
Rollback plan
- Keep
/var/www/htmlor the original root untouched until verification is complete. - Restore the previous
rootline in the active server block. - Run
sudo nginx -tto verify the reverted configuration. - Run
sudo systemctl reload nginx. - Confirm the original representative URLs work, then investigate the destination copy, permissions, location overrides, or policy rules before attempting the migration again.
Once the new root has served all required traffic successfully and you have a separate backup, remove the old directory only according to your retention and rollback policy. Deleting it immediately removes your simplest recovery option.
Quick wins for a faster PC:
Scan for outdated or missing drivers - takes under a minuteDriver Scan →Clear out junk files and repair common Windows errorsFree Scan →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Quick Recap
Migration checklist
- Identify the compiled and included Nginx configuration path.
- Identify the server block for the hostname being tested.
- Create the destination directory.
- Copy all site content, preserving required ownership, modes, symlinks, and extended attributes.
- Check parent-directory traversal and file readability for the Nginx worker account.
- Change the server-level
rootdirective. - Audit nested
locationblocks,aliasdirectives, andtry_filesfallbacks. - Run
sudo nginx -t. - Reload Nginx only after a successful test.
- Test the root URL, a nested asset, an application route, and every special location.
- Use access and error logs for any 403, 404, or unexpected content.
- Retain the old root until verification and rollback needs have passed.
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

