title: nginx, php-fpm and tilde user directories
body: <p>I'm using <code>nginx</code> and <code>php5-fpm</code> on a Debian system.</p>
  
  <p>I want my server to serve like so;</p>
  
  <ul>
  <li><code>ip/index.html</code> serves the static html page (or files) at the nginx web root</li>
  <li>and likewise, <code>ip/somefile.php</code> (or <code>index.php</code>) serves PHP through php-fpm</li>
  <li><code>ip/~user/index.html</code> serves the static html page (or files) in <code>/home/user/public_html</code></li>
  <li>and likewise, <code>ip/~user/somefile.php</code> (or <code>index.php</code>) serves PHP through php-fpm</li>
  </ul>
  
  <p>(where <code>ip</code> is either an IPv4 or IPv6 address).</p>
  
  <hr>
  
  <p>Here is my configuration for <code>nginx</code>:</p>
  
  <pre><code>server {
          listen 80;
          listen [::]:80 default_server ipv6only=on;
  
          server_name _;
          root /usr/share/nginx/www;
          index index.php index.html index.htm;
  
          # Deny access to all dotfiles
          location ~ /\. {
                  deny all;
          }
  
          location ~ \.php$ {
                  include /etc/nginx/fastcgi_params;
  
                  try_files $uri = 404; # Prevents exploit
                  fastcgi_pass unix:/var/run/php5-fpm.sock;
                  fastcgi_index index.php;
          }
  
          # Serve user directories
          location ~ ^/~(.+?)(/.*)?$ {
                  alias /home/$1/public_html$2;
                  autoindex on;
          }
  }
  </code></pre>
  
  <p>And for <code>php-fpm</code>:</p>
  
  <pre><code>; Start a new pool named 'www'.
  ; the variable $pool can we used in any directive and will be replaced by the
  ; pool name ('www' here)
  [www]
  
  ; Per pool prefix
  ; It only applies on the following directives:
  ; - 'slowlog'
  ; - 'listen' (unixsocket)
  ; - 'chroot'
  ; - 'chdir'
  ; - 'php_values'
  ; - 'php_admin_values'
  ; When not set, the global prefix (or /usr) applies instead.
  ; Note: This directive can also be relative to the global prefix.
  ; Default Value: none
  ;prefix = /path/to/pools/$pool
  
  ; Unix user/group of processes
  ; Note: The user is mandatory. If the group is not set, the default user's group
  ;       will be used.
  user = www-data
  group = www-data
  
  ; The address on which to accept FastCGI requests.
  ; Valid syntaxes are:
  ;   'ip.add.re.ss:port'    - to listen on a TCP socket to a specific address on
  ;                            a specific port;
  ;   'port'                 - to listen on a TCP socket to all addresses on a
  ;                            specific port;
  ;   '/path/to/unix/socket' - to listen on a unix socket.
  ; Note: This value is mandatory.
  listen = /var/run/php5-fpm.sock
  
  ; Set listen(2) backlog.
  ; Default Value: 128 (-1 on FreeBSD and OpenBSD)
  ;listen.backlog = 128
  
  ; Set permissions for unix socket, if one is used. In Linux, read/write
  ; permissions must be set in order to allow connections from a web server. Many
  ; BSD-derived systems allow connections regardless of permissions.
  ; Default Values: user and group are set as the running user
  ;                 mode is set to 0666
  ;listen.owner = www-data
  ;listen.group = www-data
  ;listen.mode = 0666
  
  ; List of ipv4 addresses of FastCGI clients which are allowed to connect.
  ; Equivalent to the FCGI_WEB_SERVER_ADDRS environment variable in the original
  ; PHP FCGI (5.2.2+). Makes sense only with a tcp listening socket. Each address
  ; must be separated by a comma. If this value is left blank, connections will be
  ; accepted from any ip address.
  ; Default Value: any
  ;listen.allowed_clients = 127.0.0.1
  
  ; ... and more that doesn't matter, just defaults
  </code></pre>
  
  <p>Both static files and PHP work in nginx web root (<code>ip/blah.html</code> or <code>ip/blah.php</code>), static files also work in user directories (<code>ip/~user/blah.html</code>) however PHP is giving 404 in user directories.</p>
  
  <p>Can someone help me fix my config?</p>
  
  <hr>
  
  <p><strong>Edit:</strong> some <code>ls -la</code>s incase it's a permission issue.</p>
  
  <pre><code>kvanb@pegasus:~$ ls -la
  total 32
  drwxr-xr-x 3 kvanb sudo  4096 Jan  4 04:04 .
  drwxr-xr-x 6 root  root  4096 Jan  4 01:36 ..
  -rw------- 1 kvanb kvanb  570 Jan  4 02:54 .bash_history
  -rw-r--r-- 1 kvanb sudo   220 Jan  4 01:36 .bash_logout
  -rw-r--r-- 1 kvanb sudo  3392 Jan  4 01:36 .bashrc
  -rw-r--r-- 1 kvanb sudo   675 Jan  4 01:36 .profile
  drwxr-xr-x 2 kvanb sudo  4096 Jan  4 03:41 public_html
  -rw------- 1 kvanb sudo  3303 Jan  4 04:04 .viminfo
  
  kvanb@pegasus:~/public_html$ ls -la
  total 20
  drwxr-xr-x 2 kvanb sudo 4096 Jan  4 03:41 .
  drwxr-xr-x 3 kvanb sudo 4096 Jan  4 04:04 ..
  -rwxr-xr-x 1 kvanb sudo   21 Jan  4 03:40 index.php
  -rwxr-xr-x 1 kvanb sudo   20 Jan  4 03:09 info.php
  -rw-r--r-- 1 kvanb sudo    4 Jan  4 03:41 test.html
  
  kvanb@pegasus:/usr/share/nginx/www$ ls -la
  total 20
  drwxr-xr-x 2 root root 4096 Jan  4 03:28 .
  drwxr-xr-x 3 root root 4096 Jan  4 01:34 ..
  -rw-r--r-- 1 root root  383 Jul  7  2006 50x.html
  -rw-r--r-- 1 root root  151 Oct  4  2004 index.html
  -rw-r--r-- 1 root root   20 Jan  4 03:28 info.php
  </code></pre>