Skip to content

Instantly share code, notes, and snippets.

@alanbriolat
Created September 28, 2011 14:01
Show Gist options
  • Save alanbriolat/1248004 to your computer and use it in GitHub Desktop.
Save alanbriolat/1248004 to your computer and use it in GitHub Desktop.
nginx userdir + PHP-FPM
server {
listen 80;
server_name localhost;
# ... other default site stuff, document root, etc. ...
location ~ ^/~(?<userdir_user>.+?)(?<userdir_uri>/.*)?$ {
alias /home/$userdir_user/public_html$userdir_uri;
index index.html index.htm index.php;
autoindex on;
include php5_generic;
}
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $request_filename;
fastcgi_pass unix:/var/run/php5-fpm.sock;
}
@subterfugium
Copy link

This was very good example.

However, I think this example doesn't set PATH_INFO correctly as in http://wiki.nginx.org/PHPFcgiExample.

I did modifications for the regexp to match https://server.com/user/username/ userdirs:

default.conf

        location ~^/user/(?<userdir_user>.+?)(?<userdir_uri>/.*)?$ {
                alias /home/$userdir_user/www$userdir_uri;
                index index.html index.htm index.php;
                autoindex on;

                include php5_userdirs;
        }

(This has to be before the location / rule)

Now for example

http://example.com/user/joe/test.php/foo/bar.php?v=1

saves

$userdir_user = joe
$userdir_uri = /test.php/foo/bar.php?v=1

and

php5_userdirs

location ~ \.php$ {
        include fastcgi_params;
        fastcgi_param DOCUMENT_ROOT /home/$userdir_user/www;
        fastcgi_split_path_info ^(.+?\.php)(/.*)$;
        fastcgi_param SCRIPT_FILENAME $request_filename;
        fastcgi_pass unix:/var/run/php5-fpm.sock;
}

and now SCRIPT_FILENAME, SCRIPT_NAME, PATH_INFO, REQUEST_URI, DOCUMENT_URI and DOCUMENT_ROOT variables seem to be like in nginx documentation example.

I have no idea if this is correct and I need to run more tests.

It's still missing one part of the NGINX guide:

              if (!-f $document_root$fastcgi_script_name) {
                        return 404;
                }

Can someone confirm if my findings are correct?

@alanorth
Copy link

Here's what I'm doing for PHP + userdirs in ~user:

Amend default.conf:

    index index.php index.html index.htm;
    autoindex on;

    # user directories
    location ~ ^/~(?<userdir_user>[\w-]+)(?<userdir_uri>/.*)?$ {
        alias /home/$userdir_user/public_html$userdir_uri;

        location ~ [^/]\.php(/|$) {
            include php5_common;
        }   
    }   

    # php support
    location ~ [^/]\.php(/|$) {
        include php5_common;
    }   

Add php5_common:

include fastcgi_params;

fastcgi_index index.php;

# check if requested PHP file really exists
if (!-f $request_filename) {
    return 404;
}

#NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_param SCRIPT_FILENAME $request_filename;

fastcgi_pass unix:/var/run/php-fpm-www.sock;

Some notes:

  • using one common include for php5 stuff
  • using if to test for existence of PHP script file on disk before passing it to php-fpm (try_files doesn't work after the alias in the userdir context because alias overrides the document root, and this is a valid use of if)
  • uses $request_filename instead of $fastcgi_script_name as it works better when you are using aliases, and provides the translated disk path for the script
  • Doesn't bother with PATH_INFO or DOCUMENT_ROOT fastcgi parameters because I'm not sure I need them yet...

Copy link

ghost commented May 16, 2015

@alanorth Thanks! I added that to my nginx config (with a minor adjustment; the socket on Debian is /var/run/php5-fpm.sock) and it works perfectly.

@frewie
Copy link

frewie commented Jan 17, 2017

The php5_generic cannot be included directly, it should be in a separate file. Otherwise it won't work.

Copy link

ghost commented Jun 8, 2017

Could this be modified to work with Gunicorn does anyone know?

@mlambie
Copy link

mlambie commented Jun 2, 2018

@alanorth @nyuszika7h I too was able to use this on Ubuntu 18.04 by updating just the socket reference.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment