upstart-supervised init script for Apache?
I want to run apache on Ubuntu 10.04, and use the nice supervision stuff in upstart (I'm not just talking about the apache init script, but proper service supervision a la daemontools - which is to say, restarting apache when it dies, things like that).
Does anyone have a running upstart config for supervising apache on ubuntu 10.04?
The Googles have been no help to me, but it could be that my google-fu is weak.
Solution 1:
Woooo!
I've written my own version that is pretty much working - with some conf file hacking, and using -D NO_DETACH
.
First up, I had to set User
, Group
and PidFile
in /etc/apache2/apache2.conf
manually, rather than have them coming in from /etc/apache2/envvars
. I couldn't work out a way to get those vars to be exported properly (I tried both env
and export
as per http://manpages.ubuntu.com/manpages/lucid/man5/init.5.html, but no good).
root@lucid:/etc/apache2# diff -u apache2.conf.orig apache2.conf
--- apache2.conf.orig 2010-09-20 13:46:33.857868534 +0930
+++ apache2.conf 2010-09-20 13:47:22.377842204 +0930
@@ -63,7 +63,7 @@
# identification number when it starts.
# This needs to be set in /etc/apache2/envvars
#
-PidFile ${APACHE_PID_FILE}
+PidFile /var/run/apache2.pid
#
# Timeout: The number of seconds before receives and sends time out.
@@ -142,8 +142,8 @@
</IfModule>
# These need to be set in /etc/apache2/envvars
-User ${APACHE_RUN_USER}
-Group ${APACHE_RUN_GROUP}
+User www-data
+Group www-data
#
# AccessFileName: The name of the file to look for in each directory
Then, this is my working /etc/init/apache2.conf
:
# apache2 - http server
#
# Apache is a web server that responds to HTTP and HTTPS requests.
# Required-Start: $local_fs $remote_fs $network $syslog
# Required-Stop: $local_fs $remote_fs $network $syslog
description "apache2 http server"
start on runlevel [2345]
stop on runlevel [!2345]
pre-start script
mkdir -p /var/run/apache2 || true
install -d -o www-data /var/lock/apache2 || true
# ssl_scache shouldn't be here if we're just starting up.
# (this is bad if there are several apache2 instances running)
rm -f /var/run/apache2/*ssl_scache* || true
end script
# Give up if restart occurs 10 times in 30 seconds.
respawn limit 10 30
exec /usr/sbin/apache2 -D NO_DETACH
respawn
I can do start|stop|status|reload apache2
and get meaningful results; if I kill -9
the master apache process, it gets respawned pretty much immediately, and it starts and stops on boot as expected. So it's working reasonably well I reckon.
There were things I tried that I could not get working.
- Tried to remove
-D NO_DETACH
, in conjunction with:
expect fork expect daemon
That failed to start the service.
- Tried to use a similar method to
/etc/apache2/envvars
to populate the${APACHE_*}
variables:
export APACHE_RUN_USER=www-data export APACHE_RUN_GROUP=www-data export APACHE_PID_FILE=/var/run/apache2.pid
That failed to start, and produced an error about apache2: bad user name ${APACHE_RUN_USER}
.
-
Tried console output and console default options; at this point I was really just flailing about trying to get meaningful error messages. Seemed to make no difference.
console output
-
This was useful for debugging apache messages:
exec /usr/sbin/apache2 -X -e debug -E /var/log/apache2/foo.log
-
This was another attempt to not modify
/etc/apache2/apache2.conf
that failed:exec APACHE_RUN_USER=www-data APACHE_RUN_GROUP=www-data APACHE_PID_FILE=/var/run/apache2.pid /usr/sbin/apache2 -D NO_DETACH -e debug -E /var/log/apache2/foo.log
Solution 2:
Well, this script worked for me:
# apache2 - http server
#
# Apache is a web server that responds to HTTP and HTTPS requests.
# Required-Start: $local_fs $remote_fs $network $syslog
# Required-Stop: $local_fs $remote_fs $network $syslog
description "apache2 http server"
start on runlevel [2345]
stop on runlevel [!2345]
pre-start script
mkdir -p /var/run/apache2 || true
install -d -o www-data /var/lock/apache2 || true
# ssl_scache shouldn't be here if we're just starting up.
# (this is bad if there are several apache2 instances running)
rm -f /var/run/apache2/*ssl_scache* || true
end script
limit cpu 300 300
env APACHE_RUN_USER=www-data
env APACHE_RUN_GROUP=www-data
env APACHE_PID_FILE=/var/run/apache2.pid
# Give up if restart occurs 10 times in 30 seconds.
respawn limit 10 30
exec /usr/sbin/apache2 -D NO_DETACH
respawn
Solution 3:
I've also hit this problem, however I used another approach. The easiest way to get the env variables is using the source command and pointing it to the apache envvars file, then you can run apache with the -D FOREGROUND options
so basically you need a script which looks like this (mine is in /etc/apache2/apache2_foreground.sh ) :
#!/bin/bash
read pid cmd state ppid pgrp session tty_nr tpgid rest < /proc/self/stat
trap "kill -TERM -$pgrp; exit" EXIT TERM KILL SIGKILL SIGTERM SIGQUIT
source /etc/httpd/envvars
apache2 -D FOREGROUND
Then you make it executable and point the supervisor to its location, you also need to use the stopsignal 6
command=/etc/apache2/apache2_foreground.sh
stopsignal=6
The two first lines in the script catch the process group ID of the script, and set a trap which runs on signals passed to the process - this trap executes a kill with a negative process ID of the parent that runs all apache2 processes (the script itself) - killing with a negative PID means to kill all the children of such process aswell (so in this case all apache2 processes), without that I wasn't able to make supervisor kill the apache2 processes
The stopsignal 6 is used as I couldn't fin any other signal that could invoke the trap, the 9 cannot be caught, and 2 and 3 don't do anything (the script isn't killed)
after that it should work smoothly, with no modifications to the apache2 configuration whatsoever