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?
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;
}
Related
I need to setup two projects under one domain(react+symfony), here is my nginx config:
server {
listen 80;
server_name domain.ltd;
rewrite_log on;
root /var/www/frontend;
access_log /var/log/nginx/project_access.log;
error_log /var/log/nginx/project_error.log;
location / {
index /index.html;
}
location /api/ {
alias /var/www/backend;
try_files $uri /index.php$is_args$args;
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;
internal;
}
}
}
root / works fine so static index.html I'm getting okay without any issues. but symfony application for /api throws an error(403 Forbidden) in nginx error.log:
32349 open() "/var/www/frontend/index.php"
For some reason alias ignored, what i'm doing wrong?
Thanks in advance
The location and the alias values should both end with a / or neither end with a /. The last parameter of the try_files statement is a URI, so you need to include the /api/ prefix.
For example:
location /api/ {
alias /var/www/backend/;
try_files $uri /api/index.php$is_args$args;
location ~ \.php$ {
try_files $uri =404;
fastcgi_pass 127.0.0.1:9000;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $request_filename;
fastcgi_param DOCUMENT_ROOT $realpath_root;
internal;
}
}
Also, add a try_files statement to the nested location block to avoid passing uncontrolled requests to PHP. The correct value for SCRIPT_FILENAME is $request_filename which works with either root or alias.
server {
listen <...:...>;
server_name <...>;
root /var/www/html/myserver;
location /myproject {
try_files $uri /myproject/web/app.php$is_args$args;
}
location ~ ^/myproject/web/(app_dev|config)\.php(/|$) {
fastcgi_pass <...php-fpm...>;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;
}
location ~ ^/myproject/web/app\.php(/|$) {
fastcgi_pass <...php-fpm...>;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;
internal;
}
location ~ \.php$ {
return 404;
}
}
I can see my project when I trying to go myserver.com/myproject/web
I want access to my project at myserver.com/myproject.
But this url give 404 (in Symfony):
No route found for "GET /myproject/"
I added this rewrite rule in my configuration file but its not working:
rewrite ^/myproject(/|$)$ /myproject/web last;
Your config looks ok except for your root. The other paths should then change:
root /var/www/html/myserver/web;
location / {
...
}
location ~ ^/(app_dev|config)\.php(/|$) {
...
}
location ~ ^/app\.php(/|$) {
...
}
location ~ \.php$ {
...
You can see the NGINX config docs for reference.
If you want to use your existing config, then try this URL:
myserver.com/web
That might work.
I want to override the permissions to /folder/script.php and have the following rules:
location ^~ /folder/script.php{
allow all;
} #shouldn't ^this one with ^~ override the others?
location ~ /folder/(.+)\.php$ {
deny all;
return 404;
allow 127.0.0.1;
}
location ~ ^/folder {
return 404;
}
location / {
# First attempt to serve request as file, then
# as directory, then trigger 404
try_files $uri $uri/ =404;
server_name_in_redirect off;
}
location ~ \.php$ {
try_files $uri =404;
#fastcgi_split_path_info ^(.+\.php)(/.+)$;
# NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
#fastcgi_pass /tmp/php5-fpm.sock;
#fastcgi_pass /var/run/php5-fpm.sock;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $root_folder$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $root_folder;
# send bad requests
fastcgi_intercept_errors on;
include fastcgi_params;
}
but whenever I access admin.php I still get a 404 error and/or the script.php file is served to download, not interpreted. Could someone explain me why? Tyvm
The commands to execute a php script are:
try_files $uri =404;
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME $root_folder$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $root_folder;
fastcgi_intercept_errors on;
include fastcgi_params;
I'm not sure where you define $root_folder, normally $document_root is used. The above (or similar) code must appear in each and every location block that is expected to execute php scripts.
So your configuration should look something like this:
location / {
try_files $uri $uri/ =404;
server_name_in_redirect off;
}
location ^~ /folder { deny all; }
location = /folder/script.php {
try_files $uri =404;
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME $root_folder$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $root_folder;
fastcgi_intercept_errors on;
include fastcgi_params;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME $root_folder$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $root_folder;
fastcgi_intercept_errors on;
include fastcgi_params;
}
I have taken the liberty of simplifying your configuration a little. It seems that only the file /folder/script.php is executable within the /folder hierarchy, so an exact match (location =) is used, and /folder is denied. The allow 127.0.0.1; does nothing as it comes after the deny all.
As you can see, the fastcgi_pass 127.0.0.1:9000; directive must appear in any location container that directly handles php code. I would put some or all of these directives into a separate file and use include to pull them in at each location.
The rest of the directives have been copied across from your question, but I don't know if they are required here.
I am trying to rewrite a url with nginx but its downloading the php file instead of passing it
https://www.example.com/s.php?k=7eqx6si58Mn4fBf8n9oiF9lwIQ%3D%3D&b=5
Need to show as
https://www.example.com/s/7eqx6si58Mn4fBf8n9oiF9lwIQ%3D%3D&b=5
I tried the following but its not working
location ~ ^/s.php(.*)$ {
rewrite ^/s/$ /s.php?k= last;
}
I also have the following location block
location ~* \.php$ {
root /var/www/example.com/public_html/www;
try_files $uri =404;
fastcgi_pass unix:/run/php5-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
How do I make PHP-FPM rules play nicely with Nginx rewrite rules?
Current config file
server {
location / {
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass 127.0.0.1:9000;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_script_name;
include fastcgi.conf;
}
if (!-e $request_filename){
rewrite ^(.*)$ /index.php?routestring=$1 break;
}
rewrite ^/(admincp/)$ /index.php?routestring=$1 break;
}
}
Change your location block to the following. Also try to avoid if statements, read about it (and more) here: http://wiki.nginx.org/Pitfalls
I've replaced the if (!-e ...) part with the #missing block in the config below.
server {
root /your/root/path
index index.php index.html index.htm;
server_name your.domain.com;
rewrite ^/(admincp/)$ /index.php?routestring=$1 break;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to index.php
try_files $uri $uri/ /index.php?$args;
}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
location ~ \.php$ {
# Move to the #missing part when the file doesn't exist
try_files $uri #missing;
# Fix for server variables that behave differently under nginx/$
fastcgi_split_path_info ^(.+\.php)(/.+)$;
# Include the standard fastcgi_params file included with ngingx
include fastcgi_params;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_index index.php;
# Override the SCRIPT_FILENAME variable set by fastcgi_params
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_nam$
# Pass to upstream PHP-FPM; This must match whater you name you$
#fastcgi_pass phpfpm;
fastcgi_pass 127.0.0.1:9000;
}
location #missing {
rewrite ^(.*)$ /index.php?routestring=$1 break;
}
}