Nginx dynamic location path configuration

13,114

You probably need to limit the capture to the first two path segments:

location ~ ^(/microsite/[^/]+) {
    try_files $uri $uri/ $1/;
}

The [^/] character class matches anything that is not a /

Share:
13,114
Admin
Author by

Admin

Updated on June 15, 2022

Comments

  • Admin
    Admin almost 2 years

    Firstly I want to state that I'm rather new to nginx, I basically only know what I've learned over the last week.

    That said, I currently have a Nginx server with a standard configuration of:

    server {
      listen 80;
      server_name site.com;
    
      root /var/www/site.com/;
      index index.php;
    
      location / {
        try_files $uri $uri/ /index.php;
      }
    
      location /microsite/first {
        try_files $uri $uri/ /microsite/first/;
      }
    
      location /microsite/second {
        try_files $uri $uri/ /microsite/second/;
      }
    
      ...
    }
    

    This works fine, although for every microsite I add to the existing ones, it requires that a new location be added referring to the path of the new microsite.

    My question is: is it possible to dynamically set the location parameter in a way that it catches and references whatever sub-directory exists within the microsite/ directory?

    e.g. something along the line of the rewrite rule rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 last; (taken from the nginx site) but applied to the location parameter, like:

    location ~ ^/microsite/(.*)$ {
      try_files $uri $uri/ /microsite/$1/;
    }
    

    In which the $1 would catch the sub-directory name passed in (.*)? (I tried this snippet that I built refering to the answer to (another) Nginx dynamic location configuration question, although it did not work)

    Also I'm not a Regex expert, I've tweaked a bit with it in the past but it was a while ago and I don't recall the precise terminology, so that may be part of the problem, perhaps?!

    Anyway, all help is appreciated.
    Thanks in advance!!

  • Admin
    Admin over 7 years
    thank you for your suggestion, but it didn't work. I tried the location block just like you wrote it, but when trying to access the site it just opens up the 'save file' window (downloading the index.php file, which we obviously do not want).
  • Admin
    Admin over 7 years
    thank you also for your feedback, although unfortunately it also did not work.. the location block you shared returned a 500 Internal Server Error. I played a bit with the code to see if I could get it to work, and found out that the 500 was caused by the root /path/$foo line. I also tried putting the $foo variable on the try_files $uri $uri/ /path/$foo (with the root ... line commented out) and it just opens up the 'save file' window.
  • Richard Smith
    Richard Smith over 7 years
    It needs to be placed after your location ~ \.php$ block. See this document for how nginx processes a request. And you may want to make the last element explicitly link to index.php by using $1/index.php.
  • Admin
    Admin over 7 years
    hey Richard, sorry for the absence but i got caught up in another project and just now got back to this issue. and i just want to thank you for you excellent help =) your suggestion did the trick. although for what i understood from the nginx documentation regarding location blocks prioritization, i though the more precise the path the location had configured, the higher it's priority as a server rule!! although that block does have the ~ character before, so.. anyway, i put it after the location ~ \.php$ block as you mentioned and it worked great, so thanks again =D cheers!!
  • Richard Smith
    Richard Smith over 7 years
    Your understanding is correct for prefix locations, however, regular expression locations are evaluated in order until a match is found.