Here's how I do it.. this also adds in rvm
start on startup
stop on starting rcS
chdir /data/pusher/current
env RAILS_ENV=production
script
/usr/local/bin/rvm-shell '1.9.2@app' -c 'JOBS_PER_FORK=25 RAILS_ENV=production QUEUE=app_production bundle exec rake --trace resque:work >> /data/app/current/log/app-worker.production.log 2>&1'
end script
Edit: here is how I do it for running as a different user.. chdir doesn't seem to be honored.. so it's kind of hacky
start on runlevel [2345]
stop on starting rcS
chdir /data/app/current
env RAILS_ENV=production
script
sudo -u user -s -- "cd /data/app/current; export RAILS_ENV=production; /usr/local/bin/rvm-shell '1.9.2-p180@app' -c 'QUEUE=app_production bundle exec rake resque:work >> /data/app/current/log/app-worker.production.log 2>&1'"
end script
You pretty much need to change into the correct directory and set the RAILS_ENV in the sudo command
Indeed, a limitation of upstart is that it cannot track daemons that do what unicorn is doing.. that being fork/exec and exit their main process. Believe it or not, sshd does the same thing on SIGHUP, and if you look, /etc/init/ssh.conf makes sure sshd runs in the foreground. This is also one reason apache2 still uses an init.d script.
It sounds like gunicorn actually sort of daemonizes itself when receiving SIGUSR1 by forking and then exitting. This would be confusing for any of the process managers out there that try and keep a process alive.
I think you have two options. 1 is just to not use the SIGUSR1 and stop/start gunicorn when you need it.
The other option is to not use upstart's pid tracking, and just do this:
start on ..
stop on ..
pre-start exec gunicorn -D --pid-file=/run/gunicorn.pid
post-stop exec kill `cat /run/gunicorn.pid`
Not as sexy as pid tracking, but at least you won't have to write a whole init.d script.
(incidentally, this has nothing to do with the shebangs/execs. Both of those things work just like running a regular executable, so they wouldn't cause any extra forks).
Best Answer
Read this section of the Upstart Cookbook very carefully: http://upstart.ubuntu.com/cookbook/#expect
In a nutshell, if your daemon forks once, use "
expect fork
". If it truly daemonizes (double-forks), specify "expect daemon
".