Scripts under /etc/init.d
are associated with sysvinit, a venerable and unfortunately fairly broken approach to UNIX service management. See, processes under UNIX form a tree: every process has a parent, the process that started it. The parent has a lot of control over its children and importantly is notified when a child process dies. It's practically trivial to keep a process running or shut it down if you're its parent.
And there's the problem: a sysvinit service script starts a service and then exits, leaving the service running. The service's parent process is gone, which makes it difficult to locate and track the service - when a sysvinit script is asked to stop a service, it needs to figure out which process should be stopped, using unreliable information.
Under correct service management approaches, as used in runit and daemontools, services are run by supervising processes, which stick around after launching the service. Since the service is a child process, the supervisor process knows if it's running, if it's crashed, and where to find it to send it signals.
So in a runit script, the correct thing to do is to run nginx itself, not an init.d script. This is easy enough to do. However, by default nginx daemonises itself, which means it deliberately "escapes" from its parent process and becomes very hard to keep track of. Fortunately that behaviour can be switched off, which is the purpose of the daemon off;
configuration option. A valid runit script for nginx therefore looks like this:
#!/bin/sh
exec /usr/sbin/nginx -g "daemon off;"
Short and sweet. runit can manage this arrangement very nicely - it'll keep nginx running, and you can control it with sv
. For example, sv hup nginx
tells nginx to reload its configuration. Of course, the PID will change if nginx crashes and is restarted, or if you deliberately ask it to restart with sv restart nginx
, but runit will handle that just fine.
(Incidentally, never ever ever use kill -9
, ever.)