Skip to content


PHP FastCGI with nginx on Ubuntu

One of the questions arising during Apache to nginx migration is “How to run my PHP based applications?”. Nginx supports PHP only via FastCGI interface (which is the prefered way of running PHP for me anyway). There are dozens of HOWTOs for configuring nginx to direct .php files requests to FastCGI, but only a few covering the topic of running the PHP FastCGI backend. None of them covers the correct way, though.

Let me show you how to get it right…

PHP CGI binary is perfectly able running a FastCGI interface by itself. There is no need to run it with an external wrapper. No need to install anything more than the PHP itself.

Just install the php-cgi: aptitude install php5-cgi and run: php-cgi -b 127.0.0.1:9000. Done. You have PHP running FastCGI interface on localhost on port 9000. You can connect to it from nginx using fastcgi_pass 127.0.0.1:9000;.

php-cgi binary is configurable using environment variables. The most interesting ones are PHP_FCGI_CHILDREN telling how many child processes to launch and PHP_FCGI_MAX_REQUESTS telling how many requests each child need to process before termination (and launching another one).

I use this command (wrapped in a simple script) on my development machine. But server needs something to launch the PHP FastCGI processes on boot. Here is a simple init.d script to get the php-cgi running as a normal system service:

#!/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

Put it in /etc/init.d/php-fastcgi, make it executable chmod +x /etc/init.d/php-fastcgi, unleash the daemons /etc/init.d/php-fastcgi start and finally make it permanent update-rc.d php-fastcgi defaults.

May the nginx + php-cgi fastcgi serve you well.

P.S. Here’s a simple snippet of nginx configuration to make use of the described service:


server {
        listen          80;
        server_name     example.com;

        access_log      /var/log/nginx/example.com.access_log;
        error_log       /var/log/nginx/example.com.error_log warn;

        root            /var/www/example.com/public;

        index           index.php index.html;
        fastcgi_index   index.php;

        location ~ \.php {
                include /etc/nginx/fastcgi_params;
                keepalive_timeout 0;
                fastcgi_param   SCRIPT_FILENAME  $document_root$fastcgi_script_name;
                fastcgi_pass    127.0.0.1:9000;
        }
}

Posted in HowTo.

Tagged with , , , .


27 Responses

Stay in touch with the conversation, subscribe to the RSS feed for comments on this post.

  1. Anonymous says

    Thanks for this article, I found it very helpful. I searched long for an Nginx + PHP method which doesn’t necessitate the use of something like php-apm or spawn-fcgi.
    I don’t understand the infatuation of wrappers and poorly documented patches which seem to permeate the Nginx+PHP userbase. Oh well.
    Thanks again!

  2. Rohan says

    Thanks so much for this guide. I have used spawn-fcgi previously and had a feeling there had to be a simpler solution. Thanks again

  3. vinhboy says

    Thanks for this simple method.
    I was doing this on my slicehost slice.
    My only problem was start-stop-daemon: command not found
    Just had to add /sbin/start-stop-daemon

  4. James says

    if I run php5-cgi -b 127.0.0.1:9000 or php-cgi -b 127.0.0.1:9000 it just hangs indefinately util I crtl-c out. Was hoping to try your method, but kinda at a standstill now.

    Thanks

  5. Tomasz Sterna says

    What do you expect it to do? :D It’s a FastCGI server. Just connect your HTTP server to it’s 9000 port.

  6. John says

    Thanks for this, it’s a lot simpler than other ‘recipes’ I’ve looked at in the past.

  7. Piotrek says

    I added some lines to avoid passing nonexistent php files to fastcgi:


    (...)
    location ~ \.php {
    if (!-e $request_filename) {
    return 404;
    }
    (...)

    the rest is as above

  8. Jacky says

    Thanks for this simple method., I found it very helpful. I searched long for an Nginx + PHP method

  9. Andrew says

    You rule! :)
    Thank you, the documentation is the main problem with NginX. This article explains why there is no spawn-fcgi script in NginX.

  10. C. Spencer Beggs says

    Great tutorial. THis got me running PHP5 with nginx on Ubuntu on Slicehost. It’s a great combo, if you ask me.

  11. Horse says

    Good method/

  12. Roberto says

    I can’t make it work… please help !

    I keep getting the 404 page. Maybe my settings are wrong because no .php file can be found. I don’t understand what’s this line for
    fastcgi_param SCRIPT_FILENAME /var/www/nginx-default$fastcgi_script_name;

    should I have my site’s path instead ?

    thanks!

  13. Tomasz Sterna says

    There is nothing about “/var/www/nginx-default” in my article. Where did you get it from?

  14. Roberto says

    I meant:
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    anyhow.. I got something running because the common phpinfo.php works fine.

    But I can’t load the mysql.so module… You seem to know a lot about this.. Can you help me please ?

  15. Matthew C says

    You’re a legend! I’ve always wanted to setup nginx without using spawn-fcgi (from lighttpd).

    Thanks for the awesome article! :)

  16. Gianluca DV says

    Thanks!
    You saved my day!

  17. Thankful guy says

    Worked for me. Thanks!

  18. Steve Steiner says

    Thank you! I’m just separating PHP from Apache to run Apache in Worker MPM mode and this was a great help.

    Like most people, I think, I found lots of more complicated ways to run PHP but this one’s fast, works, and is dead simple to set up.

  19. Dimas says

    Tomasz, I found your article very useful having come from an article which recommended the use of lighttpd spawn-cgi … for some reason I was getting 502 bad gateway errors after prolonged use of the nginx+php server (not quite sure why yet) … Can you expand on the CHILDREN and REQUESTS vars and their implications on memory usage, what should the laymen be aware of. Thanks a lot!

Continuing the Discussion

  1. Slicehost Setup: Ubuntu + Nginx + PHP + MySQL – Vinh Pham linked to this post on 3 November 2009

    [...] There are bunch of tutorials out there on how to achieve this, but the most SIMPLE one is here: http://tomasz.sterna.tv/2009/04/php-fastcgi-with-nginx-on-ubuntu/ [...]

  2. Slicehost Setup: Ubuntu + Nginx + PHP + MySQL | TheUnical Technologies Blog linked to this post on 24 December 2009

    [...] There are bunch of tutorials out there on how to achieve this, but the most SIMPLE one is here: http://tomasz.sterna.tv/2009/04/php-fastcgi-with-nginx-on-ubuntu/ [...]

  3. Lightweight Wordpress on Slicehost | Boris Smus linked to this post on 26 February 2010

    [...] high profile sites. Seeking help from the internet, I eventually came across Thomasz Sterna’s php-fastcgi init script and adapted it for my slice, [...]

  4. How to set up nginx with PHP on Ubuntu « Igor Partola linked to this post on 1 March 2010

    [...] how to marry nginx to PHP (to run a WordPress blog for example). The best guide I found so far is this one. I built upon it to create the simplest nginx+FastCGI/PHP setup [...]

  5. VPSLink – Ubuntu 9.4 Mail Server from Scratch « Zaries’s Blog linked to this post on 2 March 2010

    [...] get fascgi to start on boot the following script from http://tomasz.sterna.tv/2009/04/php-fastcgi-with-nginx-on-ubuntu/ must be created and its permissions [...]

  6. nginx + fastcgi PHP » Tuinslak linked to this post on 21 March 2010

    [...] there’s a PHP page as well, I had to set up fastcgi with PHP. I mainly followed this tutorial to try to get PHP [...]

  7. 配置nginx笔记 – 黑白dè独舞 linked to this post on 21 July 2010 (2 weeks ago)

    [...] http://tomasz.sterna.tv/2009/04/php-fastcgi-with-nginx-on-ubuntu/ This entry was posted in 有点儿专业 and tagged django, nginx, rewrite, wordpress. Bookmark the permalink. ← OPhone SDK一瞥 [...]

  8. How To Install NGINX Web Server linked to this post on 28 July 2010 (3 days ago)

    [...] As you may have noticed, we have installed php-cgi, that is because we will be running a FastCGI interface. There are some articles online which recommend using lighttpd for its FastCGI interface, this is totally not needed. PHP has its own FastCGI interface which works perfectly well (thanks to Tomasz Sterna for a great article on FastCGI with Nginx) [...]



Some HTML is OK

or, reply to this post via trackback.