6

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!!

Community
  • 1
  • 1
mformigo
  • 65
  • 2
  • 2
  • 7

2 Answers2

6

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 /

Richard Smith
  • 45,711
  • 6
  • 82
  • 81
  • 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). – mformigo Dec 12 '16 at 10:02
  • 2
    It needs to be placed after your `location ~ \.php$` block. See [this document](http://nginx.org/en/docs/http/request_processing.html) 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`. – Richard Smith Dec 12 '16 at 10:14
  • 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!! – mformigo Jan 12 '17 at 14:30
  • 1
    Your understanding is correct for prefix locations, however, regular expression locations are evaluated in order until a match is found. – Richard Smith Jan 12 '17 at 15:43
0

Try something along the lines of:

location ~ ^/microsite/(?<foo>.+)$ {
    try_files $uri $uri/;
    root /microsite/$foo;
}
alindt
  • 682
  • 5
  • 11
  • 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. – mformigo Dec 12 '16 at 10:08