First thing, I recommend keeping all your typical FCGI settings in a single file and importing them.
For example you might have an /etc/nginx/fastcgi.conf file that looks like this:
#fastcgi.conf
fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFTWARE nginx;
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param DOCUMENT_ROOT $document_root;
fastcgi_param SERVER_PROTOCOL $server_protocol;
fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;
# PHP only, required if PHP was built with --enable-force-cgi-redirect
#fastcgi_param REDIRECT_STATUS 200;
This allows you to keep your individual FCGI configurations as simple as possible.
To use Nginx + Virtual Host + PHP you should ommit the SCRIPT_NAME variable in order for PHP to choose the correct DOCUMENT_ROOT.
Spawning a FastCGI Process
Unlike Apache or Lighttpd, Nginx does not automatically spawn FCGI processes. You must start them separately. In fact, FCGI is a lot like proxying. There's a few ways to start FCGI programs, I happen to like using the spawn-fcgi program that comes with Lighttpd. This example shows starting an instance of PHP4 on port 10004 and PHP5 on port 10005 (adjust paths accordingly):
/usr/local/bin/spawn-fcgi -a 127.0.0.1 -p 10004 -u lighttpd -g lighttpd -f /usr/lib/php4/bin/php-cgi /usr/local/bin/spawn-fcgi -a 127.0.0.1 -p 10005 -u lighttpd -g lighttpd -f /usr/lib/php5/bin/php-cgi
NOTE: In order to use lighttpd's spawn-fcgi process like this you'll need to do one of three things:
1. Verify (and if needed set) the proper permissions on /var/lib/php/session
$ cd /var/lib/php $ ls -l drwxrwx--- 2 root apache 4096 Nov 9 13:56 session $ chown root:lighttpd session $ ls -l drwxrwx--- 2 root lighttpd 4096 Nov 9 13:56 session
2. Change the php.ini to reflect a different session directory
cd /var/my/session mkdir dir chown root:lighttpd dir vi /etc/php.ini change session.save_path = "/var/lib/php/session" to session.save_path = "/var/my/session/dir"
3. Or just use the apache user/group for the FastCGI processes (I don't use the apache user for anything else on my system, and it's already non-privileged).
/usr/local/bin/spawn-fcgi -a 127.0.0.1 -p 10004 -u apache -g apache -f /usr/lib/php4/bin/php-cgi /usr/local/bin/spawn-fcgi -a 127.0.0.1 -p 10005 -u apache -g apache -f /usr/lib/php5/bin/php-cgi
Connecting Nginx to a running FastCGI Process
Now that the FCGI process is running, we must tell Nginx to proxy requests to it via the FCGI protocol:
http {
index index.php;
root /var/www/htdocs;
# .php and .php4 sent to php4
location ~ .*\.php4?$ {
include /etc/nginx/fcgi.conf;
fastcgi_pass 127.0.0.1:10004;
fastcgi_index index.php;
}
# .php5 sent to php5
location ~ .*\.php5$ {
include /etc/nginx/fcgi.conf;
fastcgi_pass 127.0.0.1:10005;
fastcgi_index index.php;
}
}
Restart Nginx.
Secure your upload directory!!
Too many example configs fail to secure the "uploads" directory of the application. Remember that if someone can upload a file named xyz.php and the uploads dir is publically accessible then you have given the attacker an easy way to insert PHP onto your site...
So if your app has an upload dir "/images/" then adjust your fastcgi call along the lines of:
http {
index index.php;
root /var/www/htdocs;
# .php
location ~ .*\.php$ {
include /etc/nginx/fcgi.conf;
if ( $uri !~ "^/images/") {
fastcgi_pass 127.0.0.1:10004;
}
fastcgi_index index.php;
}
}
