0

I'm attempting to configure Nginx to serve both a Django application and a Laravel application. I have the Django application working correctly, so now I'd like get the Laravel application served from /snipe-it.

The main part of the nginx config that I'm struggling with is here:

    location /snipe-it/ {
        alias /var/www/html/public/;
        #try_files $uri $uri/ /index.php$is_args$args;

        location ~* \.php(/|$) {
            try_files $uri $uri/ =404;
            include fastcgi_params;
            fastcgi_pass unix:/run/php/php7.3-fpm.sock;
            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        }
    }

The actual file location of the index.php file is /var/www/html/public/index.php.

When attempting to reach the Laravel app at http://127.0.0.1/snipe-it/index.php, I get "File not found." The log output looks like this:

nginx_1        | - -  24/Jun/2020:17:37:40 +0000 "GET /snipe-it/index.php" 404
nginx_1        | 2020/06/24 17:37:40 [error] 17#17: *1 FastCGI sent in stderr: "Primary script unknown" while reading response header from upstream, client: 172.30.0.1, server: 127.0.0.1, request: "GET /snipe-it/index.php HTTP/1.1", upstream: "fastcgi://unix:/run/php/php7.3-fpm.sock:", host: "127.0.0.1"
nginx_1        | 172.30.0.1 - - [24/Jun/2020:17:37:40 +0000] "GET /snipe-it/index.php HTTP/1.1" 404 27 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:77.0) Gecko/20100101 Firefox/77.0" "-"

Everything is in a docker container that derives from the official nginx image which uses Debian buster. I believe that first line from the logs is from the php-fpm7.3 process since I set access.log to /proc/self/fd/2 in my /etc/php/7.3/fpm/pool.d/www.conf file. I also set catch_workers_output to yes hoping that it might provide more insight into where the application is looking for the index.php file but it doesn't seem to.

If it's helpful, the permissions of index.php looks like this:

-rw-r--r-- 1 docker www-data 1887 Jun 23 21:13 index.php

I'm currently running nginx as the www-data user and php-fpm as the docker user in the www-data group. It seems like the "Primary script unknown" error can be caused by a number of issues so any tips on how I can drill down deeper to find any more clues as to where the problem is would be helpful.

FYI, here's my full nginx conf file:

upstream intranet {
    server web:8000;
}

upstream prometheus {
    server prometheus:9090;
}

server {
    listen 80;
    server_name 127.0.0.1;
    root /var/www/html/public;
    index index.php index.html index.htm;

    location /static {
        alias /home/static;
    }

    location /media {
        alias /home/media;
    }

    # Prometheus settings
    location /prometheus/ {
        proxy_pass http://prometheus;
    }

    location /snipe-it/ {
        alias /var/www/html/public/;

        location ~* \.php(/|$) {
            try_files $uri $uri/ =404;
            include fastcgi_params;
            fastcgi_pass unix:/run/php/php7.3-fpm.sock;
            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        }
    }

    location / {
        proxy_pass http://intranet;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host;
        proxy_redirect off;
    }
}
TechnoConserve
  • 140
  • 1
  • 11
  • 1
    You cannot use `$document_root$fastcgi_script_name` with `alias`. See [this answer](https://stackoverflow.com/questions/42443468/nginx-location-configuration-subfolders/42467562#42467562). – Richard Smith Jun 24 '20 at 19:34

1 Answers1

2

According to nginx ngx_http_fastcgi_module documentation, $fastcgi_script_name internal variable contains request URI or, if a URI ends with a slash, request URI with an index file name configured by the fastcgi_index directive appended to it. When you using

fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

and got a /snipe-it/script.php incoming request, an $uri internal variable is equal to /snipe-it/script.php, $document_root$fastcgi_script_name internal variable is equal to /var/www/html/public/, and concantenated $document_root$fastcgi_script_name string becomes /var/www/html/public//snipe-it/script.php, which is obviously leads to an absent file. What you can do is

    location ~ ^/snipe-it/(?<subpath>.*)$ {
        alias /var/www/html/public/;
        location ~* \.php$ {
            include fastcgi_params;
            fastcgi_pass unix:/run/php/php7.3-fpm.sock;
            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME $document_root$subpath;
        }
    }

Note that this problem does not occur when you use a root directive instead of alias. However, it is not possible unless you rename /var/www/html/public directory to /var/www/html/snipe-it (than you can use root /var/www/html; instead of alias /var/www/html/public/;).

Ivan Shatsky
  • 13,267
  • 2
  • 21
  • 37