Nginx – Serving PHP from an Nginx Alias

nginx

I'm working on a migration of several sites from Apache to Nginx and I've bumped into a snag on one that has a virtual directory (alias). The alias itself works fine and the proper file gets served, but PHP isn't proxied properly.

server {
  listen      443 default_server ssl;
  server_name dev.myproject.mydomain.net;
  root        /opt/dev/project-root;
  index       index.php;

  ssl_certificate      /etc/ssl/certs/server.crt;
  ssl_certificate_key  /etc/ssl/certs/server.pem;

  access_log /var/log/nginx/vh.project.access.log;
  error_log  /var/log/nginx/vh.project.error.log;

  location ~ ^/alias_name/(.*) {
    alias /opt/dev/project-root/www/$1;

    location ~ ^/alias_name/(.+\.php)$ {
      alias /opt/dev/project-root/www/$1;
      include /etc/nginx/conf/php;
    }
  }

  location ~ \.php$ {
    include /etc/nginx/conf/php;
  }
}

I haven't tried this yet, but I suspect that if I copied the content of the \.php$ location block into the alias block things would work fine, but the engineer in me loathes replication. Is there any way to avoid that (assuming it would work at all)? Intuitively, it seems like both location blocks would be evaluated.

I could also move the php block out to a separate file and include it, I'm sure.

Any advice on the best (read: most nginx-y) way to handle this would be much appreciated.

UPDATE

Based on Kyle's answer, I've moved the PHP proxy out to a separate conf/ directory. The conf/php file has this code:

location ~ \.php$ {
  fastcgi_split_path_info ^(.+\.php)(/.+)$;
  fastcgi_pass 127.0.0.1:9000;
  fastcgi_index index.php;
  include fastcgi_params;
}

My alias location block now looks like this:

location ~ ^/alias_name/(.*) {
  alias /opt/dev/path/to/aliased/$1;
  include /etc/nginx/conf/php;
}

If I drop a static HTML file at that alias, it renders fine. A PHP file returns a 404.

UPDATE

With @quanta's help in the comments, I've managed to get PHP serving properly and I've updated the alias location block with the config. Unfortunately, not static content isn't rendering if the URL includes the alias. Today isn't my day.

Best Answer

Okay, so I may have found my own answer by brute force trial and error once I incorporated @quanta's info (see comments above). This virtual host server block seems to serve PHP and static content properly:

server {
  listen      443 default_server ssl;
  server_name dev.myproject.mydomain.net;
  root        /opt/dev/project-root;
  index       index.php;

  ssl_certificate      /etc/ssl/certs/server.crt;
  ssl_certificate_key  /etc/ssl/certs/server.pem;

  access_log /var/log/nginx/myproject.dev.access.log;
  error_log  /var/log/nginx/myproject.dev.error.log;

  location ~ ^/alias_name/(.+\.php)$ {
    alias /opt/dev/project-root/www/$1;
    include /etc/nginx/conf/php;
  }
  location ~ ^/alias_name/(.*) {
    alias /opt/dev/project-root/www/$1;
  }

  location ~ \.php$ {
    include /etc/nginx/conf/php;
  }
}

I don't know whether I'll bump into problems and I can't say that I fully understand the difference, but simply removing the nested location blocks seems to have done the trick.