動作確認環境
- CentOS7のサーバ
※Ubuntu20.04も同じ実装なので同じくハマるかと思います
落とし穴にハマった流れ
やりたいこと
-
hoge
というアプリケーションのAPIサーバを建てたい- フロントは
nginx
でリクエストを受けてアプリケーションに渡す -
hoge
はsystemd
でデーモン化する -
hoge
はnginx
からのリクエストをUNIX Socket
で受け取る-
UNIX Socket
は/var/run/hoge/hoge.sock
とする
-
- フロントは
やったこと
-
/var/run/hoge
ディレクトリを作成する- パーミッションは
hoge:hoge
とする
- パーミッションは
-
hoge
とnginx
の各種設定ファイルを配置してデーモンを起動する- この時点で動いたことは確認できた
- サーバを再起動する
- 再びAPIを叩くと
nginx
がBad Gateway
のエラーを返した- 調べてみると
/var/run/hoge/hoge.sock
がディレクトリごと無くなっていた
- 調べてみると
原因
- CentOS7では
/var/run
配下がtmpfs
になっており、サーバを再起動すると/var/run
配下のファイルが消えてしまう
# /var/run は /run へのシンボリックリンク
$ ls -ld /var/run
lrwxrwxrwx. 1 root root 6 Jul 25 2019 /var/run -> ../run
# /run は tmpfs をマウントしている
$ mount | grep /run
tmpfs on /run type tmpfs (rw,nosuid,nodev,mode=755)
対処法
systemdのUnitファイルに RuntimeDirectory
の設定を追加する
tmpfiles.d
のMANページによると
原文
System daemons frequently require private runtime directories below /run to store communication sockets and similar.
For these, it is better to use RuntimeDirectory= in their unit files (see systemd.exec(5) for details), if the flexibility provided by tmpfiles.d is not required.
The advantages are that the configuration required by the unit is centralized in one place, and that the lifetime of the directory is tied to the lifetime of the service itself.
Similarly, StateDirectory=, CacheDirectory=, LogsDirectory=, and ConfigurationDirectory= should be used to create directories under /var/lib/, /var/cache/, /var/log/, and /etc/.
tmpfiles.d should be used for files whose lifetime is independent of any service or requires more complicated configuration.
日本語訳
システムデーモンは、通信ソケットなどを格納するために、/runの下にプライベートランタイムディレクトリを必要とすることがよくあります。
これらについては、tmpfiles.dによって提供される柔軟性が必要ない場合は、ユニットファイルでRuntimeDirectory =を使用することをお勧めします(詳細については、systemd.exec(5)を参照)。
利点は、ユニットに必要な構成が1か所に集中化されていること、およびディレクトリの存続期間がサービス自体の存続期間に関連付けられていることです。
同様に、/var/lib/、/var/cache/、/var/log/、および/etc/の下にディレクトリを作成するには、StateDirectory=、CacheDirectory=、LogsDirectory=、およびConfigurationDirectory=を使用する必要があります。
tmpfiles.dは、存続期間がサービスに依存しないか、より複雑な構成が必要なファイルに使用する必要があります。
とあるので、RuntimeDirectory
の設定を追加します。
また、今回はパーミッションを 0755
としたいので以下の様に RuntimeDirectoryMode
も設定します。
UNITファイルに追加した行
RuntimeDirectory=hoge
RuntimeDirectoryMode=0755
※ systemd.exec
のMANページによると /run
が起点となるため、フルパスではなく /run
配下に作りたいディレクトリ名を指定します
参考リンク
- man - tmpfiles.d
- man - systemd.exec(5)
- Handling /var/run with systemd