I've directory say mobile
/var/www/mobile
That directory has multiple subdirectories like /android /ios and those directories have multiple PHP files
I'd like to run those PHP files like this
https://www.example.com/mobile/android/index.php
https://www.example.com/mobile/android/products.php
https://www.example.com/mobile/ios/products.php
https://www.example.com/mobile/ios/feeds.php
I want to allow these files in a single location block as many directories may be created in the future and don't want to specify separate location blocks for each directory.
I've added a location block in the config file however it is showing a 404 page.
location ~* ^/mobile($|/) {
root /var/www;
try_files $uri $uri/ /mobile/?q=$uri&$args;
location ~ \.php$ {
#include fastcgi_params;
fastcgi_pass 127.0.0.1:9002;
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
include fastcgi_params;
}
}
Help me with this.
Thank you
Just want to let everyone know before I posted this question I checked
every single thread on stackoverflow about this issue.
The aim:
Run two apps under one domain, first app on the root (/) and second app under the URI (/learn).
http://example.com/ - first app
http://example.com/learn - second app
The problem:
The main app works perfectly, but the learn app is showing a white page with "No input file specified.".
My file structure:
/srv/users/serverpilot/apps/main/public/index.php
/srv/users/serverpilot/apps/learn/public/index.php
My NGINX configuration:
root "/srv/users/serverpilot/apps/main/public";
location ^~ /learn {
root "/srv/users/serverpilot/apps";
try_files $uri /learn/public/index.php?$query_string;
location ~ \.php$ {
add_header X-debug-message $document_root$fastcgi_script_name always;
include fastcgi_params;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/srv/users/serverpilot/run/learn.php-fpm.sock;
}
}
location / {
try_files $uri $uri/ /index.php?$args;
location ~ \.php$ {
include fastcgi_params;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/srv/users/serverpilot/run/main.php-fpm.sock;
try_files $uri =404;
}
}
In addition:
I know the fastcgi_pass sockets are working because I've been
running these two apps under different domains but in the same
server in question.
I added the add_header X-debug-message $document_root$fastcgi_script_name" always; to see what the response header would show, and it shows that the
SCRIPT_FILENAME is
/srv/users/serverpilot/apps/learn/public/index.php which exists and is the exact file I am trying to run.
Oh lordy! What a wild hunt!
Okay the reason this configuration wasn't working is because aside from fastcgi_params you can also set php_value[doc_root] which will overwrite your $document_root which is commonly used in the SCRIPT_FILENAME parameter. So check your php.ini files always to make sure php_value[doc_root] is not set when you have apps that are being served from different directories otherwise it just wont pick them up. In the case that you are just serving a single app from a single directory you need not worry.
I have the following Nginx configuration for forwarding requests to a PHP-FPM backend:
server {
...
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
location ~* \.php$ {
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root/index.php;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
}
}
One specific route in the app needs a slightly longer php max_execution_time setting. I've configured this successfully and verified it works by setting a longer fastcgi_read_timeout in the above config.
However, I don't need this to be applied to every single route. I'm guessing I need a nested location somewhere but nothing I've tried seems to work!
The fastcgi_read_timeout directive does not appear to accept dynamic values, so a separate location block for the special route will be required. Looking at your configuration file, I assume the special route is a unique URI processed by the /index.php script. Something like this should work:
location ^~ /special/route/uri {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root/index.php;
fastcgi_pass 127.0.0.1:9000;
fastcgi_read_timeout 100s;
}
You can use a prefix location with the ^~ modifier (as above) to override the regex location that usually processes PHP files. Alternatively, you can use a regex location, but place it above the existing regex location so that it takes precedence.
See this document for location syntax.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed 7 years ago.
Improve this question
I'm trying to serve CachetHQ in nginx + php-fpm in a specific location. The docs gives this as example that serves in status.example.com (which works):
server {
listen 80;
server_name status.example.com;
root /var/www/Cachet/public;
index index.php;
location / {
try_files $uri /index.php$is_args$args;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_index index.php;
fastcgi_keep_conn on;
}
}
However, instead of serving in status.example.com, I would like to serve in example.com/status.
I was expecting that this would work, but from error.log I see it's trying /etc/nginx/htmlindex.php, but it should be /mnt/data/site/www-cachet/public/index.php:
location /status/ {
index index.php;
root /mnt/data/site/www-cachet/public;
try_files $uri index.php$is_args$args;
location ~ ^/status/.+\.php$ {
root /mnt/data/site/www-cachet/public;
include fastcgi_params;
fastcgi_pass unix:/tmp/php-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_index index.php;
fastcgi_keep_conn on;
}
}
Let me start with the original configuration that you claim works, and try to modify it for your requirements, results below:
location ^~ /status {
alias /var/www/Cachet/public;
index index.php;
location = /status {
return 302 /status/;
}
location / {
try_files $uri /status/index.php$is_args$args;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass 127.0.0.1:9000;
rewrite ^/status/(.*) /$1;
rewrite ^(.*)/ $1/index.php; # who knows what fastcgi_index is for?
fastcgi_param SCRIPT_FILENAME $document_root$uri;
fastcgi_keep_conn on;
}
}
Basically, you want to use alias instead of root here, and probably also have an absolute path in the final try_files as well. I don't think adding extra prefixes within nested locations is needed, but you might want to make sure that the root location is a final match with the ^~ modifier.
The main trick, I guess, is that even with the alias directive things aren't as dandy as with a proper root, so, you have to make sure that the SCRIPT_FILENAME is set correctly. This part doesn't seem to be documented very clearly, and I'm too lazy to test out whether $fastcgi_script_name ngx variable and fastcgi_index directive play nice with alias -- instead of trying to determine how those work (or not), we simply do a couple of rewrite rules as applicable, and construct SCRIPT_FILENAME based on the results of our rewrite rules instead. :-)
However, with that said, I'd think the second rewrite rule (as well as the fastcgi_index it replaces) might as well be a no-op, because how were we supposed to end up in a \.php$ location if $uri didn't end in .php already?
(Likewise, you're free to try to remove the first rewrite rule, too, and replace $uri in SCRIPT_FILENAME with $fastcgi_script_name, and see if things still work, but the internet from 2009 may indicate that they didn't.)
Your try_files is not correct.
You can do it like this:
index index.php;
root /mnt/data/site/www-cachet/public;
location / {
if (!-e $request_filename) {
rewrite ^(.*)$ /index.php?$1 last;
break;
}
}
location ~ ^/status/.+\.php$ {
root /mnt/data/site/www-cachet/public;
include fastcgi_params;
fastcgi_pass unix:/tmp/php-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_index index.php;
fastcgi_keep_conn on;
}
After so many hours trying a lot of combinations, the way I got it working was:
location ^~ /status {
alias /mnt/data/site/www-cachet/public;
try_files $uri $uri/ #status;
location = /status/ {
rewrite /status/$ /status/index.php;
}
location ~ ^/status/(.+\.php)$ {
fastcgi_pass unix:/tmp/php-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /mnt/data/site/www-cachet/public/$1;
include fastcgi_params;
}
}
location #status {
rewrite /status/(.*)$ /status/index.php?/$1 last;
}
The most important thing was fastcgi_param, I had to set it to an absolute path instead of $document_root$fastcgi_script_name or something like it. I'm not sure if it's a good pratice, but adding alias to the block just doesn't work, and neither nginx or FastCGI show us the path of the file they're trying to read.
Nevertheless I couldn't get CachetHQ to work well. Problem is that all paths in source code are absolute, so they won't point to the subdirectory which our files are hosted. The solution was do something that I was reluctant since beginning: host it in a subdomain.
I have .php files in multiple directories (/jobs/marketing/, /jobs/content/ etc) that need to map cleanly to /jobs/name-of-file.php.
For example hitting the url:
/jobs/digital-marketing
needs to map to:
/jobs/marketing/digital-marketing.php
It's safe to assume the file name of each php file is unique across directories.
my current nginx setup is the following:
location /jobs {
expires max;
add_header Cache-Control public;
add_header Pragma public;
rewrite ^/jobs[\/]?$ /marketing/jobs.php last;
location ~* ^/jobs/([\-a-z0-9]*)$ {
try_files /marketing/jobs/engineering/$1.php
/marketing/jobs/marketing/$1.php
/marketing/jobs/business-development/$1.php
/marketing/jobs/content/$1.php;
}
location ~ ^/.+\.php($|/) {
fastcgi_split_path_info ^(.+\.php)(/.*)$;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_pass unix:/run/php-fpm/php-fpm.sock;
include fastcgi_params;
fastcgi_read_timeout 3000;
}
}
This seems pretty close, except a plain text version of the file gets downloaded instead of nginx redirecting to it. I think I need to somehow catch the correct file with another location block, but I nothing seems to be working (that might not even be the correct approach).
Any ideas about how to achieve this? Or a better approach perhaps?
Thanks.
I belive that you are using try_files a bit wrong. What it does is
Checks the existence of files in the specified order and uses the
first found file for request processing; the processing is performed
in the current context.
You have one context with location ~* ^/jobs/([-a-z0-9]*)$ and another with location ~ ^/.+.php($|/)
So you are finding files but not processing them through PHP as your processing is in another context.
Therefore I belive you should add php processing in your try_files location.
location ~* ^/jobs/([\-a-z0-9]*)$ {
try_files /marketing/jobs/engineering/$1.php
/marketing/jobs/marketing/$1.php
/marketing/jobs/business-development/$1.php
/marketing/jobs/content/$1.php;
...
fastcgi_param ...;
fastcgi_pass ...;
}
To not write same config for both /jobs and .php locations you can cut it to file and include like you do with include fastcgi_params;
So ok, if your actual location directs to correct files - we're half way there. At this moment nginx is trying to download files - let's try to add another location directing those files to PHP parser - this one works for me:
location ~ ^/.+\.php($|/) {
fastcgi_split_path_info ^(.+\.php)(/.*)$;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_pass unix:/run/php-fpm/php-fpm.sock;
include fastcgi_params;
fastcgi_read_timeout 3000;
}
Add this piece of code after your location and let me know if this works for you. You can read more about nginx with PHP here