# Location - or how to setup sites in subfolders

**URL:** <https://www.ruby-forum.com/t/location-or-how-to-setup-sites-in-subfolders/219339>\
**Category:** NGINX\
**Created:** [April 29, 2012, 10:06pm UTC](https://www.ruby-forum.com/t/location-or-how-to-setup-sites-in-subfolders/219339 "2012-04-29T22:06:44Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![dubstep](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/cdc98d/32.png) [@dubstep](https://www.ruby-forum.com/u/dubstep)\
**Post date:** [April 29, 2012, 10:06pm UTC](https://www.ruby-forum.com/t/location-or-how-to-setup-sites-in-subfolders/219339/1 "2012-04-29T22:06:44Z")

</div>

I’m trying to give nginx a try as an alternative to my current server  
solutions. Named-based virtual hosting SEEMS straightforward enough -  
but I’m having a devil of a time trying to get subfolder based sites to  
work. In other words -

[egroupware.mydomain.com](http://egroupware.mydomain.com)  
[roundcubemail.mydomain.com](http://roundcubemail.mydomain.com)  
[ldap-account-manager.mydomain.com](http://ldap-account-manager.mydomain.com)

for some examples, work just fine. But trying to get -

[www.mydomain.com/egroupware](http://www.mydomain.com/egroupware)  
[www.mydomain.com/roundcubemail](http://www.mydomain.com/roundcubemail)  
[www.mydomain.com/ldap-account-manager](http://www.mydomain.com/ldap-account-manager)

to work is an exercise in extreme frustration. I’m sure it doesn’t HAVE  
to be - but Google thus far has let me down in retrieving the  
information I need. What I’ve done thus far, for egroupware for  
example:

I have a site file with:  
server {  
server\_name www.amfeslan.local egroupware.amfeslan.local;  
root /opt/egroupware;  
index index.php;

```
 client_max_body_size 8M;
 rewrite ^/egroupware/(.*)$ /$1 last;
 try_files $uri $uri/ /index.php$args;

 include global/php.conf;

```

}

my global/php.conf has:  
location ~ .php$ {  
# There’s gotta be a better way to do this - try and find it.  
# Since nginx’s “best” match is this one - need to do rewrites  
# here to get subfolders to work.  
set $php\_root $document\_root;  
if ($request\_uri ~\* /egroupware) {  
set $php\_root /opt/egroupware;  
}

```
     # Zero-day exploit defense.
     try_files $uri =404;

     fastcgi_split_path_info ^(.+\.php)(/.+)$;

     include fastcgi_params;
     fastcgi_index index.php;
     fastcgi_param SCRIPT_FILENAME $php_root$fastcgi_script_name;
     fastcgi_pass php;

```

}

Note that I tried to add the “if” construct in php.conf based on a  
previous post - and I gotta believe there’s a better way to do this.  
With or without the if construct, the above site works - but only for  
egroupware. Revising the site file to:  
server {  
server\_name www.amfeslan.local egroupware.amfeslan.local;  
root /var/www;  
index index.html;

```
 client_max_body_size 8M;

 location / {
    try_files $uri $uri/ /index.php?$args;
 }

 location ^~ /egroupware {
    root /opt/egroupware;
    index index.php;
    rewrite ^/egroupware/(.*)$ /$1 last;
    try_files $uri $uri/ /index.php$args;
 }

 include global/php.conf;

```

}

## Doesn’t work right. Can some kind soul help me not only fix this - but get a better understanding of how to build these generic constructs? Based on experience with other servers, I can’t believe folder-based controls in nginx can be as difficult as I seem to be making it!

Daniel

---

<div class="post-metadata">

**Author:** ![Daniel\_LSMiller](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/c4cdca/32.png) [@Daniel\_LSMiller](https://www.ruby-forum.com/u/Daniel_LSMiller)\
**Post date:** [April 29, 2012, 10:24pm UTC](https://www.ruby-forum.com/t/location-or-how-to-setup-sites-in-subfolders/219339/2 "2012-04-29T22:24:20Z")

</div>

2012/4/30 Daniel L. Miller [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> include global/php.conf;  
> }
> 
> Doesn’t work right. Can some kind soul help me not only fix this - but get  
> a better understanding of how to build these generic constructs? Based on  
> experience with other servers, I can’t believe folder-based controls in  
> nginx can be as difficult as I seem to be making it!

Put “location ~ .php$ { }” inside each “location ^~ /appname/ { }”  
block instead of globally so it looks like this:

location ^~ /egroupware/ {

# if index.php’s path is /opt/egroupware/index.php,

# use “root /opt” instead

root /opt/egroupware;  
index index.php;

# and remove this

rewrite ^/egroupware/(.\*)$ /$1 last;

# and update this accordingly

try\_files $uri $uri/ /index.php$args;  
location ~ .php($|/) {  
…  
}  
}

Also remember that some applications may need to know that it’s  
running in a subdirectory or it will generate incorrect link (eg.  
/something.php instead of /app/something.php).

---

<div class="post-metadata">

**Author:** ![Daniel\_LSMiller](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/c4cdca/32.png) [@Daniel\_LSMiller](https://www.ruby-forum.com/u/Daniel_LSMiller)\
**Post date:** [April 29, 2012, 11:18pm UTC](https://www.ruby-forum.com/t/location-or-how-to-setup-sites-in-subfolders/219339/3 "2012-04-29T23:18:19Z")

</div>

On 4/29/2012 1:22 PM, Edho A. wrote:

> 2012/4/30 Daniel L. Miller[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):
> 
> > Note that I tried to add the “if” construct in php.conf based on a previous  
> > post - and I gotta believe there’s a better way to do this. With or without  
> > the if construct, the above site works - but only for egroupware.  
> > [..]  
> > root /opt/egroupware;  
> > index index.php;
> 
> # and remove this
> 
> rewrite ^/egroupware/(.\*)$ /$1 last;
> 
> # and update this accordingly
> 
> try\_files $uri $uri/ /index.php$args;  
> location ~ .php($|/) {  
> …  
> }  
> }

Thank you! - that helped quite a bit. That way of thinking - of  
including the php handler inside each location, instead of a global php  
handler, just didn’t seem as “elegant” to me - but I can see the power  
potential.

## However - I still don’t understand WHY it works - specifically, why I need to have “root /opt” instead of “root /opt/egroupware”. I’m inferring that the location path is automatically added to the declared root in processing. But if that’s the case, then to be able to declare, “location ^~ /lam/”, and be able to reach a physical path of “/opt/ldap-account-manager-3.7”, I need to add a symlink from the extended path to “/opt/lam”. And while I may in fact do so for other reasons - I WOULD like to be able to control exactly what nginx is doing, and better yet - understand the how/why.

Daniel
