How to restart Discorse's nginx service inside the docker container?

AI-generated summary

The discussion is about restarting nginx inside a Discourse Docker container running Debian 10. The usual systemd approach fails, and an attempt to restart using the init.d script also fails due to a binding issue.

maltfield discovers that the proper way to restart nginx is to use the sv command, part of the runit service supervisor, as shown below:

sv stop nginx
sv start nginx

maltfield also notes that Discourse uses runit, while sam clarifies that Ruby on Rails is agnostic about the service supervisor used and that runit was chosen for the official Docker image due to its lightweight nature and ease of use.

What is the correct way to restart nginx inside the Discorse docker container?

The docker container appears to be running Debian 10, but the usual systemd approach for restarting nginx fails

[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# 

It looks like there’s an init.d script, but running that fails. The logs say it’s because it can’t bind to an address already in-use.

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)

Indeed, nginx is running already

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# 

What’s the proper way to kill the above nginx process and start it again?

The proper way to restart nginx inside the Discourse docker container is to use the sv command, which is part of the runit service supervisor.

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# 

So it looks like Ruby on Rails uses runit

I found the sv command as it’s referenced in the templates/web.template.yml file

Close… Ruby on Rails is agnostic about what you would use. Could be systemd, straight pid 1 in docker or a myriad of other tools.

We opted to use runit in our official docker image cause it is light weight and very easy to reason about. It is a tool that just works.