FastCGI Setup¶
This guide covers setting up FastCGI with NGINX, including spawning processes and securing upload directories.
FastCGI Parameters¶
Keep your typical FCGI settings in a single file (/etc/nginx/fastcgi.conf or /etc/nginx/fastcgi_params):
# 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;
Tip
You may want to replace $document_root with an actual path to avoid "script not found" errors.
Spawning FastCGI Processes¶
Unlike Apache or Lighttpd, NGINX does not automatically spawn FCGI processes. You must start them separately.
Manual Start¶
php -b 127.0.0.1:9000
Init Script (Debian/Ubuntu)¶
#!/bin/bash
BIND=127.0.0.1:9000
USER=www-data
PHP_FCGI_CHILDREN=15
PHP_FCGI_MAX_REQUESTS=1000
PHP_CGI=/usr/bin/php-cgi
PHP_CGI_NAME=`basename $PHP_CGI`
PHP_CGI_ARGS="- USER=$USER PATH=/usr/bin PHP_FCGI_CHILDREN=$PHP_FCGI_CHILDREN PHP_FCGI_MAX_REQUESTS=$PHP_FCGI_MAX_REQUESTS $PHP_CGI -b $BIND"
RETVAL=0
start() {
echo -n "Starting PHP FastCGI: "
start-stop-daemon --quiet --start --background --chuid "$USER" --exec /usr/bin/env -- $PHP_CGI_ARGS
RETVAL=$?
echo "$PHP_CGI_NAME."
}
stop() {
echo -n "Stopping PHP FastCGI: "
killall -q -w -u $USER $PHP_CGI
RETVAL=$?
echo "$PHP_CGI_NAME."
}
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
stop
start
;;
*)
echo "Usage: php-fastcgi {start|stop|restart}"
exit 1
;;
esac
exit $RETVAL
Save to /etc/init.d/php-fcgi and install:
update-rc.d php-fcgi defaults
service php-fcgi start
Connecting NGINX to FastCGI¶
location ~ \.php$ {
include /etc/nginx/fastcgi_params;
fastcgi_pass 127.0.0.1:9000;
}
Securing Upload Directories¶
Critical Security Issue
If someone uploads xyz.php to a publicly accessible uploads directory, they can execute arbitrary PHP code on your server!
Prevent PHP execution in upload directories:
location ~ \.php$ {
include /etc/nginx/fastcgi_params;
if ($uri !~ "^/images/") {
fastcgi_pass 127.0.0.1:9000;
}
}
Or use a separate location block:
# Block PHP in uploads
location ~* ^/uploads/.*\.php$ {
deny all;
}
# Normal PHP handling
location ~ \.php$ {
include /etc/nginx/fastcgi_params;
fastcgi_pass 127.0.0.1:9000;
}
Modern Alternative
Consider using PHP-FPM (FastCGI Process Manager) instead of spawning php-cgi manually. See the PHP-FPM guide.