0

I want to have different sub-websites inside my website, in such a way that each of them matches to a different location.

For example, <website>/game/ should serve stuff from /var/www/<gamePath>, and <website>/<blog> should serve stuff from /var/www/<blogPath>. As a default, <website>/<anything> should serve stuff form /var/www/html/.

My current config looks like this:

server {
 server_name <website>;
 root /var/www/html;

 location / {
   try_files $uri /index.html =404;
 }

 location /game/ {
   root /var/www/<gamePath>/;
   try_files $uri $uri/ /index.html =404;
  }
 
 location /blog/ {
   root /var/www/<blogPath>/;
   try_files $uri $uri/ /index.html =404;
  }
  <ssl stuff>
}

While the default location works, and <website> correctly serves the file /var/www/html/index.html, when I try to do <website>/blog/favicon.ico, it does not serve the favicon, but instead defaults to /var/www/<blogPath>/index.html. It seems that this is because it is appending blog (the location) to the uri, and does it won't match anything.

I have seen many questions around this issue, but no answer has worked for me so far. Some replace the root inside each specific location by alias, but if I do that I only get 404's. Other solutions try rewriting the request instead of using $uri, in order to avoid the location being appended. This seems like the way to go, but I haven't found a regex that actually works (maybe they require trivial modifications that I haven't been able to do myself, as all I've tried is to copy and paste them).

1

nginx root directive works by adding the URI part from the location to the end of file path it tries to serve to the user.

So, in your example, loading /game/example URL makes nginx look up the file /var/www/<gamePath>/game/example.

To make /game/example load /var/www/<gamePath>/example, you need to use following configuration.

location ~ ^/game/(?<filepath>.*)$ {
    root /var/www/<gamePath>/;
    try_files /$filepath /$filepath/ /index.html =404;
}

This tells nginx to capture the string after /game to $filepath variable, which is then used to locate the file.

Another alternative is to use alias instead of root.

5
  • The only comment I have is that now, if I try to access <website>/game/ it does not give me the index.html of the game location but instead the one of the / location. – Bernardo Subercaseaux Sep 15 '20 at 18:00
  • I updated the answer by changing locations of the / characters. Hope it helps. – Tero Kilkanen Sep 15 '20 at 18:06
  • 1
    I suspect just using alias would be a lot cleaner. – Michael Hampton Sep 15 '20 at 19:52
  • That is true. I had the impression of root being faster option here, but with the regex capturing this approach might be slower. – Tero Kilkanen Sep 16 '20 at 6:00
  • @Michael Hampton I tried replacing "root" with "alias" inside the locations but I kept getting 404. – Bernardo Subercaseaux Sep 17 '20 at 20:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.