FreeBSD: Nginx FastCGI PHP Configuration

by on October 9, 2008 · 10 comments· LAST UPDATED October 9, 2008

in , ,

Q. How do I configure PHP as FastCGI under FreeBSD Nginx webserver?

A. You can easily configure php as FastCGI application under Nginx for performance. You need following components:

[a] spawn-fcgi binary - For spawning a FastCGI process. This binary can be installed from Lighttpd webserver project. Nginx does not automatically spawn FCGI processes. You must start them separately using spawn-fcgi.

[b] start.php.sh : A shell script to stop / start / restart php fastcgi process. This script swap php process on 127.0.0.1 IP and 9000 port. Once backend is started Nginx can be configured to connect to PHP.

FreeBSD Install PHP5

If php5 is not installed type the following commands (make sure you select FastCGI option):
# cd /usr/ports/lang/php5
# make config
# make install clean

Fig.01 Enable FastCGI support by selecting FastCGI option

Fig.01 Enable FastCGI support by selecting FastCGI option

Also installed required php extensions such as php-msyql, php-gd and so on:
# cp /usr/local/etc/php.ini-recommended /usr/local/etc/php.ini
# cd /usr/ports/lang/php5-extensions/
# make install clean

Install spawn-fcgi

Grab latest spawn-fcgi from another Lighttpd installation or just install it as follows:
# pkg_add -r -v lighttpd
Sample output:

scheme:   [ftp]
user:     []
password: []
host:     [ftp.freebsd.org]
port:     [0]
document: [/pub/FreeBSD/ports/amd64/packages-7.0-release/Latest/lighttpd.tbz]
---> ftp.freebsd.org:21
looking up ftp.freebsd.org
connecting to ftp.freebsd.org:21
<<< 220 Welcome to freebsd.isc.org.
>>> USER anonymous
<<< 331 Please specify the password.
.....
.....
x lib/lighttpd/mod_access.so
x lib/lighttpd/mod_accesslog.a
x lib/lighttpd/mod_accesslog.la
x lib/lighttpd/mod_accesslog.so
x lib/lighttpd/mod_alias.a
x lib/lighttpd/mod_alias.la
x lib/lighttpd/mod_alias.so
x lib/lighttpd/mod_auth.a
x lib/lighttpd/mod_auth.la
.....
..

Now you can use /usr/local/bin/spawn-fcgi to swap process. If you want you can copy /usr/local/bin/spawn-fcgi to /root or other directory and just delete lighttpd package by typing the following commands:
# cp /usr/local/bin/spawn-fcgi /root/
# pkg_delete -v lighttpd-1.4.18_1
# cp /root/spawn-fcgi /usr/local/bin/spawn-fcgi

Now you can start PHP Fastcgi from command line as follows:
# /usr/local/bin/spawn-fcgi -a 127.0.0.1 -p 9000 -u www -g www -f /usr/local/bin/php-cgi
Where,

  • -a 127.0.0.1 : PHP FastCGI bind IP address, where Nginx will connect.
  • -p 9000: PHP FastCGI port number, where Nginx will connect.
  • -u www : PHP FastCGI username.
  • -g www : PHP FastCGI groupname.
  • -f /usr/local/bin/php-cgi : Path to PHP5 fastcgi binary.

Verify that php running as FastCGI, enter:
# sockstat -4 | grep 9000
Sample Output:

www      php-cgi    8998  0  tcp4   127.0.0.1:9000    *:*
www      php-cgi    8997  0  tcp4   127.0.0.1:9000    *:*
www      php-cgi    8996  0  tcp4   127.0.0.1:9000    *:*
www      php-cgi    8995  0  tcp4   127.0.0.1:9000    *:*
www      php-cgi    8994  0  tcp4   127.0.0.1:9000    *:*
www      php-cgi    8993  0  tcp4   127.0.0.1:9000    *:*

Sample Shell Script To Start / Stop PHP FastCGI process

#!/bin/sh
# NGINX FastCGI php5 startup shell script
# Feedback <vivek@nixcraft.com>
# http://bash.cyberciti.biz/web-server/fastcgi-php-server-start-stop-script/
# Set ME #
PROVIDES=php-cgi
LIGHTTPD_FCGI=/usr/local/bin/spawn-fcgi
SERVER_IP=127.0.0.1
SERVER_PORT=9000
SERVER_USER=www
SERVER_GROUP=www
PHP_CGI=/usr/local/bin/php-cgi
PGREP=/bin/pgrep
KILLALL=/usr/bin/killall
### No editing below ####
cmd=$1
 
pcgi_start(){
  	echo "Starting $PROVIDES..."
 	$LIGHTTPD_FCGI -a $SERVER_IP -p $SERVER_PORT -u $SERVER_USER -g $SERVER_GROUP -f $PHP_CGI
}
 
pcgi_stop(){
	echo "Killing $PROVIDES..."
	$KILLALL $PROVIDES
}
 
pcgi_restart(){
	pcgi_stop
	pcgi_start
}
 
pcgi_status(){
        $PGREP $PROVIDES > /dev/null
	[ $? -eq 0  ] && echo "$PROVIDES running" || echo "$PROVIDES NOT running"
 
}
 
pcgi_help(){
  	echo "Usage: $0 {start|stop|restart|status}"
}
 
 
case ${cmd} in
[Ss][Tt][Aa][Rr][Tt]) pcgi_start;;
[Ss][Tt][Oo][Pp]) pcgi_stop;;
[Rr][Ee][Ss][Tt][Aa][Rr][Tt]) pcgi_restart;;
[Ss][Tt][Aa][Tt][Uu][Ss]) pcgi_status ;;
*)      pcgi_help ;;
esac

Install above shell script:
# cd /tmp
# fetch http://bash.cyberciti.biz/dl/251.sh.zip
# unzip 251.sh.zip
# mv 251.sh /usr/local/etc/rc.d/php.cgi.sh
# chmod +x /usr/local/etc/rc.d/php.cgi.sh
# rm 251.sh.zip

To start php FastCGI, enter:
# /usr/local/etc/rc.d/php.cgi.sh start
# sockstat -4 | less

To stop php FastCGI, enter:
# /usr/local/etc/rc.d/php.cgi.sh stop

Connect Nginx Webserver To PHP FastCGI Process

Open your ngixn.conf file, enter:
# vi /usr/local/etc/nginx/nginx.conf
Append following config directives so that Nginx can pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000:

location ~ \.php$ {
            fastcgi_pass   127.0.0.1:9000;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  /websites/example.com/http$fastcgi_script_name;
            include        fastcgi_params;
    }

If your website is hosted at /home/www/theos.in/http, your config should look like as follows:

server {
	listen  80;
        server_name  theos.in www.theos.in;
 
        access_log  /var/log/nginx/theos.in/access.log  main;
 
        location / {
            root   /home/www/theos.in/http;
            index  index.php index.html index.htm;
        }
 
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   /usr/local/www/nginx-dist;
        }
 
       # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        location ~ \.php$ {
            fastcgi_pass   127.0.0.1:9000;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  /home/www/theos.in/http$fastcgi_script_name;
            include        fastcgi_params;
        }
 
        location ~ /\.ht {
            deny  all;
        }
}

Restart Nginx web server

# nginx -c /usr/local/etc/nginx/nginx.conf -t
# /usr/local/etc/rc.d/nginx restart

Test php with following sample script:

<?php
  phpinfo();
?>
TwitterFacebookGoogle+PDF versionFound an error/typo on this page? Help us!

{ 10 comments… read them below or add one }

1 George Bonev February 24, 2009 at 3:29 pm

Worked Like a charm / thx :)

Reply

2 Ed March 18, 2009 at 4:50 pm

Thanks for the great tutorial. Long life for freebsd and nginx!

Reply

3 Leo Vandewoestijne May 8, 2009 at 12:12 am

Maybe the port wasn’t available by writing your article, or maybe I’m confusing things… …but the step “Install spawn-fcgi”, can that be done without any lighttpd? Like:
pkg_add spawn-fcgi
?

Reply

4 symbol June 8, 2009 at 3:52 am

yea. and spawn_fcgi_enable=”YES” >> /etc/rc.conf seem to do the trick

or am i missing something that would come back to haunt me sometime later

Reply

5 Bash June 11, 2009 at 8:44 pm
6 ksil June 27, 2009 at 9:23 am

Hi, thank you for useful post. Let me cite this article in my Japanese blog:
http://d.hatena.ne.jp/ksil/20090627/1246093375

Reply

7 Dustin Sweigart July 3, 2009 at 2:36 pm

I set this up and it works great, but under high loads (testing with apache’s ab) the spawn-fcgi/php-cgi process dies and so my server stops being able to load PHP. I know I’m testing with an unrealistic load on my server, but I also don’t want others to be able to so easily break my server.
ab -n1000 -c200 http://websiteurl/

Does anyone else have this problem, and if so, does anyone know how to fix it?

Reply

8 nixCraft July 3, 2009 at 3:12 pm

Do you get any specific error in a log file? Also, specify your server config

Reply

9 Dustin Sweigart July 3, 2009 at 7:08 pm

my config: http://swigg.net/nginx.txt

Normally it runs fine, you can check out http://swigg.net/ if you’d like to see PHP running normally. But push the server really hard and whatever process exists after you call spawn-fcgi dies (as in it is no longer running)

[error] 24813#0: *1032 recv() failed (104: Connection reset by peer) while reading response header from upstream, client: 64.22.125.174, server: localhost, request: "GET / HTTP/1.0", upstream: "fastcgi://127.0.0.1:10005", host: "swigg.net"

[error] 24813#0: *3964 connect() failed (111: Connection refused) while connecting to upstream, client: 64.22.125.174, server: localhost, request: "GET / HTTP/1.0", upstream: "fastcgi://127.0.0.1:10005", host: "swigg.net"

Reply

10 Shatil December 26, 2010 at 3:28 am

Hi guys,

FreeBSD’s ports selection (at least 8.1′s—I’ve been using it for four hours now) has PHP 5.3.4+ now, which means PHP-FPM comes standard as long as you compile it through ports. With that, you can do away with needing spawn-fcgi, lighttpd, and the other nonsense that used to be necessary to get PHP + Nginx working.

Maybe you could post another post with that?

Reply

Leave a Comment

Tagged as: , , , , , , , , , , , ,

Previous Faq:

Next Faq: