Problem Statement: What is the simplest was to deamonize a serivce (Celeryd)on Ubuntu.
I am relatively new to Unix sys admin tasks (I have been relying on heroku to handle all of that for me) But I ran into a problem where I could not rely on that paradigm. I thought it was going to be really easy to do. But it ended up taking me a lot longer then I expected. Hopefuly this post will help someone in a similar situation.
There are a handful of unix initialization options:
- Supervisor
- Upstart (/etc/init)
- and System V Init (/etc/init.d)
I tried all three, and really the only one where I am not throwing up in my mouth is Upstart. This should be your default choice if you are running Ubuntu
Let me jump to the final solution, then I can go into the finer points
1) Create an init script
# This goes into /etc/init/celeryd
# celeryd -runs the celery worker as my virutal env user
#
#
# This task is run on startup to start the celery worker
description "runs the celery worker"
author "jonathan tushman"
start on runlevel [2345]
stop on runlevel [!2345]
# retry if ended unexpectedly
respawn
# limit the retries to max 15 times with timeouts of 5 seconds
respawn limit 15 5
# Time to wait between sending TERM and KILL signals
kill timeout 20
chdir /home/ubuntu/apps/money
exec su -c 'FLASK_ENV=production /usr/local/bin/celeryd --loglevel=info --concurrency=1 --logfile=/var/log/worker.log'
F*ck thats it. (I hate how simple this solution is once you figured out how to do it)
Now you are able to execute the following commands:
> sudo start celeryd
> sudo restart celeryd
> sudo stop celeryd
> sudo status celeryd
You can also use the initctl script
> sudo initctl list
and whenever your machine startsup or shutsdown the service will automatically start up and stop respectively. Thats what the following lines are for:
start on runlevel [2345]
stop on runlevel [!2345]
To see whats going on, these tail commands are useful:
> tail -f /var/log/money-worker.log -f /var/log/celery/celery.log
> tail -f /var/log/syslog
The main thing that haunted me, was once again Unix permissions
(One day, I am sure I am going to say — man! Unix permissions are awesome)
The most important line in the init script is the exec line:
exec su -c 'FLASK_ENV=production /usr/local/bin/celeryd --loglevel=info --concurrency=1 --logfile=/var/log/worker.log'
So what I learned here is that sudo has its own environment variable space. So even if I set the FLASK_ENV environement varable above in the script, it wouln’t be applied. So you need to use su -c
which will execute the given string as super user. Check out this StackOverflow post for more info.