Day 16 - FastCGI, second visit

A simple, newbie perspective on FastCGI deployment.

Deploying with FastCGI

Deployment can be tricky for any environment. Catalyst is no exception. Each server can have its own idiosyncrasies, and there are gotchas at every corner. Here is a guide to getting your application live deployed using FastCGI and Apache, on a pretty "uncooperative" server.

We took the FastCGI route because it offers nearly the same speed as mod_perl, but allows you to restart your app without restarting the whole Apache server. FastCGI also allows you to run multiple versions of the same application with the same web server.

There are three ways to go FastCGI: static, dynamic and external. External is the most flexible and the simplest way to restart your app without restarting the entire server.

Apache can communicate with the external server via a socket, or via a TCP connection. TCP offers the most flexibility in the end (the application can easily run on a different machine from the server), so this is the way we are going.

To configure your web server, adapt the following for use in your server's httpd.conf:

  FastCgiExternalServer
  /path/to/myapp/script/myapp_fastcgi.pl -host 127.0.0.1:55900
  Alias / /path/to/myapp/script/myapp_fastcgi.pl/
  # or Alias /myapp/ /path/to/myapp/script/myapp_fastcgi.pl/ to run at a non root location

Launch your application as

  $ script/myapp_fastcgi.pl -e -l 127.0.0.1:55900 -p /tmp/myapp.pid

The -e switch causes your application's STDERR output to go to the screen, instead of ending up in Apache's error log. Launch myapp_fastcgi.pl --help and check if its usage displays the "-e" parameter. If not, you need to have the latest version of "Catalyst::Devel" (version 1.02 at the time of writing):

  $ perl -MCPAN -e "install Catalyst::Devel"

You also need to regenerate the helper scripts. You can do this by launching

  $ catalyst.pl -force myapp

Writing a start/stop daemon

Once you've finished development, you will probably want to be able to start your FastCGI server non-interactively when your web server starts or when your operating system boots. For this, it's most efficient to write a start/stop daemon. Here's a sample start/stop daemon, tested using the bash shell on FreeBSD:



  #!/bin/bash
  myapp = mycoolapp
  myapp_path = /path/to/myapp
  port2Apache = 55900

  function start {
    echo "Restarting... Press Ctrl+Z, then type: 'bg', Enter"
    # the "-d" switch to myapp_fastcgi.pl should save us from asking the user
    # to run 'bg', but unfortunately it doesn't work in all instances
    # nohup also doesn't work because myapp_fastcgi terminates when this script terminates
    ${myapp_path}/script/${myapp}_fastcgi.pl -e -l 127.0.0.1:$port2Apache -p /tmp/${myapp}.pid 2> ${myapp_path}/${myapp}_stderr.log
  }

  function stop {
    echo -n "Waiting for existing connections to finish..."
    while [[ `netstat | grep $port2Apache | grep ESTABLISHED` ]]; do
    sleep 1
    echo -n "."
    done

    echo " OK."
    echo -n "Terminating existing instance..."

    if [[ -r /tmp/${myapp}.pid ]]; then
      kill `cat /tmp/${myapp}.pid` 2 > /dev/null;
      while [[ -r /tmp/${myapp}.pid ]]; do
        echo -n "."
        sleep 1
        rm /tmp/$myapp.pid 2> /dev/null
      done
    fi
    echo " OK."
  }

  case $1 in
  'start' )
    start;;
  'stop' )
    stop;;
  'restart' )
    stop
    start;;
  esac




Wrap up

This is a nice simple step by step deployment guide for FastCGI on Apache. Please report any problems you have with this guide to the Catlyst Mailing List (http://lists.rawmode.org/mailman/listinfo/catalyst).

For further information, please see the Catalyst::Engine::FastCGI and Catalyst::Cookbook documentation.

AUTHOR

Vlad Dan Dascalescu <ddascalescu@gmail.com> Kieren Diment <diment@gmail.com>