Solution to PHP script at home page is downloaded instead of executed

The issue is only at the website home page's PHP script has the download behaviour but the rest of the website pages' PHP script run normally. In this article will show two solutions. This issue is very hard to debug because there are no helpful logs that will give hint on solving this issue. Actually, I was debugging a "Permission denied" issue and the fixes I tried to apply to this resulted to our main topic issue. The web server setup: Nginx as reverse proxy to Apache and under a web hosting control panel. In Virtualmin or cPanel setup, the directory structure of root path of a user's website is something like this:


The fixes I tried for this "Permission denied" issue were:

  1. Added execute permission to /home/roland/ and /home/roland/public_html/ directories.

    chmod +x /home/roland
    chmod +x /home/roland/public_html
  2. Added existing user "nginx" to "roland" supplementary/secondary group.

    usermod -a -G roland nginx

... and these fixes I tried caused to PHP script at home page is downloaded instead of executed issue.

To undo these, run the following commands:

chmod 750 /home/roland
chmod 750 /home/roland/public_html
gpasswd -d nginx roland

Checking the directory:

ls -la /home/roland

The directory permission should now be:

drwxr-x--- 22 roland roland     4096 May 21 00:02 .
drwxr-xr-x  8 root   root       4096 Aug 12  2015 ..
drwxr-x--- 15 roland roland     4096 May  5 17:24 public_html

Checking the "nginx" user:

groups nginx

The "nginx" user's group list should now be:

nginx : nginx

The second solution, edit your Nginx configuration file and add the script that handles the index.php file.

For Nginx reverse proxy to Apache setup:

location = /index.php {
  proxy_http_version 1.1; # keep alive to the Apache upstream
  proxy_set_header Connection '';
  ## Referrer 
  proxy_set_header Visitor-referrer $http_referer;
  ## Rewrite the 'Host' header to the value in the client request,
  ## or primary server name
  proxy_set_header Host $host;

For Nginx+PHP FPM setup:

location = /index.php {
  ## 1. Parameters.
  fastcgi_param QUERY_STRING $query_string;
  fastcgi_param REQUEST_METHOD $request_method;
  fastcgi_param CONTENT_TYPE $content_type;
  fastcgi_param CONTENT_LENGTH $content_length;

  fastcgi_param SCRIPT_NAME /index.php;
  fastcgi_param REQUEST_URI $request_uri;
  fastcgi_param DOCUMENT_URI $document_uri;
  fastcgi_param DOCUMENT_ROOT $document_root;
  fastcgi_param SERVER_PROTOCOL $server_protocol;

  fastcgi_param GATEWAY_INTERFACE CGI/1.1;
  fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;

  fastcgi_param REMOTE_ADDR $remote_addr;
  fastcgi_param REMOTE_PORT $remote_port;
  fastcgi_param SERVER_ADDR $server_addr;
  fastcgi_param SERVER_PORT $server_port;
  fastcgi_param SERVER_NAME $server_name;
  ## PHP only, required if PHP was built with --enable-force-cgi-redirect
  fastcgi_param REDIRECT_STATUS 200;
  fastcgi_param SCRIPT_FILENAME $document_root/index.php;
  fastcgi_param HTTP_HTTPS $https;
  fastcgi_param HTTPS $https;
  #fastcgi_pass unix:/var/run/www.sock; # Socket
  fastcgi_pass; # TCP

  ## 2. Nginx FCGI specific directives.
  fastcgi_buffers 256 4k;
  fastcgi_intercept_errors on;
  ## Allow 4 hrs - pass timeout responsibility to upstream.
  fastcgi_read_timeout 14400;
  fastcgi_index index.php;

The above Nginx configuration will ensure that index.php will be handled directly by PHP to execute it and avoid the try_files $uri $uri/ @drupal; which results download behaviour of index.php instead of executing it.


Add new comment

Restricted HTML

  • Allowed HTML tags: <a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • Lines and paragraphs break automatically.