Why is my site downloaded instead of running? - nginx

I'm trying to install Wordpress on a Ubuntu 18.04 on a subdomain. I set the Nginx files on sites-available, but I get a 502 error on browser because Wordpress is using a .php file type for the index, so I added "index.php" on the list in sites-available. Well after adding "index.php" on the list when I try to access the URL in browser it downloads a file named with the subdomain address.
Here's my code in sites-available
server {
listen 80;
listen [::]:80;
root /var/www/apt;
# Add index.php to the list if you are using PHP
index index.html index.htm index.nginx-debian.html index.php;
server_name apt.forrum.ro;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
}
}
Please let me know how to fix it.

This is simplified, basically Nginx uses the try_files directive to serve the file to user in the folder. This is why your php file is being sent to the user, it's then downloaded rather than shown as browsers don't really know how to show PHP to the user.
What you need to do is tell Nginx to run the file. In the case of PHP you can use FastCGI. There are many guides to doing this on ubuntu such as This One.
Once you have it installed, all the directives for FastCGI are described by Nginx themselves Here.
Their example is posted here:
location ~ [^/]\.php(/|$) {
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
if (!-f $document_root$fastcgi_script_name) {
return 404;
}
# Mitigate https://httpoxy.org/ vulnerabilities
fastcgi_param HTTP_PROXY "";
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
# include the fastcgi_param setting
include fastcgi_params;
# SCRIPT_FILENAME parameter is used for PHP FPM determining
# the script name. If it is not set in fastcgi_params file,
# i.e. /etc/nginx/fastcgi_params or in the parent contexts,
# please comment off following line:
# fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}

Related

NGINX + Passenger w/ Rails + WordPress permalinks

The environment is as follows:
I have https://website.com and a blog at https://website.com/blog
The root path points to a Passenger-hosted Rails app, and the blog subdirectory points to a WordPress app via php-fpm
Everything works fine with my Nginx config, but when I try to change the permalink structure to anything other than "Plain", I get a 404 page from the Rails app as if the location blocks aren't utilized. I tried looking at the error log in debug mode, and I do see it attempting to try_files, but ultimately it fails with the Rails 404 page.
It may be worth noting that the entire site is behind Cloudflare. Not sure if it could be something with that, though I kind of doubt it.
Here is the almost-working Nginx config I'm using:
server {
listen 80 default_server;
server_name IP_ADDRESS;
passenger_enabled on;
passenger_app_env production;
passenger_ruby /home/ubuntu/.rbenv/shims/ruby;
root /web/rails/public;
client_max_body_size 20M;
location ^~ /blog {
passenger_enabled off;
alias /web/blog;
index index.php index.htm index.html;
# Tried the commented line below, but then nothing works.
# try_files $uri $uri/ /blog/index.php?$args;
# The line below works, but peramlinks don't.
try_files $uri $uri/ /blog/index.php?q=$uri&$args;
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass unix:/run/php/php7.3-fpm.sock;
# Tried the commented line below, but then nothing works
# fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
# The line below works, but peramlinks don't.
fastcgi_param SCRIPT_FILENAME $request_filename;
}
}
}
I wanted to comment in short but I don't have enough reputation for that.
I used the following block and worked for me. I added an add_header directive just to debug that if my request is reaching the correct block.
location ^~ /blog {
try_files $uri $uri/ /index.php?$args;
add_header reached blog;
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass php;
}
}
If your server is behind CloudFlare, you can try with /etc/hosts entry on your local machine if you're using Ubuntu/Mac. Which will stop the DNS lookup and site will directly be accessed from the IP address.
Check if any redirects are happening due to any other Nginx configuration.
Also, you have mentioned in the question that site is https:// while your server block has only listen 80 meaning non HTTPS.
Check for the response headers with
curl -XGET -IL site-name.tld
which may help you more debugging the situation.
Difference between alias and root directives https://stackoverflow.com/a/10647080/12257950

Nginx load subpath as wordpress root

I'm trying to set up a Wordpress in a system that has another php application installed, using nginx as web server.
I've simplified my config file to the maximun. The following confi is serving one post of my blog:
server {
listen 80;
server_name blog.ct.com;
root /home/ff/www/blog/;
index index.php index.html;
location / {
try_files $uri $uri/ /index.php?$uri&$args =405;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_buffer_size 128k;
fastcgi_buffers 64 32k;
fastcgi_busy_buffers_size 128k;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
include /etc/nginx/fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param APPLICATION_ENV development;
fastcgi_param HTTP_X_FORWARDED_PROTO https;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
}
}
But, due my system's requirements I need to serve the blog from within a sub path (In my final system http://blog.ct.com/ should be serving my custom php app and http://blog.ct.com/vendor should be serving the wordpress blog).
The local root directory from wordpress must be /home/ff/www/blog/ (this cannot be changed, while my custom app's directory is /home/ff/www/myapp/). So I think I need to reserve location / for my custom app, I have to create a location /vendor
If I add /vendor and I return 403 in / (just to debug easier), the browser says 405 (notice the =405 in /vendor, also to debug easier):
location /vendor {
try_files $uri $uri/ /index.php?$uri&$args =405;
}
location / {
return 403;
}
So I think nginx is going into location /vendor but is not finding my php script in /home/ff/www/blog/index.php so its returning the fallback 405.
Any idea why this could happen?
How can I achieve to load http://blog.ct.com/vendor as the root from wordpress but keeping http://blog.ct.com/ using another php script?
I've found out the following hints that gave me the clue to fix the problem (in case someone has the same problem than me, this may help)
Using location /path is not the same as using location ~(/path) (regex have different priority, so maybe they are not being checked in the order you think)
Adding error_log /your/path/log/error.log debug; to any location block may help you to see how is nginx serving every request (e.g. to location fastcgi, location \vendor, or the server{ block).
alias /var/www/path/vendor works different than root /var/www/path/vendor (check Nginx -- static file serving confusion with root & alias);
In case of the root directive, full path is appended to the root including the location part, whereas in case of the alias directive, only the portion of the path NOT including the location part is appended to the alias.
using rewrite with alias can help you parse the php file you want independent of the path
if (!-f $request_filename) {
rewrite ^ $document_root/index-wp.php last;
}
Take care of the SCRIPT_FILENAME you are using (check it with error_log, see above), maybe you need fastcgi_param SCRIPT_FILENAME $fastcgi_script_name; but you are loading fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; so depending on your previous config you may be attaching the document root twice.
Two different configurations for fastcgi can be used if you change your index.php file names. E.g. location ~ wp\.php$ { will work with wp.php while location ~ \.php$ { will work with all other php files like index.php.

Ubuntu Nginx - changing the server root directory

I really depends on changing the server root directory from /var/www to the /srv/http.
Because if I sue:
server {
server_name www.domain.tld;
root /srv/http/project/web;
location / {
# try to serve file directly, fallback to app.php
try_files $uri /app.php$is_args$args;
}
# DEV
# This rule should only be placed on your development environment
# In production, don't include this and don't deploy app_dev.php or config.php
location ~ ^/(app_dev|config)\.php(/|$) {
fastcgi_pass unix:/var/run/php/php7.1-fpm.sock;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
# When you are using symlinks to link the document root to the
# current version of your application, you should pass the real
# application path instead of the path to the symlink to PHP
# FPM.
# Otherwise, PHP's OPcache may not properly detect changes to
# your PHP files (see https://github.com/zendtech/ZendOptimizerPlus/issues/126
# for more information).
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;
}
# PROD
location ~ ^/app\.php(/|$) {
fastcgi_pass unix:/var/run/php/php7.1-fpm.sock;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
# When you are using symlinks to link the document root to the
# current version of your application, you should pass the real
# application path instead of the path to the symlink to PHP
# FPM.
# Otherwise, PHP's OPcache may not properly detect changes to
# your PHP files (see https://github.com/zendtech/ZendOptimizerPlus/issues/126
# for more information).
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;
# Prevents URIs that include the front controller. This will 404:
# http://domain.tld/app.php/some-path
# Remove the internal directive to allow URIs like this
internal;
}
# return 404 for all other php files not matching the front controller
# this prevents access to other php files you don't want to be accessible.
location ~ \.php$ {
return 404;
}
error_log /var/log/nginx/project_error.log;
access_log /var/log/nginx/project_access.log;
}
does not work.
The system is Ubuntu 16.04 and server Nginx.
Thanks in advance for your help.
First of all your root directory is /srv/http/project/web but not /var/www, and in order to change it to /srv/http, you got to find root /srv/http/project/web; in above configuration(which is third line of the same) and change it to root /srv/http;. -Thank You :)

1 nginx server multiple php servers

what i am missing?
lets say this simple conf:
upstream php {
server 111.1111.1111.1111:9000;
}
server {
listen 80 reuseport;
root /var/www/html/public/;
index index.php;
location / {
set $orig_uri $uri;
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
ssi on;
include snippets/fastcgi-php.conf;
fastcgi_param REQUEST_URI $orig_uri$is_args$args;
fastcgi_cache_key "$scheme$request_method$orig_uri$is_args$args";
add_header X-Cache-Key $scheme$request_method$orig_uri$is_args$args;
add_header X-Cache $upstream_cache_status;
# With php5-cgi alone:
#fastcgi_pass 127.0.0.1:9000;
# With php5-fpm:
#fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_pass php;
}
}
how does nginx gonna access "/var/www/html/public/" on different server? how will it know if the file exists or not exists? I tried to play with it and I always get
404 Not Found
So i am missing something but cant understand what, if the php servers dont have nginx installed
How does nginx gonna access "/var/www/html/public/" on different
server? how will it know if the file exists or not exists?
nginx cannot determine if the file exists on the upstream PHP service. It will pass a script pathname to the PHP service and if it does not exist, the PHP service will return a 404 response.
The PHP service probably uses the fastcgi_param SCRIPT_FILENAME parameter to find the upstream script file. The parameter should be defined in your snippets/fastcgi-php.conf file.
This is usually set to a value of $document_root$fastcgi_script_name. The value for $document_root being set by the root directive in your configuration file.
This will only work if the scripts on the upstream server are placed in the exact same directory hierarchy as specified by the nginx server. Otherwise, you may need to handcraft the value of the SCRIPT_FILENAME parameter.

Nginx, fastcgi PHP Windows, No input file specified

Running php-cgi on port 9000
Netstat gives me
TCP 127.0.0.1:9000 DESKTOP-xxxxxxx:0 LISTENING
[php-cgi.exe]
nginx.conf
http://pastebin.com/wkfz8wxw
Every php file gives me this No input file specified. error...
Changed SCRIPT_FILENAME to SCRIPT_NAME and no succes..
I am on Windows 10 Home x64
You need to set a document root with the root directive, either within your location ~ \.php$ block or inherited from the outer server block.
The solution may be to move the root c:/Users/Youri/PhpstormProjects; line out of your location / block into a position above it.
Usually fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; is the correct method to specify the full path to the script, whereas SCRIPT_NAME is usually just the last element.
Like this:
server {
...
root c:/Users/Youri/PhpstormProjects;
location / {
index index.html index.htm index.php;
}
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
Set root directive with absolute path in windows PC.
Check for the case or any typing mistake in the path.
Reload the nginx process.
May be the root path problem. I used the backslash \ on Windows and found this issue.
server {
location ~ \.php$ {
- root C:\Users\name\ProjectOfPHP; # 404
+ root C:/Users/name/ProjectOfPHP; # Use this pattern
}
}

Resources