Gunicorn が systemd の Unix ドメインソケットをどのように取得しているか
以下のような *.socket
と対応する *.service
ファイル(Gunicorn を起動する)を systemd に登録しておくと、Gunicorn アプリケーション側の設定(コード)を特にいじらなくても当該ソケットから Listen できます。
Gunicorn が接続すべきソケットをどのように取得しているか疑問だったので、軽く調べました。
[Unit]
Description=Gunicorn Socket
[Socket]
ListenStream=/run/myapp.sock
SocketUser=www-data
SocketMode=600
[Install]
WantedBy=sockets.target
目次
systemd を利用しているかどうかの判別
Gunicorn はデフォルトでは、TCP で Listen します。
Gunicorn ソースコードに以下のような部分があり、特定の環境変数を見ることで systemd 由来のソケットを Listen すべきと判断しているようです。
listen_fds = systemd.listen_fds()
if listen_fds:
self.systemd = True
$LISTEN_FDS
環境変数
$LISTEN_FDS
環境変数は、systemd が開いているソケットの情報を提供するためにセットします。$LISTEN_FDS
は開いているソケットの数を表す整数値です。
ファイルディスクリプタによるソケットの取得
標準入出力の次である 3 番1以降の連番を、開いているソケット数分見ることで取得しています。
$LISTEN_PID
環境変数
systemd は $LISTEN_FDS
だけでなく、$LISTEN_PID
も設定します。ソケットの所有者であるプロセスの ID が格納されます。
$LISTEN_FDNAMES
環境変数
$LISTEN_FDNAMES
というファイル識別名を格納する補助的な環境変数もあるようですが、Gunicorn では使用していませんでした。
参考文献
- https://manpages.debian.org/bookworm/libelogind-dev-doc/sd_listen_fds.3.en.html
- https://github.com/benoitc/gunicorn
SD_LISTEN_FDS_START
定数 ↩︎