zozo6015
zozo6015

Reputation: 577

nginx configure /folder run from a different path than the /

I am having an issue running /folder from a different path than the main website.

my nginx.conf for that section look like this:

        location ~ \.php$ {
            try_files               $uri = 404;
            fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_param       SCRIPT_FILENAME $request_filename;
            fastcgi_pass            unix:/var/run/php/php7.2-fpm.sock;
            fastcgi_index           index.php;
           include                 fastcgi_params;
            include                 fastcgi.conf;
    }


location ~ /folder {
        alias /srv/http/folder;
    try_files $uri $uri/ @folder;

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

location @folder {
    rewrite /folder/(.*)$ /folder/index.php?/$1 last;
}

In the error.log I can see the following:

2020/06/03 09:05:26 [error] 25966#25966: *1 FastCGI sent in stderr: "Primary script unknown" while reading response header from upstream, client: 172.21.2.46, server: example.com, request: "GET /folder/xxx_v6.15.11/Resources/images/redcaplogo.gif HTTP/1.1", upstream: "fastcgi://unix:/var/run/php/php7.2-fpm.sock:", host: "example.com"

Any suggestion how to fix this?

Upvotes: 0

Views: 1983

Answers (1)

Ivan Shatsky
Ivan Shatsky

Reputation: 15470

Regex locations are matched from first to last, and the first found match processed by nginx. When you get a request for /folder/script.php, it is processed by the first location block. Try to swap this two locations. Additionaly, why are you do not include fastcgi_params in your second location block?

Update

I did some debugging, lets look at you code (assuming location block already swapped):

location ~ /folder {
    alias /srv/http/folder;
    try_files $uri $uri/ @folder;

    location ~ \.php$ {
        fastcgi_param  SCRIPT_FILENAME $request_filename;
        fastcgi_pass   unix:/var/run/php/php7.2-fpm.sock;
        include        fastcgi_params;
        include        fastcgi.conf;
    }
}

location ~ \.php$ {
    try_files               $uri =404;
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    fastcgi_param           SCRIPT_FILENAME $request_filename;
    fastcgi_pass            unix:/var/run/php/php7.2-fpm.sock;
    fastcgi_index           index.php;
    include                 fastcgi_params;
    include                 fastcgi.conf;
}

location @folder {
    rewrite /folder/(.*)$ /folder/index.php?/$1 last;
}

If we get a request /folder/some/path (and there is no some/path file or directory inside the folder), inside the nested location internal nginx variables would have following values:

  • $request_filename: empty string (there is no real file or folder /some/path inside th folder directory);
  • $uri: /folder/check.php;
  • $document_root: /srv/http/folder.

If we get a request /folder/some/path/script.php (and there is a real PHP script with this name), inside the nested location internal nginx variables would have following values:

  • $request_filename: /srv/http/folder/some/path/script.php;
  • $uri: /folder/some/path/check.php;
  • $document_root: /srv/http/folder.

Additionally, when you get a request for a static resource from your folder, for example /folder/some/path/static.css, the try_files $uri ... directive will search folder/some/path/static.css file in a /srv/http/folder directory, which leads to check the existence of /srv/http/folder/folder/some/path/static.css file.

One of possible solutions to get a file subpath inside the folder directory:

location ~ ^/folder(?<subpath>.*) {
    alias /srv/http/folder;
    try_files $subpath $subpath/ @folder;

    location ~ \.php$ {
        fastcgi_param  SCRIPT_FILENAME $document_root$subpath;
        fastcgi_pass   unix:/var/run/php/php7.2-fpm.sock;
        include        fastcgi_params;
        include        fastcgi.conf;
    }
}

location ~ \.php$ {
    try_files               $uri =404;
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    fastcgi_param           SCRIPT_FILENAME $request_filename;
    fastcgi_pass            unix:/var/run/php/php7.2-fpm.sock;
    fastcgi_index           index.php;
    include                 fastcgi_params;
    include                 fastcgi.conf;
}

location @folder {
    rewrite ^/folder/(.*)$ /folder/index.php?/$1 last;
}

This could be simplified if your real folder directory name is the same as your /folder URI prefix:

location ~ ^/folder {
    root /srv/http;
    try_files $uri $uri/ @folder;

    location ~ \.php$ {
        fastcgi_param  SCRIPT_FILENAME $document_root$uri;
        fastcgi_pass   unix:/var/run/php/php7.2-fpm.sock;
        include        fastcgi_params;
        include        fastcgi.conf;
    }
}

...

As nginx documentation states:

When location matches the last part of the directive’s value:

location /images/ {
  alias /data/w3/images/;
}

it is better to use the root directive instead:

location /images/ {
  root /data/w3;
}

Upvotes: 1

Related Questions