Millet Porridge

English version of https://corvo.myseu.cn

0%

Docker Series 10: Trick, Reloading the Host's Nginx

How We Usually Reload Nginx

The most-used commands should be these:

1
2
3
4
nginx -s reload
systemctl reload nginx
/etc/init.d/nginx reload
kill -HUP `cat /var/run/nginx.pid`

Nginx reloading is based on the HUP signal — that is to say, if you want to restart the host’s Nginx from within Docker, you need to send a signal from inside the container to a process outside the container.

Use Case

Remember I mentioned in the last blog post the Dockerization of some orchestration tools — the orchestration tool itself is also deployed with Docker. But an egress program like Nginx doesn’t need to be in Docker; putting it directly on the host is more cost-effective. Hence this approach of reloading Nginx from within a container. Since most people wouldn’t use it this way, I’ve also put it in the “unusual uses” section.

Concrete Operations

1
2
3
4
5
6
7
8
9
$ docker run -ti \
-v /var/run/nginx.pid:/var/run/nginx.pid \
--pid host \
--rm \
--privileged \
alpine \
/bin/sh

> kill -HUP `cat /var/run/nginx.pid`

How to Confirm the Nginx Reload Succeeded

During an Nginx reload the master process stays the same; you need to confirm whether its worker processes changed. Here I paste the script directly — it finds child processes via ppid and keeps comparing:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#!/bin/sh

# parent id
PARPID=`cat /var/run/nginx.pid`
OLD_PIDS=`pgrep -P $PARPID`

kill -HUP `cat /var/run/nginx.pid`

x=10
while [ $x -gt 0 ]
do
sleep 1s
NEW_PIDS=`pgrep -P $PARPID`
[ "$NEW_PIDS" != "$OLD_PIDS" ] && echo "Update success" && exit 0
echo "$x seconds until blast off"
x=$(( $x - 1 ))
done
echo "Failed update" && exit 1

Summary

This is the last post of the “unusual Docker uses” series. It introduced the situation of operating host processes from within a container that I use at work. Unlike mounting a unix socket in the previous post — because Nginx only supports signals — we adopt --pid host to unify the host’s and container’s process spaces. Please note this is also a dangerous operation; please don’t abuse it.

Clever friends may think of whether supervisor’s socket can also be mounted into a container for handling. I express no opinion here — maybe there’s always a scenario that suits it.