apacheのファイルディスクリプタ数の上限変更(2025年5月)

# はじめに

私の過去の経験では /etc/rc.lodal に ulimit -n 65536 とか書けば恒久的にファイルディスクリプタの制限は緩和できてた気がする。

昨今はそれだけではダメなのか、気が付いたらデフォルトの1024に戻っていた。(VMWareの仮想マシン上のUbuntuだからとか関係ある？？？)

そこで色々調べ、試してようやく辿り着いたのでメモとして残しておく。

# 環境

* Ubuntu 22.04.2 LTS
* systemd 249.11-0
* Apache2 2.4.52

# 結論

## 最終的に採用した設定方法

```Text:/etc/apache2/envvars
## If you need a higher file descriptor limit, uncomment and adjust the
## following line (default is 8192):
APACHE_ULIMIT_MAX_FILES='ulimit -n 65536'
```

APACHE_ULIMIT_MAX_FILESがコメントアウトされているので外してからapacheを再起動する。(reloadでもいい？未検証 → 「追記 － /etc/apache2/envvars 変更後のreload/restart」)

```Text
systemctl restart apache2
```

## 確認方法(設定値)

### cat /proc/PID/limits

```Text:Max open filesのみ抜粋(envvarsのコメント外す前)
Max open files            8192                 8192                 files
```

```Text:Max open filesのみ抜粋(envvarsのコメント外した後)
Max open files            65536                65536                files
```

apacheのMPMの設定によっては子プロセスも複数存在するが、この設定は子プロセス毎に異なるなんてこともなさそうなので親プロセスだけの確認でいいかもしれない。

以前だったら

```
ulimit -n
```

だったが、ログインシェル上で適用されている値の確認になる模様。なのでこの値がデーモンにも適用されている訳ではない点に注意。

## 確認方法(現在値)

```Text
ls -la /proc/PID/fd | wc -l
```

apacheのMPMの設定によっては子プロセスも存在し、親プロセス側の使用状況みても変化なし、ってこともあるのでその点は要注意かも。


# お試し

## limits.conf

調べ始めて最初に出てきたやり方が /etc/security/limits.conf を利用したもの。

```Text
USER soft nofile 65536
USER hard nofile 65536
```

本番サーバーは再起動が難しいのでいったんスルー。(前述のenvvarsでデフォルトは8192とあるが、どちらが優先されるだろうか、、、。短絡的にシステム側の設定と思いそうだが、デーモンを起動するスクリプトでulimitしていたらそちらが有効になる。envvarsはどちらかというと後者だが、デフォルトはコメントアウトされているので、やはりシステム側の設定が使われるのか、、、 → 「追記 - limits.confとenvvarsの優先順位」)

## sysctl.conf

sysctl.conf の file-max で指定するやり方もあるらしいが、以下の通り。

```Text
#sysctl -a | grep file
fs.file-max = 9223372036854775807
```

(なんでまたこんな値なんだろう、、、そっ閉じ)

## systemd（/usr/lib/systemd/system/apache2.service）

環境によっては /etc/systemd/system/multi-user.target.wants/apache2.service とか。

```Text
[Service]
・
・
・
LimitNOFILE=65535

[Install]
WantedBy=multi-user.target
```

[Service]の最後に LimitNOFILE=65535 追加する。

前述の確認方法で8192のままだった。

## systemd（/etc/systemd/system/apache2.service.d/override.conf）

こっちもsystemdで、前述のapache2.serviceと別のやり方って感じか。

mkdir /etc/systemd/system/apache2.service.d
vi /etc/systemd/system/apache2.service.d/override.conf

```Text
[Service]
LimitNOFILE=65535
```

上記2行を追加。

こちらも前述の確認方法で8192のままだった。

# お試しから導き出した結論

おそらくだがsystemdの設定(前述2点)はapache起動直後に有効になっているかもしれないが、systemdから呼ばれるapache起動用のスクリプトまたはコマンドでenvvarsが使われており、そちらで上書きされるのだろうと推測している。

# 最後に

* 今回のenvvarsを利用した方法はapacheのバージョンによって異なるかもしれない。
* apacheのバージョンによっては or apache以外だとsystemdの2つのやり方のどちらかでも良さそう。
* ~~これからサーバー構築するという場合は/etc/security/limits.confもあり？。~~
　→ ダメだった。「追記 - limits.confとenvvarsの優先順位」参照。

# 追記 - limits.confとenvvarsの優先順位

/etc/security/limits.conf に設定を追記してUbuntuを再起動してから実行したコマンドを以下に列挙する。

```Text:再起動直後の/etc/security/limits.conf
# cat /etc/security/limits.conf
・
・
・
#ftp             hard    nproc           0
#ftp             -       chroot          /ftp
#@student        -       maxlogins       4

* soft nofile 32768
* hard nofile 32768

# End of file
```

```Text:
# ulimit -n
1024
```

```Text:/etc/apache2/envvarsのAPACHE_ULIMIT_MAX_FILESはコメントのまま
# cat /etc/apache2/envvars
・
・
・
## If you need a higher file descriptor limit, uncomment and adjust the
## following line (default is 8192):
#APACHE_ULIMIT_MAX_FILES='ulimit -n 65536'
```

```Text:apacheのPID
# ps ax | grep apache
    781 ?        Ss     0:00 /usr/sbin/apache2 -k start
    795 ?        Sl     0:00 /usr/sbin/apache2 -k start
    796 ?        Sl     0:00 /usr/sbin/apache2 -k start
   1240 pts/1    S+     0:00 grep --color=auto apache
```

```Text:PID毎の上限
# cat /proc/781/limits | grep "Max open files"
Max open files            8192                 8192                 files
# cat /proc/795/limits | grep "Max open files"
Max open files            8192                 8192                 files
# cat /proc/796/limits | grep "Max open files"
Max open files            8192                 8192                 files
```

* /etc/apache2/envvars一択。


# 追記 － /etc/apache2/envvars 変更後のreload/restart

```Text
# vi /etc/apache2/envvars
# systemctl reload apache2
# cat /proc/781/limits | grep "Max open files"
Max open files            8192                 8192                 files
# systemctl restart apache2
# cat /proc/1653/limits | grep "Max open files"
Max open files            65536                65536                files
```

* restartで反映。(ulimitコマンドで変更したものを反映する、とするなら確かにrestartじゃないと適用されない気もする)