0

I have a nginx installation which I need for hosting web sites in development so that other people can test them out.

Right now I've set up a virtual host for a single sub-domain and in that directory I symlink projects which should be open for testing. As you can see have I restricted access to the whole site but enabled for the specific directory, but keeping it private with a simple auth_basic.

The PHP runs but I keep getting 404s for anything other than / or /wp-admin/, all the other permalinks gives 404s. I've done just about everything to get this to work but I have no idea what I'm doing wrong. Please point out my error in the following configuration:

server {
  listen 80;
  server_name dev.example.com;
  client_max_body_size 20m;
  server_tokens off;

  root /srv/dev.example.com;
  index index.php index.html index.htm;

  location / {
    deny all;
  }

  location /my-site {
    allow all;

    try_files $uri $uri/ /index.php?$args;

    auth_basic "Restricted";
    auth_basic_user_file /etc/nginx/auth.d/.htpasswd-my-site;

    location ~ \.php$ {
      include fastcgi_params;
      fastcgi_index index.php;
      fastcgi_pass php5-fpm-sock;
      fastcgi_param SCRIPT_FILENAME $request_filename;
      fastcgi_intercept_errors on;
      fastcgi_param HTTPS $https;
    }
  }
}

Thank you!

UPDATE:

This request would work: http://dev.example.com/my-site/, it would result in loading the file /srv/dev.example.com/my-site/index.php.

A request to the wordpress admin interface would work too: http://dev.example.com/my-site/wp/wp-admin, also going directly to an index file: /srv/dev.example.com/my-site/wp/wp-admin/index.php. Everything within the admin interface works since it doesn't use permalinks but the raw GET input.

However, as soon as I attempt to load a permalink (I use the most simple format /%postname%/) it fails in finding it and the try_files directive in location /my-site {} should match them. This means that routes such as the following doesn't work:

http://dev.example.com/my-site/about
http://dev.example.com/my-site/contact
http://dev.example.com/my-site/etc
Niklas
  • 113
  • 2
  • 8

1 Answers1

3

I'm gonna assume the following files don't exist on your filesystem :

/srv/dev.example.com/my-site/about/index.{php,html,htm}
/srv/dev.example.com/my-site/contact/index.{php,html,htm}
/srv/dev.example.com/my-site/etc/index.{php,html,htm}

Your issue comes from the fact that your php fallback location is nested within /my-site location and that try_files directive may not work like you are expecting.

Indeed, try_files accepts as a last parameter either :

  1. an URI
  2. a named location
  3. an HTTP code

For options 1 & 2, it will imply an internal redirect to the specified element. In your case /index.php?$args is interpreted as an URI and nginx will internaly redirect to it if $uri, $uri/, $uri/index.php, $uri/index.html, $uri/index.htm are missing.

Now, the other thing is : you use a nested location to handle php files processing. But as your try_files last parameter is the /index.php?$args URI it won't match the apex location /my-site so it's handled by the server block and if the URI can't be resolved to a local file then you end up with an HTTP 404 reply.

Note that the index directive will also imply internal redirects to the specified index files, but as URIs start with /my-site it will always fall in your php location.

So you must either move this location to the same level than the others or prefix your try_files URI with the prefix of your apex location and make sure the php file is in the right place.

Xavier Lucas
  • 12,815
  • 2
  • 44
  • 50
  • So what you are saying is that the try_files directive should instead be under `location / {}` or that I change the last element to `/my-site/index.php?$args`? Does it really matter where I put the `location ~ \.php$ {` since I'm not getting "File not found" from php-fpm but 404 from nginx? Are you also saying that I can't have the try_files directive under the `location /my-site {}`, that it must be at the root? – Niklas Nov 05 '14 at 08:48
  • @Niklas Well, I though I had explained these. Either change the last parameter of try_files or move the php location to the same level than the other locations. The 404 from nginx is exactly what I explained : you don't reach the php location because it's nested in `/my-site` and the URI of `/index.php?$args` doesn't match `/my-site` location. – Xavier Lucas Nov 05 '14 at 09:38