Script init.d pour php-cgi (spawn-fcgi-php)

J’ai longtemps galéré pour trouver un script décent pour lancer php-cgi via init.d utilisant start-stop-daemon.

Intérêt de spawn-fcgi plutôt qu’un mod apache?

  • Privilege separation without needing a suid-binary or running a server as root.
  • You can restart your web server and the FastCGI applications without restarting the others.
  • You can run them in different chroot()s.
  • Running your FastCGI applications doesn’t depend on the web server you are running, which allows for easier testing of/migration to other web servers.

C’est ce dernier point qui m’a fait craquer, apache, nginx, cherokee, autres, tous ou presque supportent un accès à php de cette façon

Je voulais donc vous faire profiter de ma découverte.

#! /bin/sh
### BEGIN INIT INFO
# Provides:          spawn-fcgi-php
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Start/stop php-cgi using spawn-fcgi
# Description:       Start/stop php-cgi using spawn-fcgi
### END INIT INFO

# Author: Richard Laskey 
# for more information, please visit http://rlaskey.org/

PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC="php-cgi via spawn-fcgi"
NAME=spawn-fcgi-php
PIDFILE=/var/run/$NAME.pid
DAEMON=/usr/bin/spawn-fcgi

# Specify the requests limit for a php instance (prevent memory leaks)
PHP_FCGI_MAX_REQUESTS=500
export PHP_FCGI_MAX_REQUESTS;

# you can change the arguments for spawn-fcgi here:
	# -C 3 implies three children processes
	# -a 127.0.0.1 binds to the loopback device
	# -p XYZ sets the the listening port to XYZ
	# -u and -g set the user/group the process runs as
	# -f is deprecated; --  is the preferred syntax
DAEMON_ARGS="-C 3 -a 127.0.0.1 -p 9001 -u hcblog -g www-hcblog -P $PIDFILE -- /usr/bin/php-cgi $PHP_ARGS"
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.2-14) to ensure that this file is present
# and status_of_proc is working.
. /lib/lsb/init-functions

#
# Function that starts the daemon/service
#
do_start()
{
	# Return
	#   0 if daemon has been started
	#   1 if daemon was already running
	#   2 if daemon could not be started
	# --exec has been replaced by --startas
	start-stop-daemon --start --quiet --pidfile $PIDFILE --startas $DAEMON --test > /dev/null \
		|| return 1
	start-stop-daemon --start --quiet --pidfile $PIDFILE --startas $DAEMON -- \
		$DAEMON_ARGS \
		|| return 2
	# Add code here, if necessary, that waits for the process to be ready
	# to handle requests from services started subsequently which depend
	# on this one.  As a last resort, sleep for some time.
}

#
# Function that stops the daemon/service
#
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
	# removed --name $NAME since the running process is not spawn-fcgi
	start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE
	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.
	# commenting out this line; probably won't find processes via --exec
	# 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
	;;
  status)
       # added -p $PIDFILE, can't find process otherwise
       status_of_proc -p $PIDFILE "$DAEMON" "$NAME" && exit 0 || exit $?
       ;;
  restart|force-reload)
	# removed  "$NAME", was repetitive
	log_daemon_msg "Restarting $DESC"
	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|status|restart|force-reload}" >&2
	exit 3
	;;
esac

:

Il vous faut le binaire spawn-fcgi bien sur ;)
N’oubliez pas de chmoder +x le fichier créé dans /etc/init.d/ et de lui passer un tit coup de update-rc.d spawn-fcgi-php defaults pour le lancer automatiquement au démarrage ;-)

Quelques liens de référence :

Posted in Web by El Gnap at January 2nd, 2012.
Tags: , , , , ,

3 Responses to “Script init.d pour php-cgi (spawn-fcgi-php)”

  1. […] vous avez pris le script que je fourni pour spawn-fcgi-php, alors c’est déjà établi sur localhost par le paramètre du daemon suivant : -a 127.0.0.1 […]

  2. […] la configuration que j’avais donnée auparavant pour charger php via FCGI, les enfants n’étaient jamais “killés” et les heures passant le serveur fastCGI […]

  3. zygis says:

    Very nice script. Works like a charm.