Nginx by examples: php setup

Nginx configuration for PHP can be a little fiddly.

Let’s see how to make things work :)

When setting up PHP with Nginx we are effectively still using Nginx as a reverse proxy in front of a FastCGI server as the fastcgi_pass directive is functionally equivalent to the proxy_pass one.

There are plenty of blog posts and examples online that show how to setup PHP behind nginx but most of them don’t really explain why the suggested setup simply works :)

Let’s start with a simple configuration:

server {
 
  root /var/www/mydomain.com/web/;
  index index.php;
 
  server_name mydomain.com;
 
  access_log /var/www/mydomain.com/log/mydomain.com.access;
  error_log /var/www/mydomain.com/log/mydomain.com.error error;
 
  location / {
  
	# we serve a file if it's there, 
	# otherwise we rewrite internally as a request to /index.php
    try_files $uri /index.php?$args;
  }
  
  # regex matching: anything ending with .php
  location ~ \.php$ {
  
	# allows for requests to /test.php/article/0001 
	# to be handled by /test.php. At the same time 
	# it sets the $fastcgi_path_info env variable 
	# (that can be sent to php via the fastcgi interface)
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    
	# defaults calls to /uri/ to /uri/index.php (optional)
	fastcgi_index index.php;
	
	# sets the standard fastcgi parameters (from another file)
    include fastcgi_params;
	
	# if the rewritten $uri doesn't really exist 
	# let's return 404 to the user
    try_files $uri =404;
	
	# let's pass the request to the fastcgi downstream
    fastcgi_pass 127.0.0.1:9000;	
  }
  
}

Request resolution process

The main point here is to understand how the

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

and the

location ~ \.php$ {
   ...
}

interact with each other

In the catch-all location / {} block the tryfiles directive matches any incoming request not ending with .php If the request has:

  1. rewritten as /index.php?$args (last option in the try_files directive)
  2. is now ending with .php
  3. it now matches the php location block as Nginx gives precedence to location blocks with matching regular exceptions
  4. is now served through the fastcgi_pass directive

Apache Mod Rewrite

Comments

comments powered by Disqus

Subscribe to my newsletter