如何在 Docker 容器内重启 Discourse 的 nginx 服务?

在 Discourse Docker 容器中重启 nginx 的正确方法是什么?

该 Docker 容器似乎运行的是 Debian 10,但使用常规的 systemd 方式重启 nginx 失败了。

[root@osestaging1 discourse]# ./launcher enter discourse_ose
root@osestaging1-discourse-ose:/var/www/discourse# cat /etc/issue
Debian GNU/Linux 10 \n \l

root@osestaging1-discourse-ose:/var/www/discourse# systemctl restart nginx
System has not been booted with systemd as init system (PID 1). Can't operate.
Failed to connect to bus: Host is down
root@osestaging1-discourse-ose:/var/www/discourse# 

看起来有一个 init.d 脚本,但运行它也会失败。日志显示是因为无法绑定到一个已被占用的地址。

root@osestaging1-discourse-ose:/etc/nginx/conf.d# /etc/init.d/nginx restart
[FAIL] Restarting nginx: nginx failed!
root@osestaging1-discourse-ose:/etc/nginx/conf.d# tail /var/log/nginx/error.log
2019/11/12 10:32:45 [emerg] 1123#1123: bind() to unix:/shared/nginx.http.sock failed (98: Address already in use)
2019/11/12 10:32:45 [emerg] 1123#1123: bind() to unix:/shared/nginx.http.sock failed (98: Address already in use)
2019/11/12 10:32:45 [emerg] 1123#1123: bind() to unix:/shared/nginx.http.sock failed (98: Address already in use)
2019/11/12 10:32:45 [emerg] 1123#1123: bind() to unix:/shared/nginx.http.sock failed (98: Address already in use)
2019/11/12 10:32:45 [emerg] 1123#1123: bind() to unix:/shared/nginx.http.sock failed (98: Address already in use)
2019/11/12 10:32:45 [emerg] 1123#1123: still could not bind()
2019/11/12 10:32:47 [emerg] 1127#1127: bind() to unix:/shared/nginx.http.sock failed (98: Address already in use)
2019/11/12 10:32:47 [emerg] 1127#1127: bind() to unix:/shared/nginx.http.sock failed (98: Address already in use)
2019/11/12 10:32:47 [emerg] 1127#1127: bind() to unix:/shared/nginx.http.sock failed (98: Address already in use)
2019/11/12 10:32:47 [emerg] 1127#1127: bind() to unix:/shared/nginx.http.sock failed (98: Address already in use)

确实,nginx 已经在运行了。

root@osestaging1-discourse-ose:/etc/nginx/conf.d# ps -ef | grep -i nginx
root        46    40  0 10:19 ?        00:00:00 runsv nginx
root      1174    46  1 10:33 ?        00:00:00 /usr/sbin/nginx
root      1177   108  0 10:33 pts/1    00:00:00 grep -i nginx
root@osestaging1-discourse-ose:/etc/nginx/conf.d# 

正确关闭上述 nginx 进程并重新启动它的方法是什么?

在 Discourse Docker 容器中正确重启 nginx 的方式是使用 sv 命令,该命令属于 runit 服务监督工具的一部分。

root@osestaging1-discourse-ose:/var/www/discourse# sv stop nginx
ok: down: nginx: 1s, normally up
root@osestaging1-discourse-ose:/var/www/discourse# sv start nginx
ok: run: nginx: (pid 269) 0s
root@osestaging1-discourse-ose:/var/www/discourse# 

因此,看起来 Ruby on Rails 使用了 runit。

我找到 sv 命令是因为它在 templates/web.template.yml 文件 中被引用。

接近了……Ruby on Rails 本身并不限定你使用什么。可以是 systemd、Docker 中的原生 pid 1,或者 myriad 其他工具。

我们在官方 Docker 镜像中选择使用 runit,是因为它轻量且非常容易理解。它是一个即插即用的工具。