4

I'm setting up multiple Laravel apps under subfolders of a single domain (social network apps, need https, single certificate).

Cannot figure out how to write nginx config to map HTTP requests to /app1/ to a Laravel installation under /var/www/other_folder/public/

Here's the latest iteration of config tests. Debug logging omitted. Laravel root location /app1/ works, but mapping of routes (/app1/api/method/) does not. Please help, how to either debug how nginx processes the request step by step (debug log is not that explanatory), or give me a hint how to map subfolders of /app1/... to the index.php of Laravel.

server {
    listen      80;
    server_name  apps.mydomain.com;
    root    /var/www/apps.mydomain.com/docs;

    location /  {
        index   index.html index.php;
    }

    location /app1    {
        alias   /var/www/other_folder/public;
        index   index.php   index.html;
        try_files   $uri  $uri/ /app1/index.php$is_args$args /app1/index.php?$query_string;
    }

    location ~ /app1/.+\.php$ {
        rewrite ^/app1/(.*)$  /$1  break;
        include /etc/nginx/fastcgi.conf;
        fastcgi_param    SCRIPT_FILENAME    /var/www/other_folder/public$fastcgi_script_name;

        fastcgi_index  index.php;
        fastcgi_pass php;

        #   Database access parameters
        fastcgi_param   DB_HOST "localhost";
        fastcgi_param   DB_USER "apps";
        fastcgi_param   DB_PASS "xxxxxxxx";
        fastcgi_param   DB_NAME "app1";
    }

    # Other locations skipped
    include /etc/nginx/global/php.conf; # other php scripts
}
Sergiks
  • 249
  • 3
  • 5
  • 11
  • I had this exact same problem, but didn't investigate any further into it because I was using separate domains. I will take a look at this again tonight and get back to you when I figure it out :) – jaseeey Jan 16 '14 at 22:18

2 Answers2

4

I think you should change the root of the location. According to Nginx documentation, the root directive also has the context "location":

syntax: root path;

context: http, server, location, if in location

So you should be able to do something like the following:

server {
    listen      80;
    server_name  apps.mydomain.com;
    root    /var/www/apps.mydomain.com/docs;

    location /  {
        index   index.html index.php;
    }

    location /app1    {
        root   /var/www/other_folder/public;
        rewrite ^/app1/(.*)$  /$1  break;
        index   index.php   index.html;
        try_files   $uri  $uri/ /index.php$is_args$args /index.php?$query_string;
    }

    location ~ /app1/.+\.php$ {
        root   /var/www/other_folder/public;
        rewrite ^/app1/(.*)$  /$1  break;
        include /etc/nginx/fastcgi.conf;
        fastcgi_param    SCRIPT_FILENAME    $document_root$fastcgi_script_name;

        fastcgi_index  index.php;
        fastcgi_pass php;

        #   Database access parameters
        fastcgi_param   DB_HOST "localhost";
        fastcgi_param   DB_USER "apps";
        fastcgi_param   DB_PASS "xxxxxxxx";
        fastcgi_param   DB_NAME "app1";
    }

    # Other locations skipped
    include /etc/nginx/global/php.conf; # other php scripts
}

As far as I understand, the alias directive remaps an URL to another URL and the processing goes on, it does not define a directory from where to source files. I am unsure whether you still need the rewrite in the PHP location.

  • 1
    `root` would require a `rewrite` in the first section, as it [still appends](http://wiki.nginx.org/HttpCoreModule#root) the folder to the request. – Sergiks Jan 17 '14 at 15:30
  • Yes, you are absolutely right. Fixed the answer. – Fabio Scaccabarozzi Jan 19 '14 at 18:47
  • Hmm, I try to do this, but Laravel still interprets my path as "/app1/index.php/test", which means it is unable to route. Is there something I am missing? The path should be "/test" for it to route correctly. – jaseeey Jan 23 '14 at 05:40
  • My bad, I mistakenly supposed that the PHP location included a try_files directive. Comment the rewrite and try adding this: `try_files $uri $uri/ /app1/index.php$is_args$args;` This line should be used also in the non-PHP location. The rewrite will change the URL nginx is processing, kicking you out of the location. You should try processing what you get instead. If this fails, try looking at fastcgi_split_path_info. – Fabio Scaccabarozzi Jan 27 '14 at 11:56
1

This code is untested. But you're saying it works with /app1/ but not with /app1/api/method/ . I would guess your problem lies in this part:

location /app1    {
    alias   /var/www/other_folder/public;
    index   index.php   index.html;
    try_files   $uri  $uri/ /app1/index.php$is_args$args /app1/index.php?$query_string;
}

so this basically tells to go try the url, and if it doesn't match, try to match it as a directory url/, and if no files and directory exists, then we try to match it as /app1/index.php?someargs, and if it doesn't exists, match it as /app1/index.php?$query_string

First of all, alias and try_files don't work together, so you can use root instead. Change the /app1 location block to the following to see whether it fixes your problem.

location /app1    {
    root   /var/www/other_folder/public;
    index   index.php   index.html;
    try_files $uri $uri/ /index.php$is_args$args;
}

Second, $query_string is the same as $args , the only difference is that it's read-only.

Like I said, this is untested, but it would be nice if it works. And when it doesn't, I still have another idea.

Rowanto
  • 121
  • 1
  • 5