Daemonizing processes in Linux and running them on boot is a very easy task in theory, but the variety of different Linux distributions tend to make it incredible hard sometimes. So here’s my take on Daemonizing processes without a headache.
When starting a process on boot there are usually few requirements I need
- Drop privileges from root
- Ensure safe umask
- Redirect stdout/stderr to a log file
- Set current working directory
- Set environment variables
- Write a pid file
- And finally daemonize the process
These all are fairly trivial tasks to implement in the actual application, but also these are the same for every app. I like to keep things DRY. When I’m creating for example some simple prototype application in Node.js I really don’t care to think about which logging framework to use or how to do a double fork in a environment which don’t even have a fork call to begin with.
I’m usually working with Debian and Ubuntu based distros. They both have a init system which can be used to accomplish these requirements.
/etc/init.d/ style scripts and Ubuntu uses Upstart which is
actually somewhat usable. Here’s my Upstart config for Redis for
example, but that’s not usable in Debian of course. Debian gives you a skeleton
/etc/init.d/skeleton which can be used to create a daemon on boot
up. That’s 159 lines long! Pretty complex for such a simple task I’d say.
Luckily there are alternative tools for daemonizing processes. One of the simplest ones I’ve encountered is called daemon. This tool has been around for a while, but I’ve just found out about it. I think the name makes it kinda hard to stumble upon…
It’s easily installable via apt-get
# apt-get install daemon
Then it is just matter of running the command on boot up. I don’t usually care
about the run levels so I just put it in
/etc/rc.local which is the last
script executed during Debian and Ubuntu boot process.
My daemon setup for Node.js servers is usually something like this:
daemon \ --name myapp \ --user user \ --chdir /home/user/myapp/ \ --output /home/user/myapp/myapp.log \ --pidfile /home/user/myapp/myapp.pid \ --inherit \ --env="NODE_ENV=production" \ /usr/local/bin/node /home/user/myapp/server.js
It’s Fairly straightforward. Just make sure that the pid and log directories
are writable by the user. The
--inherit switch is only required when defining
custom environment variables with
--env so that you don’t loose previously
defined environment variables such as
PATH. There is no mention of umask in
this command, because daemon sets it to 022 by default to prevent creation of
group or world readable files. Checkout the man page for details.