Supervisor がバックグラウンドで起動しているのに supervisor.sock no such file となる

$ sudo supervisorctl status
unix:///tmp/supervisor.sock no such file

普通、Supervisor が起動していない時に上記エラーが出るはずなんだけど、
何故かバックグラウンドで動いているのに上記エラーが出る。

$ sudo ps aux | grep supervisord
root     2200998  0.0  0.5 248036 20500 ?        Ss   Aug20  43:44 /usr/bin/python3 /usr/local/bin/supervisord -c /etc/supervisord.conf

起動しているけど supervisorctl status で参照?できない。
supervisorctl のコマンド全てエラーが出る。

原因

AI による概要

Supervisorがバックグラウンドで起動しているにもかかわらず unix:///tmp/supervisor.sock no such file となり supervisorctl で参照できない場合、OSによる /tmp ディレクトリの自動クリーンアップ(古いファイルの削除設定)によって、ソケットファイルだけが消されてしまった可能性が最も高いです。

↑おそらくこれが原因。

1.一時的な復旧方法(再起動)

最も手っ取り早い解決策は、Supervisorデーモン自体を再起動してソケットファイルを再生成させることです。ただし、管理している子プロセスもすべて一緒に再起動する点に注意してください。

だそう。
でもこれだと根本的な解決にならない。

2.根本解決(ソケットの保存先を /tmp 以外にする)

Linux(Ubuntu、CentOS、Amazon Linuxなど)の多くは、定期的に /tmp 内のファイルを自動削除します。再発を防ぐために、ソケットファイルの作成場所を /var/run/(または /run/)配下などに変更します。

こちらの対応の方がよさそう。

ソケットファイルとは

AI による概要

Linuxにおけるソケットファイル(UNIXドメインソケット)とは、同一のコンピュータ(マシン)内にあるプロセス同士が高速にデータをやり取りするため(プロセス間通信:IPC)に、ファイルシステム上に作成される通信の窓口となる特殊なファイルです。

主な特徴

・高速な通信: ネットワーク(TCP/IP)のプロトコルスタックを通さず、OSのカーネル内部で直接データをやり取りするため、通常のネットワーク通信よりも高速に動作します。
・セキュリティ: ネットワーク上にポートを公開しないため、同一マシン外からのアクセスを遮断でき、安全に通信できます。
・見分け方: ls -l コマンドで確認した際、ファイルのパーミッションの先頭文字が s(例:srwxr-xr-x)で表示されます。

よく使われる具体例

・Webサーバーとアプリサーバーの連携: Nginx や Apache などのWebサーバーから、Puma や Unicorn といったRubyなどのアプリケーションサーバーへリクエストを渡す際によく使われます。
・Dockerの制御: Docker では、クライアントからデーモンを操作する入口として /run/docker.sock というソケットファイルが使用されます。

だそう。
なんでソケットファイルがないのに動いているんだろ。
と、思って調べてみたら、ファイルがなくても一応動く仕組みらしい。

解決

/etc/supervisord.conf

変更箇所だけ。

[unix_http_server]
file=/tmp/supervisor.sock   ; the path to the socket file

↓

[unix_http_server]
file=/var/run/supervisor/supervisor.sock
[supervisorctl]
serverurl=unix:///tmp/supervisor.sock ; use a unix:// URL  for a unix socket

↓

[supervisorctl]
serverurl=unix:///var/run/supervisor/supervisor.sock

起動してみる

変更箇所を変更し、保存したら起動しみたらエラーが出た。

$ sudo supervisord -c /etc/supervisord.conf
Error: Cannot open an HTTP server: socket.error reported errno.ENOENT (2)
For help, use /usr/local/bin/supervisord -h

ディレクトリを用意する必要があった。

$ cd /var/run
$ sudo mkdir supervisor

再び起動してみる。

$ sudo supervisord -c /etc/supervisord.conf
$ sudo supervisorctl status
sample-go               RUNNING   pid 596203, uptime 0:02:00

ソケットファイルも確認。

$ ls /var/run/supervisor -l
srwx------. 1 root root 0 Oct  1 00:00 supervisor.sock

関連記事