287

I'm looking to serve the root url of a subdomain and directory of a subdomain to two different folders on my server. Here is the simple set-up that I have and is not working...

server {

    index index.html index.htm;
    server_name test.example.com;

    location / {
            root /web/test.example.com/www;
    }

    location /static {
            root /web/test.example.com/static;
    }
}

In this example going to test.example.com/ would bring the index file in /web/test.example.com/www

and going to test.example.com/static would bring the index file in /web/test.example.com/static

6 Answers 6

325

You need to use the alias directive for location /static:

server {

  index index.html;
  server_name test.example.com;

  root /web/test.example.com/www;

  location /static/ {
    alias /web/test.example.com/static/;
  }

}

The nginx wiki explains the difference between root and alias better than I can:

Note that it may look similar to the root directive at first sight, but the document root doesn't change, just the file system path used for the request. The location part of the request is dropped in the request Nginx issues.

Note that root and alias handle trailing slashes differently.

Sign up to request clarification or add additional context in comments.

9 Comments

He doesn't need alias. Please, read the official docs, not the community wiki filled by users. Quote: When location matches the last part of the directive's value it is better to use the root directive.
This worked for me except that it's missing a trailing slash. The alias should read: alias /web/test.example.com/static/;
@VBart the docs do say exactly what you quote them as saying, but they don't justify that instruction at all - it seems like an arbitrary style choice. Do you see any logical reason behind it?
Just need to remember... as i just found out ... alias = "REPLACE" root = "APPEND"
@elysch yes, if you had /static and root /root/ the path would be /root/static/ if you had /static and an alias /root/ the path would be /root/ only. The initial path would be completely replaced.
|
142

The Location directive system is

Like you want to forward all request which start /static and your data present in /var/www/static

So a simple method is separated last folder from full path , that means

Full path : /var/www/static

Last Path : /static and First path : /var/www

location <lastPath> {
    root <FirstPath>;
}

So lets see what you did mistake and what is your solutions

Your Mistake :

location /static {
    root /web/test.example.com/static;
}

Your Solutions :

location /static {
    root /web/test.example.com;
}

2 Comments

This looks like a rather SEVERE limitation on Freedom To Do What I Want. I want URIs starting with a certain path to be served from a directory that doesn't contain that URI path in its physical file path. With this solution, I am FORCED to put my documents on disk under a path that ends with "/static". I don't like this at all. I want absolute and complete freedom of putting the files wherever I want.
@SzczepanHołyszewski then use the "alias" directive
61
server {

    index index.html index.htm;
    server_name test.example.com;

    location / {
        root /web/test.example.com/www;
    }

    location /static {
        root /web/test.example.com;
    }
}

https://nginx.org/en/docs/http/ngx_http_core_module.html#root

3 Comments

what's the different with asked?
@Wooden the difference: root /web/test.example.com; instead of root /web/test.example.com/static;. nginx maps the path specified by location to the diretory tree and since the path and the source directory share the same name, it works with root.
This format is discouraged. Better to have a parent root under server. See Nginx config pitfalls.
18

A little more elaborate example.

Setup: You have a website at example.com and you have a web app at example.com/webapp

...
server {
  listen 443 ssl;
  server_name example.com;

  root   /usr/share/nginx/html/website_dir;
  index  index.html index.htm;
  try_files $uri $uri/ /index.html;

  location /webapp/ {
    alias  /usr/share/nginx/html/webapp_dir/;
    index  index.html index.htm;
    try_files $uri $uri/ /webapp/index.html;
  }
}
...

I've named webapp_dir and website_dir on purpose. If you have matching names and folders you can use the root directive.

This setup works and is tested with Docker.

NB!!! Be careful with the slashes. Put them exactly as in the example.

2 Comments

Works like a charm. Thanks, also for the good explanation!
I was getting 404 errors when refreshing nested URLs (e.g. /webapp/feature-one): this solved the issue. Thanks.
2

If you use this, I will suggest you set up this command too.

location /static/ {
    proxy_set_header Host $host/static; // if you change the directory and the browser can't find your path
    alias /web/test.example.com/static/;
}

Comments

2

If you want to check two different directories for the same URI use this config:

server {
...
    root /var/www/my-site/public/;
...
    index index.php index.html index.htm;
...
    location / {
        root /var/www/old-site/dist/;
        try_files $uri $uri/ /index.php$is_args$args;
    }
...
}

If Nginx couldn't find file in /var/www/old-site/dist/ directory, then it will try file in /var/www/my-site/public/ directory, but as we said to Nginx to try files with $uri $uri/ /index.php$is_args$args patterns, so Nginx will try /index.php$is_args$args in /var/www/my-site/public/ directory. not $uri

If you want to complete your fallthrough, then replace /index.php$is_args$args with /fallthrough$uri and then add the location /fallthrough { ... } with the alias key to your target directory.

https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/#root-inside-location-block

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.