1

For the love of nginx, I can't wrap my head around this issue.

Desired: I want two simple php projects (wordpress in the long haul) in two sub locations under one server block. Side note: These projects reside in two different directories on the server deployed with capistrano.

Problem: I either end up with a 404, 403 or a direct octet stream download of the index.php. On the latter I seem to hit the correct index.php but it is not passed to the php-fpm block. php-fpm is working and not the issue (tested in other serverblock without sublocations)

I have looked all over the web and have tried gazillions of "working" configs, but its not coming together.

Plan: Below you see a working nginx vhost, hitting the right index.html files in the correct alias directories. Thus I am halfway there.

With your help I would like to adapt the config below, to change the index to index.php and get php working on location /staging and /production.

In the location /production you see one config (commented out) how I tried to get php working.

server {
  listen 82;
  listen [::]:82;

  server_name nginx-web.ch;

  access_log /var/log/nginx/nginx-web_access.log;
  error_log /var/log/nginx/nginx-web_error.log;

  location  /staging {
    alias /var/www/nginx-web1/current;
    index index.html
    add_header X-debug-message "Location web1";
  }

  location /production {
    alias /var/www/nginx-web/current;
    index index.html
    add_header X-debug-message "Location web";

    #try_files $uri $uri/ /production/index.php;

    #location ~ \.php$ {
      # add_header X-debug-message "Location ~ php";
      # try_files $uri =404;
      # fastcgi_split_path_info ^(.+\.php)(/.+)$;
      # fastcgi_pass unix:/var/run/php5-fpm.sock;
      # fastcgi_index index.php;
      # include fastcgi_params;
      # fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
    #}
  }
}

Here is a working server block it tried to adapt for sublocations, without success :(

server {
  listen 80;
  listen [::]:80;

  server_name testdev;

  access_log /var/log/nginx/wp_access.log;
  error_log  /var/log/nginx/wp_error.log;

  root /var/www;
  index index.php;

  location / {
    try_files $uri $uri/ /index.php?$args; 
  }

  location ~ \.php$ {
    try_files $uri =404;
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    fastcgi_pass unix:/var/run/php5-fpm.sock;
    fastcgi_index index.php;
    include fastcgi_params;
  }
}

UPDATE with WORKING CONFIG (gotta <3 serverfault/stackoverflow):

Here is the final working configuration, many thanks to @RichardSmith

server {
    listen 82;
    listen [::]:82;

    server_name nginx-web.ch;

    access_log /var/log/nginx/nginx-web_access.log;
    error_log /var/log/nginx/nginx-web_error.log;

    index index.php;

    location ^~ /staging/ {
      alias /var/www/nginx-web1/current/;

      if (!-e $request_filename) { rewrite ^ /staging/index.php last; }

      location ~ \.php$ {
       if (!-f $request_filename) { return 404; }

       include fastcgi_params;
          fastcgi_param  SCRIPT_FILENAME $request_filename;
          fastcgi_pass unix:/var/run/php5-fpm.sock;
       }
    }

    location /production {
      alias /var/www/nginx-web/current;

      if (!-e $request_filename) { rewrite ^ /production/index.php last; }

      location ~ \.php$ {
        if (!-f $request_filename) { return 404; }

        include fastcgi_params;
          fastcgi_param  SCRIPT_FILENAME $request_filename;
          fastcgi_pass unix:/var/run/php5-fpm.sock;
        }
    }
}
7
  • nested locations? – Alexander Makarenko Nov 24 '17 at 10:29
  • Yes @AlexanderMakarenko nested locations! – mahatmanich Nov 24 '17 at 11:39
  • mailman.nginx.org/pipermail/nginx-ru/2011-October/043594.html It's in russian, just check 1st example. I'll translate it for you if something is still unclear for you. – Alexander Makarenko Nov 24 '17 at 11:42
  • What are you trying to tell me with this 6 year old mailing list text? And yeah my russian is not fluid :-) I want a working config not bits and pieces. I had those the last 24 hours ... – mahatmanich Nov 24 '17 at 12:05
  • It's about nginx behavior with nested locations. This info is absent in docs and it's still actual. If it's not interesting for you, I do not insist. – Alexander Makarenko Nov 24 '17 at 12:11
1

This pattern works:

location ^~ /prefix/ {
    alias /path/to/root/;
    if (!-e $request_filename) { rewrite ^ /prefix/index.php last; }

    location ~ \.php$ {
        if (!-f $request_filename) { return 404; }

        include        fastcgi_params;
        fastcgi_param  SCRIPT_FILENAME $request_filename;
        fastcgi_pass   ...;
    }
}

Use the ^~ prefix to avoid other regular expression location blocks taking precedence. See this document.

The value of the location and the alias both end with / or neither end with /. See this document.

Avoid using alias and try_files together due to this issue and see this caution on the use of if.

Use $request_filename as the computed value of SCRIPT_FILENAME (as it works with both alias and root).

Always set fastcgi_param after including the fastcgi_params file, to avoid the latter silently overwriting the local value.

10
  • Hi Richard, I have it all setup as you wrote, but I am hitting this: nginx and php-fpm “Primary script unknown” serverfault.com/questions/734935/… since I don't have a root set on the server and I am using $request_filename how can that be? – mahatmanich Nov 24 '17 at 12:23
  • 1
    Use fastcgi_param SCRIPT_FILENAME $request_filename; instead of fastcgi_param SCRIPT_FILENAME $fastcgi_script_name; - the latter is the URI and not the path to the file. – Richard Smith Nov 24 '17 at 12:30
  • 1
    And FYI, the fastcgi_split_path_info and fastcgi_index statements are redundant, as they have no effect on URIs that end with .php. – Richard Smith Nov 24 '17 at 12:33
  • 1
    They are all documented here. – Richard Smith Nov 24 '17 at 12:35
  • 1
    That is correct. The query string is not part of the normalized URI which is used to evaluate locations, rewrites and the request filename. – Richard Smith Nov 24 '17 at 12:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.