3.1 root vs alias: The Filesystem Mapping, Settled
Two directives, one job: turn a URI into a file path. One appends, one replaces — and every confusion you've ever had reduces to that difference plus a trailing slash.
Basic
What you will learn
The one-line rule separating
rootfromalias.rootin depth: inheritance, nesting, and the path-construction formula.aliasin depth: the trailing-slash law and the regex-capture law.The five classic failures — each reproduced and fixed below.
When neither is the answer (
internal, X-Accel-Redirect preview).
1. The one-line rule
root: final path =<root value> + <entire URI>alias: final path =<alias value> + <URI minus the location prefix>
root says
"this directory is the root of the URL space" — the URI, slashes and all, gets glued to the end.
alias says
"this location is a nickname for that directory" — the matched prefix is cut off and replaced.
Both live in
http/
server/
location;
alias additionally has a regex-powered form that
root lacks. Here is the matrix, live — four URIs, four mappings, all green in the output:
$ for u in /about.html /images/hero.png /downloads/handbook.pdf /dl/handbook.pdf; do
printf '%-28s %s\n' "$u" "$(curl -s -o /dev/null -w '%{http_code} %{content_type}' \
-H 'Host: static.example.test' http://127.0.0.1:8300$u)"
done
/about.html 200 text/html; charset=utf-8
/images/hero.png 200 image/png
/downloads/handbook.pdf 200 application/pdf
/dl/handbook.pdf 200 application/pdf2.
root in depth
Our example server sets
root www/main; once at server level, and — via Lesson 2.5's inheritance — most locations borrow it:
server {
root www/main; # prefix-relative: <prefix>/www/main
location / { } # GET /about.html
location /images/ { } # GET /images/hero.png
}Path construction, mechanically:
GET /images/hero.png
URI: /images/hero.png
root: …//var/www/main (symlink -> /var/www)
final: …/www/main + /images/hero.png = …/www/main/images/hero.png ✓Properties that make
root the default choice:
It inherits. Server-level
root+ silent locations = one mapping for the whole vhost — the flat, obvious arrangement.It's location-order-proof. The full URI survives into the path, so "which prefix matched" doesn't change where files come from; only which other directives apply.
Nested locations keep it. A nested block without its own
rootborrows the outer's — the ladder rule again.
3.
alias in depth
The trailing-slash law
location /downloads/ { # location prefix ENDS with /
alias www/main/docs/; # alias value MUST end with / too
}Because the final path is
alias + (URI − prefix), the slash alignment is mechanical: strip
/downloads/ from the URI, glue the rest onto
www/main/docs/.
GET /downloads/handbook.pdf
URI − prefix: handbook.pdf
alias: …/www/main/docs/
final: …/www/main/docs/handbook.pdf ✓Miss the slash on
either side and you concatenate into a wall:
…/docs +
handbook.pdf =
…/docshandbook.pdf → 404. The matrix above verifies both real files through this mapping (plus a
Content-Disposition: attachment header, because a
downloads/ location that
displays PDFs betrays its own name — Lesson 3.3 covers the header).
The regex-capture law
alias + regex location is where senior engineers sweat. The rule:
with a regex location,
alias
must contain the captures, because there is no fixed prefix to strip. Our working version:
location ~ ^/dl/(?<file>.+)$ {
alias www/main/docs/$file;
}GET /dl/handbook.pdf
capture: handbook.pdf
alias: …/www/main/docs/ + $file
final: …/www/main/docs/handbook.pdf ✓ (200, application/pdf)Omit
$file and NGINX silently serves the
directory — usually a 404 or, with
autoindex inherited, an accidental listing. Two hard-won habits:
Always name the capture (
?<file>not$1) — regexes get edited, and$1renumbering is a silent data-loss bug.Anchor the regex (
^/dl/) — an unanchored~ /dl/would also swallow/old/dl/xand reshape that mapping too.
4. The five classic failures (and their one-glance diagnoses)
Failure 1 — the doubled path segment.
location /images/ { root www/main/images/; } →
/images/hero.png looks for
…/images/images/hero.png. Diagnosis: root
appends; you already had
/images in the URI. Fix:
root www/main; (or use alias).
Failure 2 — the eaten path segment.
location /downloads/ { alias www/main/docs; } (no trailing slash) →
…/docshandbook.pdf. Diagnosis: read the 404 path; the missing separator is visible. Fix: slash on both sides.
Failure 3 — alias inside a regex location without captures. Covered above: silent directory serves. Fix:
$file-style capture.
Failure 4 — root at http level, surprise at server level.
http { root /srv/default; } server { server_name b…; } — b serves from
/srv/default (inherited) while the author "configured nothing". It's not a bug, it's the ladder (Lesson 2.5) — but it's the classic "works on A, 404s on B" fleet mystery. Fix: explicit
root per server, or accept the default consciously.
Failure 5 — symlinked roots and
disable_symlinks
. By default NGINX happily follows symlinks (our example's
www is one!). When a hardened config sets
disable_symlinks on; (or
if_not_owner), all symlinked roots — including
$document_root tricks — start 403ing. Diagnosis: sudden, uniform 403s after a security pass. Fix: real paths or documented exceptions (
disable_symlinks off; where required).
5. When neither is the answer
Two advanced neighbors you'll meet later (previews, not homework):
internal— a location that only internal redirects may reach (Module 11): the protected-file pattern pairsinternalwith X-Accel-Redirect from an app.Variables in
root/alias—root /srv/$site;per-tenant mapping. Legal and fast (the value is computed per request), but it converts your filesystem into an API: validate$site(map/regex) before it ever touches a path. Lesson 15.1's njs work shows a safe shape.
Try it yourself
Reproduce the mapping matrix (§1) and then predict before curling:
/docs/payload.bin(root-mapped),/downloads/payload.bin(alias-mapped) — same file, two doors. Which returns theContent-Dispositionheader? Why?Watch the path-resolver work. Request
/images/absent.pngand read the resolved path from the error log:
tail -1 /var/log/nginx/error.logBuild failure #1 live. Change the images location to
root www/main/images/;, reload, request/images/hero.png, read the doubled path in the 404. Restore.Regex-alias surgery. Add
location ~ ^/repo/(?<pkg>.+)$ { alias www/main/docs/$pkg; }, reload, fetch/repo/handbook.pdf. Then remove$pkgand fetch again — observe the silent wrongness.
Q&A
Q1.
location /static/ { root /srv/web; } — where does
/static/js/app.js resolve?
Answer
/srv/web/static/js/app.js. The full URI (including
/static/) is appended to the root value.
Q2. Same URI under
location /static/ { alias /srv/web/; }?
Answer
/srv/web/js/app.js. The
/static/ prefix is stripped and replaced by the alias.
Q3. Why must a regex location's
alias use captures?
Answer
alias normally works by subtracting the location prefix — but a regex has no fixed character prefix to subtract. Without captures there's nothing to append, so the alias value is used as-is (a directory) or misroutes. The capture is how you carry the variable part of the URI into the path.
Q4. Your 404 error log shows
…/www/main/downloads/handbook.pdf for a request to
/downloads/handbook.pdf in an
alias location. What's wrong?
Answer
Nothing is wrong with the path shape — that's exactly where alias put it. The file is genuinely missing there (or permissions). The lesson: read the resolved path first, decide "mapping bug or missing file" second — this log line says the latter.
Takeaways
rootappends the whole URI;aliasreplaces the matched prefix — everything else is consequences.Prefer
root(it inherits and is order-proof); reach foraliaswhen the URL space and disk layout genuinely disagree.The trailing-slash law (both sides) and the regex-capture law (alias in regex locations must carry captures) prevent the classic failures.
The 404's resolved path in
error.logis free forensics — the fastest root/alias debugging tool you own.disable_symlinkshardening interacts with symlinked roots; our example setup runs on one, which is exactly why it's on this page.
Thanks for your feedback.
Mark this learning resource complete to track your learning progress.