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
Related
Say a website has this folder structure
/index.php
/<public>
dikpic.jpeg
And when someone visits the website I want the physical web root to point to /public,
like mywebsite.com/dikpic.jpeg
(without url rewrites).
This can be achieved with the root /myuser/public; command.
But I also want to load the index.php file from outside this directory:
index /myuser/index.php;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~* \.php$ {
fastcgi_pass unix:/run/php/php7.4-fpm-myuser.sock;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
}
The problem is with the location try files block that assumes / is the web root :(
Any way around this?
I should also point out that the index.php is the only script on the website.
So I don't really care if any other requests for .php files are ignored. The index.php handles url rewriting stuff...
You can use an additional location block for that, although it doesn't seems an elegant solution to me:
location ~* \.php$ {
fastcgi_pass unix:/run/php/php7.4-fpm-myuser.sock;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
}
location = /index.php {
fastcgi_pass unix:/run/php/php7.4-fpm-myuser.sock;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME /full/path/to/your/index.php;
fastcgi_param SCRIPT_NAME /index.php;
}
Exact matching locations have a priority over regex matching ones, so the first block will be used for any PHP file request except the /index.php. You don't even need to define a root for the second location, setting right SCRIPT_FILENAME FastCGI parameter value will be enough.
Update
I didn't notice the very last sentence of your question, but if you didn't care for any other PHP files, only the second block location = /index.php { ... } will be enough.
You can create symlinks of your index.php here is how to do that.
And as result you will have single index.php to all your websites
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 an online web server where I have deployed multiple applications and they all have to share the domain, so my nginx config is a bit messy. The last time I changed it, the PHP files didn't load getting the error ("access denied to file") so I had to do some changes, now the config for one of the applications is like this:
location ^~ /vuelos_baratos {
root /home/gonzalo;
try_files $uri $uri/ /$uri/index.php /index.php$is_args$args $uri/index.php =404;
#root /usr/share/nginx/html;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include /etc/nginx/fastcgi_params;
include /etc/nginx/mime.types;
autoindex on;
}
and the urls of this application are like this:
mydomain.com/vuelos_baratos/index.php
mydomain.com/vuelos_baratos/style.css
...
and so on.
And the PHP files and everything is working fine, except that If I try to acces:
mydomain.com/vuelos_baratos/image.png
I get the binary data of the image, I discovered that that is because the headers for all files under "vuelos_baratos" are set to type: text/html
How can I fix this?
I don't think that nginx is responsible for determining the content type in your current configuration, as you pass everything to php-fpm.
You could divide the static and dynamic sections into separate locations, for example:
location ^~ /vuelos_baratos {
include /etc/nginx/mime.types;
root /home/gonzalo;
index index.php;
try_files $uri $uri/ /index.php$is_args$args;
location ~ \.php$ {
try_files $uri =404;
include /etc/nginx/fastcgi_params;
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
fastcgi_param SCRIPT_FILENAME $request_filename;
}
}
Which should mean that /vuelos_baratos/image.png is processed by nginx and that /etc/nginx/mime.types is used to determine the Content Type.
Based on this question How to install symfony2 app in a subdirectory in nginx
I've created symfony3 application that works in subdirectory called bcms4. I've manged to make php work with PHP-FPM but I have probelms with assets. When I want to GET asset it directs the request to app_dev and shows 404 because obviosly the path does not exist.
My question is how to make assets not to be proccesed by app_dev but downloaded as supposed?
So when I enter
test.localhost/s/asdfad -> it runs symfony
test.localhost/asdf -> it runs other app living in main dir
test.localhost/s/assets/css/test.css -> it will show file in directory /var/www/test.localhost/bcms4/web/assets/css/test.css
My nginx config:
server {
listen 80;
root /var/www/test.localhost;
index index.html index.htm index.php;
# Make site accessible from http://localhost/
server_name test.localhost;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
# Uncomment to enable naxsi on this location
# include /etc/nginx/naxsi.rules
}
location ~ ^/s(/.*)$ {
try_files /s/web$1 /web$1 #sf2dev =404;
}
location #sf2dev {
expires off;
fastcgi_pass unix:/var/run/php5-fpm.sock;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME /var/www/test.localhost/bcms4/web/app_dev.php;
fastcgi_param SCRIPT_NAME /s/app_dev.php;
fastcgi_param REQUEST_URI /s$1;
}
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
# NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
# With php5-fpm:
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;
fastcgi_intercept_errors on;
}
}
After hours of trying I've managed to figure it out with little hack.
This is what I've added to my config file
location ~ ^/s(/.*).\w{1,5}$ {
rewrite ^/s(/.*) /bcms4/web$1 break;
return 404;
}
It'll rewrite files that has prefix /s and extension to directory where they are actually.
Maybe it will help someone. I'll leave question open for a while maybe someone has better solution cause it's seems hacky for me.
I am trying to achieve the following result with an nginx configuration:
A PHP app is running in a subdirectory of a server, lets say
server.com/app/. Files in images/ and styles/ (for example) should be accessible, php files in api/ should be executed, and in all other cases nginx should pass the whole string after app/ to PHP as a GET variable, say path.
I really have no clue what I am doing here, and I can not seem to find anything useful for this on the web, so if you can chip in, thank you.
I am running php5-fpm currently like this:
location /app {
index index.html index.php;
access_log /{...}/access.log;
error_log /{...}/error.log;
location ~ \.php {
try_files $uri = 404;
fastcgi_pass php5-fpm-sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
Please ask if you need any more details.
EDIT
For now I found that this works
location /{path}/ {
index index.php;
access_log /{path}/access.log;
error_log /{path}/error.log;
location ~\.php {
try_files $uri = 404;
fastcgi_pass php5-fpm-sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location ~ {
try_files $uri $uri/ /{path}/index.php?path=$uri;
}
}
However I am worried that this might allow unwanted file access. Any comments?
You can probably simplify it by moving the try_files directive out of the location sub-block so that your config file ends up looking like:
location /app {
index index.php;
try_files $uri $uri/ /app/index.php?path=$uri;
access_log /{path}/access.log;
error_log /{path}/error.log;
location ~\.php {
try_files $uri =404;
fastcgi_pass php5-fpm-sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
The key thing is the try_files directive - nginx will try each location in the order specified. $uri looks for a file matching the exact path specified (so /api/random.php loads correctly because it's a file), $uri/ looks for a folder matching the path, and attempts to load the index from the folder, and finally /app/index.php?path=$uri loads the page /app/index.php. This is then picked up by the location ~\.php block and passed to php-fpm.
The main thing I'd be concerned about is that your access and error.log files would be publicly accessible by virtue of being stored in the web directory. If possible, shift them somewhere else (like /var/log maybe?)