Nginx by examples: PHP setup

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/;
  index index.php;


  access_log /var/www/;
  error_log /var/www/ 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


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:

Apache Mod Rewrite #


Now read this

Nginx by examples: HTTPS

Setting up SSL/TLS on Nginx is a very simple exercise. A typical setup will look like this: server { root /var/www/; index index.php; server_name; # we enable SSL listen 443 ssl; ssl_certificate... Continue →