Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
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;
}
@Battleroid

This comment has been minimized.

Show comment Hide comment
@Battleroid

Battleroid Jan 30, 2013

Used to setup user directories on my personal server. Works brilliantly. Saved me a lot of time and stress. Thanks.

Used to setup user directories on my personal server. Works brilliantly. Saved me a lot of time and stress. Thanks.

@bagage

This comment has been minimized.

Show comment Hide comment
@bagage

bagage Jul 18, 2013

Thank you guy!

bagage commented Jul 18, 2013

Thank you guy!

@brahimmachkouri

This comment has been minimized.

Show comment Hide comment
@brahimmachkouri

brahimmachkouri Dec 31, 2013

Really helpful. Thanks.

Really helpful. Thanks.

@subterfugium

This comment has been minimized.

Show comment Hide comment
@subterfugium

subterfugium Jan 5, 2015

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?

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

This comment has been minimized.

Show comment Hide comment
@alanorth

alanorth Feb 26, 2015

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...

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...
@nyuszika7h

This comment has been minimized.

Show comment Hide comment
@nyuszika7h

nyuszika7h 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.

@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

This comment has been minimized.

Show comment Hide comment
@frewie

frewie Jan 17, 2017

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

frewie commented Jan 17, 2017

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

@ODonnellM

This comment has been minimized.

Show comment Hide comment
@ODonnellM

ODonnellM Jun 8, 2017

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

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

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