Configure nginx with two php-fpm fastcgi_pass locations - php

For wordpress site using nginx + php-fpm I'm interested in applying a longer fastcgi_read_timeout directive just to /wp-admin directory to avoid timeouts for time intensive admin tasks.
The only issue with the code sample below is when I visit http://webpage.org/wp-admin I get 404. When I visit http://webpage.org/wp-admin/index.php the page posts.
Using nginx add-header directive to help me debug I've been able to determine that when visiting http://webpage.org/wp-admin nginx chooses location ~ .php$ over location ^~ /wp-admin.
Any ideas on how to resolve this? Thanks
location ^/wp-admin/.*.(php|phps)$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;
fastcgi_keep_conn on;
fastcgi_read_timeout 120;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;
fastcgi_keep_conn on;
}

I tested change to try_files directive suggested by Keenan Lawrence which resolved issue for me.
Helpful explanation of nginx try_files directive can be found here: how can i make this try_files directive work?
To troubleshoot this problem I used add_header directive, placing one directive in each location. Then with Chrome browser I opened Developer Tools, clicked on Network tab, clicked on Record Network Log, then loaded the test wp-admin/ page. There is a Header tab that you can then click on to verify where your page loaded. Also see https://serverfault.com/questions/404626/how-to-output-variable-in-nginx-log-for-debugging
Working configuration below that includes header directives for debug.
location ~* ^/wp-admin/.*.(php|phps)$ {
add_header X-debug-message "This page processed from location ^~ /wp-admin . uri = $uri ." always;
try_files $uri $uri/ =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;
fastcgi_keep_conn on;
fastcgi_read_timeout 120;
}
location ~ \.php$ {
add_header X-debug-message "This page processed from location ~ \.php uri = $uri ." always;
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;
fastcgi_keep_conn on;
}

Related

Nginx configuration for Wordpress running along side Symfony

I have two applications:
a wordpress site at /var/www/html/wordpress
a symfony application at /var/www/html/symfony.
The wordpress application is running as the main domain (domain.com).
I want to achieve the following behavior:
a user visits URL domain.com/example1
nginx redirects to the Symfony route /example1.
With my current config nginx already redirects to the Symfony app.
It loads the wordpress site and its admin dashboard correctly.
Issue:
nginx returns the Symfony home page (/) instead of /example1.
The URLs domain.com/example1 and domain.com/example2 loads the Symfony homepage instead of its corresponding route created in the Symfony app.
My nginx configuration:
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name domain.com;
server_tokens off;
root /var/www/html/wordpress;
index index.php index.html index.htm;
index index.html index.htm index.php;
client_max_body_size 500M;
# charset utf-8;
location / {
# CUSTOM
satisfy any;
charset utf-8;
allow 1.1.1.0/32;
deny all;
try_files $uri $uri/ /index.php?$query_string;
}
### start test
location ^~ /example1 {
satisfy any;
allow 1.1.1.0/32;
deny all;
index index.php;
alias /var/www/html/symfony/current/public/;
try_files $uri $uri/ /index.php?$query_string;
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
#fastcgi_pass 127.0.0.1:9000;
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
location ^~ /example2 {
satisfy any;
allow 1.1.1.0/32;
deny all;
index index.php;
alias /var/www/html/symfony/current/public/;
try_files $uri $uri/ /index.php;
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
#fastcgi_pass 127.0.0.1:9000;
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
location ~ ^((?!\/example1).)*$ { #this regex is to match anything but `/example1`
satisfy any;
allow 1.1.1.0/32;
deny all;
index index.php;
root /var/www/html/wordpress;
try_files $uri $uri/ /index.php?$request_uri;
#try_files $uri $uri/ /index.php?do=$request_uri;
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
#fastcgi_pass 127.0.0.1:9000;
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
### end test
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
access_log off;
error_log /var/log/nginx/domain.com-error.log error;
error_page 404 /index.php;
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
# CUSTOM
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;
internal;
}
location ~ /\.(?!well-known).* {
deny all;
}
You're potentially overriding the fastcgi_* parameters with the defaults in the file fastcgi_params after setting them.
Instead of:
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
# the following line loads defaults from file `fastcgi_params`
include fastcgi_params;
Move the include directive after fastcgi_pass and fastcgi_split_path_info but before setting SCRIPT_FILENAME like this:
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
include fastcgi_params;
# the following fastcgi_* parameters override the defaults in file `fastcgi_params`
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

Nginx with worpress as sub-directory returning 404 in posts

After adding various configurations into the Wordpress subdirectory, I can access without any issues the WP homepage, but I'm still not able to access the posts, returning 404.
www.test.com/blog - WP homepage, works perfectly fine
www.test.com/blog/test-post-for-blog - WP Post, 404
Here is the config:
server {
listen 80;
listen [::]:80;
server_name www.test.com;
location ^~ /media {
alias /var/local/test/static/media;
}
location ^~ /icons {
alias /var/local/test/static/icons;
}
location /blog {
alias /var/www/html;
index index.html index.htm index.php;
try_files $uri $uri/ /blog/index.php?$args /blog/index.php?q=$uri&$args;
# try_files $uri $uri/ /blog/index.php?q=$uri$args;
location ~ \.php$ {
try_files $uri =404;
include fastcgi_params;
fastcgi_intercept_errors on;
fastcgi_index index.php;
fastcgi_pass blog-test:9000;
fastcgi_split_path_info ^(/blog)(/.*)$;
fastcgi_param SCRIPT_FILENAME $request_filename;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
}
}
And the log:
2022/02/09 14:47:25 [error] 32#32: *45 open() "/etc/nginx/html/index.php" failed (2: No such file or directory), client: 10.10.10.10, server: www.test.com, request: "GET /blog/test-post-for-blog/ HTTP/1.1", host: "www.test.com", referrer: "https://www.test.com/blog/"
10.10.10.10 - admin [09/Feb/2022:14:47:25 +0000] "GET /blog/test-post-for-blog/ HTTP/1.1" 404 187 "https://www.test.com/blog/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.87 Safari/537.36"
Checking the logs, it seems to look into the wrong place, which is /etc/nginx/html/index.php, but if I add the alias in the php location block, then the homepage will stop working as well, which gets me a bit confused.
Currently, I'm not quite sure if the problem is the alias in the blog block ( nginx recommends not using alias together with try_files, apparently due to a bug ), or anything else. If it is indeed the alias directive, I'll try to add root, together with some rewrite rules to avoid modifying the file structure.
It really took me more than it should to figure it out, and still can not actually understand what might be the issue here.
UPDATE 1 :
This is extremely odd. With the following blog config, separating the php location from the blog, the WP posts are accesible, but not the homepage and admin, returning 404:
location /blog {
alias /var/www/html;
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
alias /var/www/html;
try_files $uri =404;
include fastcgi_params;
fastcgi_intercept_errors on;
fastcgi_index index.php;
fastcgi_pass blog-test:9000;
fastcgi_split_path_info ^(/blog)(/.*)$;
fastcgi_param SCRIPT_FILENAME $request_filename;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
UPDATE 2 :
Now this works ( the blog and the posts can be accesed ) , but the admin seems to be going into a redirect loop:
location /blog {
alias /var/www/html;
index index.php;
try_files $uri $uri/ /blog/index.php?q=$uri&$args;
}
location ~ \.php$ {
alias /var/www/html;
try_files $uri $uri/ /index.php?$args;
include fastcgi_params;
fastcgi_intercept_errors on;
fastcgi_index index.php;
fastcgi_pass blog-test:9000;
fastcgi_param SCRIPT_FILENAME $request_filename;
}
UPDATE 3 & FIX :
This apparently works, but the config seems to be really unpleasant and unoptimised. If I try to nest the php location into the blog block, then the php files will download instead of rendering. If I try to use alias instead of root, some pages will not show resulting in 404. In any case, this seems to be functional:
root /var/www/html;
index index.php;
location /blog {
rewrite ^/blog(.*)$ /$1 break;
try_files $uri $uri/ /blog/index.php?$args;
}
location ~ \.php$ {
rewrite ^/blog(.*)$ $1 break;
fastcgi_pass blog-test:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_split_path_info ^(/blog)(/.*)$;
fastcgi_param SCRIPT_FILENAME $request_filename;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
Outside the /blog dir you might also have php files. There should be a separate block for the wordpress install that has the same settings, but then for the blog dir.
This could be the block for wordpress (tested in Docker)
location /blog {
try_files $uri $uri/ /blog/index.php?$args;
location ~ \.php$ {
fastcgi_split_path_info ^/blog/(.+\.php)(/.+)$;
fastcgi_pass wp:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
}
}
So your complete nginx config would look like this:
server {
listen 80;
listen [::]:80;
server_name www.test.com;
root /var/www/html;
index index.php;
location ^~ /media {
alias /var/local/test/static/media;
}
location ^~ /icons {
alias /var/local/test/static/icons;
}
# This is for Wordpress
location /blog {
try_files $uri $uri/ /blog/index.php?$args;
location ~ \.php$ {
fastcgi_split_path_info ^/blog/(.+\.php)(/.+)$;
fastcgi_pass wp:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
}
}
# This is for php files in the root. If there is no php to be parsed there you could leave these blocks out.
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass wp:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
}
}
UPDATE: I added a root and index property to the nginx server config.
UPDATE 3 & FIX :
This apparently works, but the config seems to be really unpleasant and unoptimised. If I try to nest the php location into the blog block, then the php files will download instead of rendering. If I try to use alias instead of root, some pages will not show resulting in 404. In any case, this seems to be functional:
root /var/www/html;
index index.php;
location /blog {
rewrite ^/blog(.*)$ /$1 break;
try_files $uri $uri/ /blog/index.php?$args;
}
location ~ \.php$ {
rewrite ^/blog(.*)$ $1 break;
fastcgi_pass blog-test:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_split_path_info ^(/blog)(/.*)$;
fastcgi_param SCRIPT_FILENAME $request_filename;
fastcgi_param PATH_INFO $fastcgi_path_info;
}

nginx: how to serve /index.php of subfolders?

I have a legacy php websiste that has been migrated to a new server with nginx (and php 7.4)
My nginx has near only this
server {
listen 80;
server_name domain.tld;
root /var/www/domain.tld;
error_log /var/log/nginx/domain.tld-error.log warn;
access_log /var/log/nginx/domain.tldt-access.log combined;
client_body_buffer_size 10M;
client_max_body_size 10M;
location / {
try_files $uri /index.php?$args;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/run/php/php7.4-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
}
}
If I access to mydomain.tld it works, it serves correctly mydomain.tld/index.php
but If I access mydomain.tld/subfolder or mydomain.tld/subfolder/ it doesn't serve mydomain.tld/subfolder/index.php as I expect
What am I doing wrong?
I resolved modifiying the suggestion of Daniel W
I moved the location / block under location ~ \.php$
But instead of remove the initial / I prepended also $uri
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/run/php/php7.4-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
}
location / {
index index.php;
try_files $uri $uri/index.php?$args;
}
If I will find some pitfalls I will update my answer

Nginx try_files for php file

I have nginx configuration
location / {
try_files $uri $uri/ /index.php?q=$uri&$args;
}
location ~ \.php$ {
try_files $uri /index.php?q=$uri&$args;
include conf.d/php-fpm.inc;
}
it works when i access mysite.com/nonexistent_file.ext, showing the content of index.php
but, accessing mysite.com/nonexistent_file.php (with ending php), show nginx 404 page.
Please help crafting the try_files rule for php file. Thank you.
UPDATE, conf.d/php-fpm.inc contains
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
Update:
Solved by removing location tag inside the conf.d/php-fpm.inc file.
Thank you everyone.

Laravel Nginx Query String Parameters

I'm using Laravel 5.2 and Nginx and works fine on my development server.
For example:
http://example.com/results?page=2
Development Server
LengthAwarePaginator::resolveCurrentPage(); // returns 2
Paginator::resolveCurrentPage(); // returns 2
$request->input('page'); // returns 2
But in production server
LengthAwarePaginator::resolveCurrentPage(); // returns 1
Paginator::resolveCurrentPage(); // returns 1
$request->input('page'); // returns null
Production Server Configuration
server {
listen 80 ;
listen [::]:80 default_server ipv6only=on;
root /usr/share/nginx/html/laravel/public;
index index.php index.html index.htm;
# Make site accessible from http://localhost/
server_name example.com www.example.com;
location / {
try_files $uri $uri/ /index.php;
}
location #rewrite {
rewrite ^(.*)$ /index.php?_url=$1;
}
location ~ \.php$ {
try_files $uri $uri/ /index.php$is_args$args;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/var/run/php5-fpm.sock;
include /etc/nginx/fastcgi_params;
}
}
Development Server Configuration
server {
listen 80;
server_name example.com;
client_max_body_size 50M;
root /var/www/html/laravel/public;
index index.html index.htm index.php;
try_files $uri $uri/ #rewrite;
add_header 'Access-Control-Allow-Origin' '*';
location #rewrite {
rewrite ^(.*)$ /index.php?_url=$1;
}
location ~ \.php$ {
fastcgi_pass unix:/run/php/php5.6-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PHP_VALUE "upload_max_filesize=52428800 \n post_max_size=53477376 \n memory_limit=536870912";
fastcgi_param APPLICATION_ENV development;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
What changes should I make in server nginx configuration?
Any help appreciated!
Resolved!
I needed to make some corrections as there were two fastcgi_pass in location ~ \.php$ {} so had to change
location ~ \.php$ {
try_files $uri $uri/ /index.php$is_args$args;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/var/run/php5-fpm.sock;
include /etc/nginx/fastcgi_params;
}
To
location ~ \.php$ {
try_files $uri $uri/ /index.php$is_args$args;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/var/run/php5-fpm.sock;
include /etc/nginx/fastcgi_params;
}
and modify try_files in location / {} hence had to change
location / {
try_files $uri $uri/ /index.php;
}
To
location / {
try_files $uri $uri/ /index.php?$query_string;
}

Categories