Recently I set up a virtual machine through vagrant and I'm using nginx as a web server. The OS I'm using for the VM is Ubuntu Linux 12.04. The problem is that any script I write in PHP gets downloaded, instead of being executed on the browser. Seeing as the PHP interpreter is normally installed I figured I'd post here the config file of nginx, as this is where the problem is likely to be found. Being a novice in the world of web development, I can't figure out what is out of the ordinary, can you guys take a look and tell me if you see something wrong? Thanks.
server {
listen 80;
server_name localhost;
root /vagrant/www/web;
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
#strip app.php/ prefix if it is present
rewrite ^/app\.php/?(.*)$ /$1 permanent;
location / {
index app.php;
try_files $uri #rewriteapp;
}
location #rewriteapp {
rewrite ^(.*)$ /app.php/$1 last;
}
# pass the PHP scripts to FastCGI server listening socket
location ~ ^/(app|app_dev)\.php(/|$) {
fastcgi_pass unix://var/run/php5-fpm.sock;
fastcgi_keep_conn on;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param HTTPS off;
}
# enable global phpMyAdmin
location /phpmyadmin {
root /usr/share/;
index index.php index.html index.htm;
location ~ ^/phpmyadmin/(.+\.php)$ {
try_files $uri =404;
root /usr/share/;
fastcgi_pass unix://var/run/php5-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include /etc/nginx/fastcgi_params;
}
location ~* ^/phpmyadmin/(.+\.(jpg|jpeg|gif|css|png|js|ico|html|xml|txt))$ {
root /usr/share/;
}
}
location /phpMyAdmin {
rewrite ^/* /phpmyadmin last;
}
}
Looks like you're having double // to indicate the fastcgi_pass path of php in your location block, try this instead
location ~ \.php$ {
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_keep_conn on;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param HTTPS off;
}
As was my suspicion the problem was in this location block:
location ~ ^/(app|app_dev)\.php(/|$) {
fastcgi_pass unix://var/run/php5-fpm.sock;
fastcgi_keep_conn on;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param HTTPS off;
}
The parameter to the location directive is a regular expression that defines only two possible file names: app.php and app_dev.php, thus making any other filename non-executable. For this to change, one needs to either add the names of one's php scripts to the parameter or change the regular expression to a more inclusive form as per Frederic Henri's suggestion.
Related
I'm setting up an Nginx + PHP web server on AWS Linux 2. It is a fresh install with nginx and PHP7.4 installed. Below is the virtual host config file in nginx.
I need to redirect all the traffic to index.php because it is a Single Page App.
When I go to www.xxx.com/index.php, the PHP page renders fine (so PHP is definitely running).
When I go to www.xxx.com/login/, the browser prompts for download of the index.php file instead of executing it.
Can anyone please help? (I've tried to clear my browser cache).
/etc/nginx/conf.d/myapp.conf
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/vhosts/app.userback.io/frontend/;
index index.php index.html index.htm;
server_name www.myapp.com;
location / {
try_files $uri $uri/ /index.php =404;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.(?:php|phar))(/.*)$;
fastcgi_intercept_errors on;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_pass php-fpm;
}
}
Can you try:
location ~ \.php$ {
try_files $uri /404.html;
fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;// change it if not valid
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
I've found the answer here: NGINX try_files does not pass to PHP.
It turns out it is the order of the location plus removing the 404 to make the redirect internal.
lets say I've a path like:
/var/www/myside/
that path contains two folders... let's say
/static and /manage
I'd like to configure nginx to have an access to:
/static folder on / (eg. http://example.org/)
this folder has some .html files.
/manage folder on /manage (eg. http://example.org/manage) in this case this folder contains Slim's PHP framework code - that means the index.php file is in public subfolder (eg. /var/www/mysite/manage/public/index.php)
I've tried a lot of combinations such as
server {
listen 80;
server_name example.org;
error_log /usr/local/etc/nginx/logs/mysite/error.log;
access_log /usr/local/etc/nginx/logs/mysite/access.log;
root /var/www/mysite;
location /manage {
root $uri/manage/public;
try_files $uri /index.php$is_args$args;
}
location / {
root $uri/static/;
index index.html;
}
location ~ \.php {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_index index.php;
fastcgi_pass 127.0.0.1:9000;
}
}
The / works correctly anyway manage doesn't. Am I doing something wrong? Does anybody know what should I change?
Matthew.
To access a path like /var/www/mysite/manage/public with a URI like /manage, you will need to use alias rather than root. See this document for details.
I am assuming that you need to run PHP from both roots, in which case you will need two location ~ \.php blocks, see example below. If you have no PHP within /var/www/mysite/static, you can delete the unused location block.
For example:
server {
listen 80;
server_name example.org;
error_log /usr/local/etc/nginx/logs/mysite/error.log;
access_log /usr/local/etc/nginx/logs/mysite/access.log;
root /var/www/mysite/static;
index index.html;
location / {
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_pass 127.0.0.1:9000;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $request_filename;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
}
location ^~ /manage {
alias /var/www/mysite/manage/public;
index index.php;
if (!-e $request_filename) { rewrite ^ /manage/index.php last; }
location ~ \.php$ {
if (!-f $request_filename) { return 404; }
fastcgi_pass 127.0.0.1:9000;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $request_filename;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
}
}
}
The ^~ modifier causes the prefix location to take precedence over regular expression locations at the same level. See this document for details.
The alias and try_files directives are not together due to this long standing bug.
Be aware of this caution in the use of the if directive.
Here is my nginx's content.
My current access url is http://localhost/lampi/, and I am receiving response 403 forbidden.
My server's documentroot is /Library/WebServer/Documents/.
When I access http://localhost/, it shows ok. I can also see the index.html page's content.
I don't know what the matter is. I have checked top 10 pages in stackoverflow.
server {
server_name localhost;
access_log /var/log/nginx/nginx.host.access.log main;
root /Library/WebServer/Documents/;
location / {
#root html;
index index.html index.htm index.php;
}
location /lampi {
#autoindex on;
if (!-e $request_filename){
rewrite ^/lampi/(.*)$ /lampi/index.php?s=$1 last;
}
}
location ~ \.php$ {
include /usr/local/etc/nginx/fastcgi_params;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /Library/WebServer/Documents/lampi/$fastcgi_script_name;
}
location ~ [^/]\.php(/|$) {
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
if (!-f $document_root$fastcgi_script_name) {
return 404;
}
fastcgi_param HTTP_PROXY "";
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi_params;
}
#location /images/ {
# root /usr/local/var/www;
#}
}
There are three potential problems with your configuration file.
The use of if (!-e $request_filename) is causing problems because it checks for the existence of directories, and you should probably be using try_files anyway (see this document for details):
location /lampi {
try_files $uri $uri/ #lampi;
}
location #lampi {
rewrite ^/lampi/(.*)$ /lampi/index.php?s=$1 last;
}
The value of SCRIPT_FILENAME adds an extra /lampi into the pathname. Use either of (both evaluate to the same value in this case):
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_FILENAME $request_filename;
For example:
location ~ \.php$ {
try_files $uri =404;
include /usr/local/etc/nginx/fastcgi_params;
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME $request_filename;
}
The location ~ [^/]\.php(/|$) block is confusing. Normally it is adequate to use either location ~ \.php$ or something like location ~ [^/]\.php(/|$) depending on whether or not your application uses PATH_INFO. Delete the block you are not using. See this document for details.
I have a development box that each user has a www folder in the home dir. NGINX is hosting those dirs from http://IP ADDRESS/USERNAME. And this works great. I want to get PHP working in the same fashion.
/etc/nginx/sites-available-default:
server {
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
#root /usr/share/nginx/html;
#index index.html index.htm;
# Make site accessible from http://IP ADDRESS/
server_name IP ADDRESS;
#location ~ ^/(.+?)(/.*)?$ {
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
alias /home/$1/www$2;
index index.html index.htm index.php;
include /etc/nginx/php.fast.conf;
autoindex on;
}
php.fast.conf file:
location ~ \.php$ {
fastcgi_split_path_info ^(.+?\.php)(/.*)?$;
fastcgi_pass unix:/var/run/php5-fpm.sock;
# fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_FILENAME /home/$1/www$2$fastcgi_script_name;
include /etc/nginx/fastcgi_params;
}
As you can see I have tried a few variations but seem to continue to receive the following error in the log: *1 FastCGI sent in stderr: "Primary script unknown" while reading response header from upstream, client.
When attempting to render a simple PHP info page The page displays "file not found"
Other info:
Server = ubuntu 14.x
Latest Nginx
Digital Ocean Droplet
Thanks in advance.
server {
listen 80 default_server;
root /var/www/html;
# Add index.php to the list if you are using PHP
index index.php index.html index.htm index.nginx-debian.html;
server_name _;
location ~* \.php$ {
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
try_files $fastcgi_script_name =404;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
set $path_info $fastcgi_path_info;
fastcgi_param PATH_INFO $path_info;
fastcgi_index index.php;
include fastcgi_params;
}
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
}
location ~* ^/(.+?)/www(/.*|/|)$ {
root /home;
index index.php index.html;
fastcgi_pass unix:/var/run/php5-fpm.sock;
# regex to split $uri to $fastcgi_script_name and $fastcgi_path
fastcgi_split_path_info ^(.+\.php)(/.+)$;
# Check that the PHP script exists before passing it
try_files $fastcgi_script_name =404;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
# Bypass the fact that try_files resets $fastcgi_path_info
# see: http://trac.nginx.org/nginx/ticket/321
set $path_info $fastcgi_path_info;
fastcgi_param PATH_INFO $path_info;
fastcgi_index index.php;
include fastcgi_params;
}
location ~* ^/(.+?)(/.*|/|)$ {
index index.php index.html;
try_files $uri $uri/ #home;
}
location #home {
rewrite ^/([^/]+?)$ /$1/www/ last;
rewrite ^/(.+?)(/.*|/)$ /$1/www$2 last;
}
}
The cons of this config, you can't use URI like /<anything_you_want>/www.
Maybe it helps. But it's weird, non-optimized and ugly config.
I would like to serve 2 PHP(Symfony) applications under the same domain, with a URL prefix for one of the apps.
So www.mydomain.com/ should serve the first app while www.mydomain.com/secondapp should serve the second one.
I ended up with this config which doesn't work :
server {
server_name mydomain.com www.mydomain.com;
location / {
root /var/www/first-app/web;
try_files $uri /app.php$is_args$args;
}
location /secondapp {
root /var/www/second-app/web;
try_files $uri /app.php$is_args$args;
}
location ~ ^/(app|app_dev|config)\.php(/|$) {
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param HTTPS off;
}
}
When I put the root directive for the first app under the last location, it works for the first app but the second can't be served.
Should I create a second server directive and use sub-domain rewriting instead?
Thanks!
You should use alias instead of root in your locations. If you use root, the path that is matched in the location is added to the root path.
So I finally found the solution: my nginx conf:
server {
listen 80;
server_name www.mydomain.com;
root /var/www/first-app/web;
location ~ ^/secondapp(/.*)$ {
alias /var/www/second-app/web;
try_files $1 #app;
}
location #app {
expires off;
fastcgi_pass unix:/var/run/php5-fpm.sock;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME /var/www/second-app/web/app.php;
fastcgi_param SCRIPT_NAME /secondapp/app.php;
fastcgi_param REQUEST_URI /secondapp$1;
}
location / {
try_files $uri /app.php$is_args$args;
}
location ~ ^/(app|app_dev|config)\.php(/|$) {
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param HTTPS off;
}
error_log /var/log/nginx/app_error.log;
access_log /var/log/nginx/app_access.log;
}