Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
template for a gunicorn upstart job that can run several instances of a django application
# %(mysite)s - run %(mysite)s instances (default is the main production instance)
#
# This runs gunicorn-django for %(mysite)s; to install:
# * sudo ln -s <this file> /etc/init/%(mysite)s
# * sudo initctl reload-configuration
#
# it expects the following directory layout:
#
# /home/%(mysite)s/public_html
# \-env -> virtualenv
# | \-bin
# | \-gunicorn_django
# | \-activate
# \-<instance>
# | \-app -> application
# | \-conf
# | | \-gunicorn_<instance>.conf.py
# | | \-<this file>
# | \-log -> logs
# | \-run -> pid files and the like
# \-<instance>
# ...
#
# to use:
# * sudo start/stop/restart/reload/status %(mysite)s
# * sudo start/stop/restart/reload/status %(mysite)s instance=testing
description "%(mysite)s gunicorn instance, default is the main instance"
start on runlevel [2345]
stop on runlevel [06]
expect fork
respawn
respawn limit 10 5
instance ${instance:-main}
env APPHOME="/home/%(mysite)s/public_html"
pre-start script
INST=${instance:-main}
GUNICORN="$APPHOME/env/bin/gunicorn_django"
test -n "$GUNICORN" -a -x "$GUNICORN" || { stop; exit 0; }
test -d "$APPHOME" || { stop; exit 0; }
end script
script
INST=${instance:-main}
CONF="$APPHOME/$INST/conf/gunicorn_$INST.conf.py"
GUNICORN="$APPHOME/env/bin/gunicorn_django"
PIDFILE="$APPHOME/$INST/run/$INST.pid"
LOGFILE="$APPHOME/$INST/log/gunicorn.log"
cd "$APPHOME/$INST/app"
source "$APPHOME/env/bin/activate"
exec $GUNICORN --pid="$PIDFILE" --name="$INST" --user=django --group=django --config="$CONF" --daemon --log-file="$LOGFILE" 2>>"$LOGFILE"
end script
post-stop script
INST=${instance:-main}
rm -rf "$APPHOME/$INST/run/$INST".{pid,sock}
end script
# vim: set et sw=4 ts=4 sts=4
@andrewjennings

This comment has been minimized.

Copy link

@andrewjennings andrewjennings commented Feb 14, 2012

This would be really handy. It seems that $GUNICORN doesn't get passed from the pre-start to the run script though. I tried using the "export" command and didn't have much luck with that either.

@m0n5t3r

This comment has been minimized.

Copy link
Owner Author

@m0n5t3r m0n5t3r commented Feb 14, 2012

it was actually a bug (fixed now), they are executed in different shell processes

I gave up on upstart a long time ago and am running gunicorn under supervisord now, btw :)

@andrewjennings

This comment has been minimized.

Copy link

@andrewjennings andrewjennings commented Feb 17, 2012

I got upstart working finally - though I found that it was impossible to pass variables around the way I was thinking. Your instance-based variable storage is probably the way to go. I'll probably revisit my script when launching multiple instances on a server.
Thanks for the gist. It was inspirational :)

@DavidWittman

This comment has been minimized.

Copy link

@DavidWittman DavidWittman commented Mar 20, 2012

What's the purpose of the source "$APPHOME/" on line 58? It was causing my upstart script to fail, and I can't really think of a good reason for sourcing a directory.

@m0n5t3r

This comment has been minimized.

Copy link
Owner Author

@m0n5t3r m0n5t3r commented Mar 21, 2012

hmm, I have no idea why I left out the rest of the line, it was supposed to source the activate script, changing now

@jacobg

This comment has been minimized.

Copy link

@jacobg jacobg commented Jul 25, 2012

I don't think "--daemon" should be set in upstart, because you don't want to detach it from the upstart service. The daemon option is used when you run gunicorn_django directly from the command line.

@lechup

This comment has been minimized.

Copy link

@lechup lechup commented Jun 5, 2013

Things to mention:

  • Upstart in ubuntu 12.04 uses /bin/sh in script section, so source is . in /bin/sh
  • Do we really need expect fork and --daemon in gunicorn part?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment