2

I am trying to serve laravel from a /location block in a Ubuntu nginx virtual host configuration. I have the laravel application installed and working fine when accessed directly but the nginx location block seems like not doing what it is expected to do.

This works : https://www.madol.example.com/horizontal-laravel/public/index.php

This doesn't (403): https://www.madol.example.com/horizontal-laravel/

Note: Real address omitted.

Main snippets which might be wrong:

root /var/www/madol.example.com;
server_name madol.example.com www.madol.example.com;
location /horizontal-laravel {
    try_files $uri $uri/ /horizontal-laravel/public/index.php;
}

Here is the full code from my config file-

server {

     root /var/www/madol.example.com;
     index index.php index.html;

     server_name madol.example.com www.madol.example.com;

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

     location ~ \.php$ {
            fastcgi_pass unix:/run/php/php7.2-fpm.sock;
            include snippets/fastcgi-php.conf;
     }

     **# Something wrong here?**
     location /horizontal-laravel {
           try_files $uri $uri/ /horizontal-laravel/public/index.php;
     }

     location ~*  \.(jpg|jpeg|png|gif|svg|ico|css|js)$ {
            expires 7d;
}

     listen [::]:443 ssl; # managed by Certbot
     listen 443 ssl; # managed by Certbot
     ssl_certificate /etc/letsencrypt/live/madol.madcoderz.com/fullchain.pem; # managed by Certbot
     ssl_certificate_key /etc/letsencrypt/live/madol.madcoderz.com/privkey.pem; # managed by Certbot
     include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
     ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}

server {
     if ($host = www.madol.example.com) {
            return 301 https://$host$request_uri;
     } # managed by Certbot

     if ($host = madol.example.com) {
            return 301 https://$host$request_uri;
     } # managed by Certbot


     listen 80;
     listen [::]:80;
     server_name madol.example.com www.madol.example.com;
     return 404;
} # managed by Certbot

Is there any other config issues apart from this in the code?

RP McMurphy
  • 704
  • 8
  • 30
  • Do you want `/horizontal-laravel/` to find `/horizontal-laravel/public/index.php`? Because that's not what you have at the moment. The `index` directive is looking for a file at `/horizontal-laravel/index.php` and not finding anything. – Richard Smith Feb 17 '19 at 16:35
  • @RichardSmith Yes! That is where I would like it to go to. Also could you please explain why this current code not working? I have another config with Codeigniter and this is working- location /steller-color { try_files $uri $uri/ /steller-color/index.php; } I want https://www.madol.example.com/horizontal-laravel/ to go to /horizontal-laravel/public/index.php file. – RP McMurphy Feb 17 '19 at 16:58

1 Answers1

1

The index directive is looking for a file at /var/www/madol.example.com/horizontal-laravel/index.php and not finding anything.

The simplest solution is to expand the index directive to look for index.php within the public folder. See this document for details.

For example:

location /horizontal-laravel {
    index index.php public/index.php index.html;
    ...
}

Alternatively, you could stop index processing for this location by removing the $uri/ file term from the try_files directive. See this document for details.

For example:

location /horizontal-laravel {
    try_files $uri /horizontal-laravel/public/index.php;
    ...
}

You could explicitly redirect this one URI with a rewrite...last statement. See this document for details.

location = /horizontal-laravel/ { 
    rewrite ^ /horizontal-laravel/public/index.php last; 
}
location /horizontal-laravel {
    ...
}

Finally, you could redesign the URI scheme to eliminate the /public/ bit from being exposed. This is probably best achieved using an alias directive. You will need a nested location to execute the PHP scripts under the new root.

For example:

location ^~ /horizontal-laravel {
    alias /var/www/madol.example.com/horizontal-laravel/public;
    if (!-e $request_filename) { rewrite ^ /horizontal-laravel/public/index.php last; }

    location ~ \.php$ {
        if (!-f $request_filename) { return 404; }
        fastcgi_pass unix:/run/php/php7.2-fpm.sock;
        include snippets/fastcgi-php.conf;
        fastcgi_param SCRIPT_FILENAME $request_filename;
    }
}

Notice that the if directives and SCRIPT_FILENAME uses $request_filename to obtain the path to the local file. You will need to check what is inside snippets/fastcgi-php.conf to ensure it doesn't break anything.

Using try_files with alias is problematic due to this issue. See this caution on the use of if.

Richard Smith
  • 45,711
  • 6
  • 82
  • 81
  • Hi @Richard, I read the docs you linked and tried all the solutions one by one and the last one worked. Thank you. Any ideas why the previous ones didn't work? I am just worried if there are other problems in the configuration which will cause the server break in future. – RP McMurphy Feb 17 '19 at 18:13
  • Did you clear the browser cache between each configuration change? I did test each approach, but the last solution would be my preference. – Richard Smith Feb 17 '19 at 18:19
  • Hi @Richard, also I find the internal links started giving 404 with the last solution though the root address works, for example https://www.madol.example.com/horizontal-laravel/chart/chartJs whereas previously link mapping for the same page was https://www.madol.example.com/horizontal-laravel/public/index.php/chart/chartJs which worked. Any fix for the internal links? I am just worried if there are other problems in the configuration which will cause the server break in future. Didn't clean browser cache though as I wasn't aware that could be the issue. – RP McMurphy Feb 17 '19 at 18:22
  • If your internal links use the `/public/` element in the URI, you should perhaps avoid the last solution. – Richard Smith Feb 17 '19 at 20:02