5

I'm working on a system whose primary startup system is runit.

Unfortunately, runit requires that whatever application it is running be running in the foreground like so:

#!/bin/bash

exec sshd -D

Seeing as nginx doesn't offer a way to run it in the foreground, how can I have runit still manage nginx and be able to stop, start, and restart it using runit's sv commands?

6

You can use option daemon off:

exec /usr/sbin/nginx -c /etc/nginx/nginx.conf  -g "daemon off;"

From nginx wiki:

You can use daemon off safely in production mode with runit / daemontools however you can't do a graceful upgrade. master_process off should never be used in production.

When you use runit to control nginx, it becomes the parent process of the nginx master process. But if you try to do an online upgrade, the nginx master process will fork and execute the new binary.

A new master process is created, but because old master process still exists (because it's controlled by runit), the parent of the new master process will be the init process, because runit can not control new master master process as it didn't start it.

  • Is there any way to do an online upgrade using runit? Sometimes, runit makes me miss my old simple /etc/init.d/ scripts. – Naftuli Kay Jul 30 '14 at 16:50
  • @NaftuliTzviKay: nginx doc says you can't. My answer also provides details explanation. – cuonglm Jul 30 '14 at 16:51
  • What if runit becomes PID 1 inside, say a container? Then.. what happens? – CMCDragonkai Oct 23 '15 at 6:57
0

Don’t turn off the master process for anything used in the real world, it doesn’t do zero-downtime upgrades and it’s unsupported.

Do it the/a right way using page sentinel monitoring of port 80, etc. to not contain some magic content, otherwise nginx can’t do zero-downtime upgrades and you’ll look like a rank amateur.

# . . .
set -e
## config - start - should move to another file
CONF='/etc/nginx/nginx.conf'
# TODO: grab below by parsing CONF
PROTO=http
IP=0.0.0.0
PORT=80
## config - end - should move to another file
case "$(uname | tr '[A-Z]' '[a-z]')" in
darwin|freebsd|netbsd|openbsd) NC_ARGS="-n -w 5 -z '${IP}' '${PORT}'" ;;
linux) NC_ARGS="-n -w 5 --send-only '${IP}' '${PORT}'" ;;
*) echo "unsupported os $(uname)" >&2; exit 1 ;;
esac
/usr/bin/nginx -t -c "${CONF}"
/usr/bin/nginx -c "${CONF}"
sleep 5
while /usr/bin/nc $NC_ARGS </dev/null >/dev/null 2>&1; do
  set -e # loop runs in a subshell
  /usr/bin/curl -m5 -fsS -A 'runit script/0.0.0' \
    "${PROTO}"://"${IP}":"${PORT}" | \
    /usr/bin/grep -q 'This comment is required'
  sleep 2
done

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.