VPS with Ubuntu 18.04 NGINX Downloads PHP FILE

I have a VPS with:

  • Ubuntu 18.04
  • Nginx
  • Php7.2-fpm

The server runs Ruby on rails project as homeurl (example.com) and wordpress as directory (example.com/blog) . First the VPS was configured with Apache2, made everything work fine, untill i had to integrate a live chat. Had to switch to Nginx for Action Cable.

Now, the chat app works fine, on RoR, but if i try to access the blog i get the index.php file to download, it does not execute.

Here is my nginx default conf:

# You should look at the following URL's in order to grasp a solid understanding
# of Nginx configuration files in order to fully unleash the power of Nginx.
# https://www.nginx.com/resources/wiki/start/
# https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/
# https://wiki.debian.org/Nginx/DirectoryStructure
#
# In most cases, administrators will remove this file from sites-enabled/ and
# leave it as reference inside of sites-available where it will continue to be
# updated by the nginx packaging team.
#
# This file will automatically load configuration files provided by other
# applications, such as Drupal or Wordpress. These applications will be made
# available underneath a path with that package name, such as /drupal8.
#
# Please see /usr/share/doc/nginx-doc/examples/ for more detailed examples.
##

# Default server configuration
#

server { 

        listen   80; ## listen for ipv4; this line is default and implied
        listen   [::]:80 default_server ipv6only=on; ## listen for ipv6
        index index.php index.html index.htm index.nginx-debian.html;
        server_name localhost; 
        listen 443 ssl default_server;
        listen [::]:443 ssl default_server;
        ssl_certificate /etc/letsencrypt/live/asdfsf.net/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/sdafasdf.net/privkey.pem;
        root /var/www/html/public;
        passenger_enabled on;
        passenger_ruby /usr/local/bin/ruby;

location /var/www/html/public {
        try_files $uri $uri/ =404;
    }

    

location ~ ^/blog(/.*|$) {

 root /var/www/html/public/blog;
        
         try_files $uri $uri/ /blog/index.php?$args;
        passenger_enabled off;       
        index index.php;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        fastcgi_param DOCUMENT_ROOT $realpath_root;

        }

location ~ \.php$ {
                include snippets/fastcgi-php.conf;
                fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
   
        }


}

Spent 3 night on troubleshoting I cant get it right. Any hint is very welcomed. Thank you


Solution 1:

You have two regex matching locations and you don't have fastcgi_pass directive in the first one. Regex matching locations are checked from the first to the last one, so the second location (where you do have fastcgi_pass directive) will never be reached. That means any PHP file accessed with the /blog/ URI prefix will be treated as a simple file and will not be passed to the PHP-FPM backend for execution. You can use two nested locations instead:

location ~ ^/blog(/.*|$) {
    passenger_enabled off;       
    index index.php;
    try_files $uri $uri/ /blog/index.php?$args;
    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        fastcgi_param DOCUMENT_ROOT $realpath_root;
        fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
    }
}

You don't need to define root /var/www/html/public/blog; for this location. You already have root /var/www/html/public; at the upper level, so nginx will search file index.php requested as /blog/index.php in the /var/www/html/public/blog directory (see the difference between root and alias nginx directives).