Skip to content

Instantly share code, notes, and snippets.

@gfrey
Created January 17, 2014 11:34
Show Gist options
  • Save gfrey/8472007 to your computer and use it in GitHub Desktop.
Save gfrey/8472007 to your computer and use it in GitHub Desktop.
Upstart script for haproxy with support for reload.
description "Properly handle haproxy"
start on startup
env PID_PATH=/var/run/haproxy.pid
env BIN_PATH=/usr/sbin/haproxy
script
exec /bin/bash <<EOF
$BIN_PATH -f /etc/haproxy.cfg -D -p $PID_PATH
trap "$BIN_PATH -f /etc/haproxy.cfg -p $PID_PATH -sf \\\$(cat $PID_PATH)" SIGHUP
trap "kill -TERM \\\$(cat $PID_PATH) && exit 0" SIGTERM SIGINT
while true; do # Iterate to keep job running.
sleep 1 # Don't sleep to long as signals will not be handled during sleep.
done
EOF
end script
@gfrey
Copy link
Author

gfrey commented Jan 18, 2014

HAProxy Upstart Script

haproxy can perfectly be used with upstart. There is one problem though: haproxy uses a pretty weird pattern for configuration reload.

  1. A new process is started given the list of PIDs of the running processes.
  2. New processes are started using the current configuration.
  3. When everything is ready to server the old processes are either terminated (-st option) or asked to not accept new connections and finish when done serving (-sf option).
  4. The new processes start serving.

Upstart assumes that reloading configuration will be triggered by the SIGHUP signal. This is why I wrote a small wrapper script, that runs forever (sleeping all the time), just waiting for signals to sent forward to the currently running haproxy instance.

The major problem was getting the escaping of subshells in the signal traps right.

@quinn
Copy link

quinn commented Oct 3, 2014

Would this work with respawn? I would assume not because the wrapper would not know that haproxy had crashed / exited.

@gfrey
Copy link
Author

gfrey commented Oct 7, 2014

You're right, of course. There should be some sort of check for the pid-file in the while loop. $Something like kill -0 $(cat $PID_PATH) || exit 1 should do the trick (untested though).

@kevpie
Copy link

kevpie commented Apr 29, 2015

There is one small bug here. The SIGHUP trap won't write out the new pid to the pid file without -D to daemonize. Anyways thanks for this, I adapted your gist to runit and it properly responds to reload, restart, etc.

@basinilya
Copy link

Need to check with nbproc >1 and -Ds option to stay in foreground in "systemd daemon mode".
If pidfile still created, we can use shell builtin wait instead of sleep 1.

In shells I saw so far wait is interrupted by SIGHUP and the signal handler is executed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment