TurnKey Linux Virtual Appliance Library

Wire: Privacy is a Right

I had intended to create a patch for Cory Doctorow's Wire initiative (http://wire.0xf.nl/). But I get stuck. Following with build notes.

Build Notes and Sticking Point

Set hostname

apt-get install -y nginx python-pip supervisor python-dev build-essential
pip install fabric flask redis flask-markdown flask-uploads whirlpool markdown gunicorn meinheld
cd /var/www
git clone git://github.com/radiosilence/wire.git
cd /tmp
wget http://ftp.dlitz.net/pub/dlitz/crypto/pycrypto/pycrypto-2.3.tar.gz
tar xvzf pycrypto-2.3.tar.gz
cd pycrypto-2.3
python setup.py install
cd /var/www/wire
fab install

That's where I get stuck. fab install doesn't seem to know what install means, unless I use pip install pycrypto; in which case, it knows what install means but tells me I need a newer version of pycrypto.

All that aside, I've never touched nginx and don't understand the instructions for fast-cgi.



Liraz Siri's picture

Tips on Nginx with Fast CGI

I don't have any experience with Wire yet so I can't comment on that specifically save that it sounds like a great project.

Regarding Nginx, I doubt you need to use it specifically and I recommend you try setting this up with Apache instead, especially if you have more experience with that. There's really nothing special about nginx except that it is more resource efficient than Apache, at the price of being more difficult to configure.

But in case you insist on Nginx approach I have setup nginx with fast-cgi before so I might be able to help you with that. In a nutshell you need to understand that nginx doesn't know how to run PHP directly like Apache does when you install mod_php.

So to run PHP you setup a separate application server, which is really just a fancy way of saying that there is a PHP process running along side nginx that handles PHP requests and nginx is configured to pass along PHP requests via the Fast CGI protocol.

Here's the configuration directive I use configure nginx to pass along PHP requests:

location ~ \.php$ {
        fastcgi_pass unix:/var/run/nginx/php-fastcgi.sock;
        fastcgi_index index.php;
}

Here's the /etc/init.d/php-fastcgi script I use to start the PHP process:

#! /bin/sh
### BEGIN INIT INFO
# Provides:          php-fastcgi
# Required-Start:    $all
# Required-Stop:     $all
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Start and stop php-cgi in external FASTCGI mode
# Description:       Start and stop php-cgi in external FASTCGI mode
### END INIT INFO

# Author: Kurt Zankl <kz@xon.uni.cc>

# Do NOT "set -e"

PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
NAME=php-fastcgi
DESC="php-cgi in external FASTCGI mode"
DAEMON=/usr/bin/php-cgi
PIDFILE=/var/run/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME

# Exit if the package is not installed
[ -x "$DAEMON" ] || exit 0

# Read configuration variable file if it is present
[ -r /etc/default/$NAME ] && . /etc/default/$NAME

# Load the VERBOSE setting and other rcS variables
. /lib/init/vars.sh

# Define LSB log_* functions.
# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
. /lib/lsb/init-functions

# If the daemon is not enabled, give the user a warning and then exit,
# unless we are stopping the daemon
if [ "$START" != "yes" -a "$1" != "stop" ]; then
        log_warning_msg "To enable $NAME, edit /etc/default/$NAME and set START=yes"
        exit 0
fi

# Process configuration
export PHP_FCGI_CHILDREN PHP_FCGI_MAX_REQUESTS
DAEMON_ARGS="-q -b $PHP_FCGI_SOCKET"



do_start()
{
        # Return
        #   0 if daemon has been started
        #   1 if daemon was already running
        #   2 if daemon could not be started
        start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \
                || return 1
        start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON \
                --background --make-pidfile --chuid $EXEC_AS_USER --startas $DAEMON -- \
                $DAEMON_ARGS \
                || return 2
}

do_stop()
{
        # Return
        #   0 if daemon has been stopped
        #   1 if daemon was already stopped
        #   2 if daemon could not be stopped
        #   other if a failure occurred
        start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE > /dev/null # --name $DAEMON
        RETVAL="$?"
        [ "$RETVAL" = 2 ] && return 2
        # Wait for children to finish too if this is a daemon that forks
        # and if the daemon is only ever run from this initscript.
        # If the above conditions are not satisfied then add some other code
        # that waits for the process to drop all resources that could be
        # needed by services started subsequently.  A last resort is to
        # sleep for some time.
        start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON
        [ "$?" = 2 ] && return 2
        # Many daemons don't delete their pidfiles when they exit.
        rm -f $PIDFILE
        return "$RETVAL"
}

case "$1" in
  start)
        [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
        do_start
        case "$?" in
                0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
                2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
        esac
        ;;

  stop)
        [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
        do_stop
        case "$?" in
                0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
                2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
        esac
        ;;
  restart|force-reload)
        log_daemon_msg "Restarting $DESC" "$NAME"
        do_stop
        case "$?" in
          0|1)
                do_start
                case "$?" in
                        0) log_end_msg 0 ;;
                        1) log_end_msg 1 ;; # Old process is still running
                        *) log_end_msg 1 ;; # Failed to start
                esac
                ;;
          *)
                # Failed to stop
                log_end_msg 1
                ;;
        esac
        ;;
  *)
        echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload}" >&2
        exit 3
        ;;
esac

:

My /etc/default/php-fastcgi file:

START=yes

# Which user runs PHP? (default: www-data)

EXEC_AS_USER=www-data:www-data

# Host and TCP port for FASTCGI-Listener (default: localhost:9000)

PHP_FCGI_SOCKET=/var/run/nginx/$NAME.sock

# Environment variables, which are processed by PHP

PHP_FCGI_CHILDREN=2
PHP_FCGI_MAX_REQUESTS=1000

Got it?

Jeremy's picture

Ahh so that's why I don't use NginX

Hehe! :) I stuggle enough with Apache!

BTW welcome back Rik. Good to see you launch back into it with a couple of great looking appliances! :) Look forward to hearing/seeing more from you and your students.

I just spent 2 months with

I just spent 2 months with that kind of web server idea....it's still a side project along with the tiny server project I mentioned elsewhere here.  I managed to get Hiawatha, nginx and cherokee to all work on a few slim distros like archlinux.   It's a worthy goal to make a minimum high security web server...it has it's drawbacks too..like Liraz said.  I found the "simple" config files like nginx.conf still to convoluted even when they were well doc'ed.

Cherokee had the closest thing to easy with their web interface but even that bogs down into a doc search time eater.   At least TKL has simplified the config issue to a good degree.  It makes them the only place I can find to overcome that issue as a newbie.

Those config files will be improved to a simple interface someday and then the litttle servers will be even more the rage then they are right now. That's another goal I would participate in, btw. Everybody is racing to simplify web work..it just isn't here yet in most cases I have found.  Gettin there.


Post new comment

The content of this field is kept private and will not be shown publicly. If you have a Gravatar account, used to display your avatar.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <p> <span> <div> <h1> <h2> <h3> <h4> <h5> <h6> <img> <map> <area> <hr> <br> <br /> <ul> <ol> <li> <dl> <dt> <dd> <table> <tr> <td> <em> <b> <u> <i> <strong> <font> <del> <ins> <sub> <sup> <quote> <blockquote> <pre> <address> <code> <cite> <strike> <caption>

More information about formatting options

Leave this field empty. It's part of a security mechanism.
(Dear spammers: moderators are notified of all new posts. Spam is deleted immediately)