/tmp 掃除の作法 - tmpfiles.d と systemd-tmpfiles
この記事で解決できること
/tmpの掃除が自動で行われる仕組みを理解できるtmpfiles.dのルールファイルを自作できるsystemd-tmpfilesコマンドを手動・自動の両方で使える
結論(実務の型)
/tmpの自動削除はsystemd-tmpfiles-clean.timerが担う- カスタムクリーンアップは
/etc/tmpfiles.d/にルールファイルを置く - ルールの書式は
タイプ パス モード UID GID 年齢 引数
前提(対象環境)
- OS: Ubuntu / systemd 搭載 Linux
- root 権限または sudo 実行が必要
/tmp とは何か — なぜ掃除が必要なのか?
/tmp はアプリケーションが一時ファイルを書き込む場所で、再起動後は内容が保証されない。長時間稼働するサーバでは放置するとディスクを圧迫し、PID ファイルやソケットファイルの誤参照が起きる。
- 典型的な用途: 圧縮・解凍の中間ファイル、セッションデータ、ソケットファイル
- Ubuntu のデフォルト:
/tmpはメモリ上のtmpfsにマウントされており、再起動で自動消去 /var/tmp: 再起動後も消えない永続 tmp。意図的な管理が必要
$ mount | grep /tmp tmpfs on /tmp type tmpfs (rw,nosuid,nodev)
tmpfs の場合は再起動で自動消去されるが、長時間稼働システムでは蓄積するため定期削除が必要。df -h /tmp でディスク使用量を確認しておく。
systemd-tmpfiles とは何か?
systemd-tmpfiles は、/tmp や /run といった一時ディレクトリの作成・削除・パーミッション管理を設定ファイルで宣言的に制御するツール。
3 つの動作モードを持つ:
| モード | コマンド | 動作 |
|---|---|---|
| 作成 | --create |
ルールに従ってファイル・ディレクトリを作成 |
| 削除 | --clean |
年齢基準を超えた一時ファイルを削除 |
| 完全削除 | --remove |
ルール対象のファイル・ディレクトリをすべて削除 |
# 手動で実行する場合 $ sudo systemd-tmpfiles --create $ sudo systemd-tmpfiles --clean $ sudo systemd-tmpfiles --remove
systemd の起動シーケンスに統合されており、2 つのユニットが自動動作する:
systemd-tmpfiles-setup.service— 起動時に--createを実行systemd-tmpfiles-clean.timer— 定期的(デフォルト: 起動後 15 分 + 1 日ごと)に--cleanを実行
tmpfiles.d の設定ファイルの書き方
設定ファイルは /etc/tmpfiles.d/*.conf に置く。システム提供のルールは /usr/lib/tmpfiles.d/ にある(直接編集禁止、パッケージ更新で上書きされる)。
書式
タイプ パス モード UID GID 年齢 引数
各フィールドの意味:
| フィールド | 説明 | 例 |
|---|---|---|
| タイプ | 操作の種類 | d(ディレクトリ作成)/ f(ファイル作成)/ x(削除除外) |
| パス | 対象パス | /tmp/myapp |
| モード | パーミッション(8進数) | 0755 |
| UID / GID | 所有者(- で現状維持) |
root / - |
| 年齢 | この経過時間を超えたら削除(--clean 時) |
7d(7日)/ 1h(1時間)/ -(削除しない) |
| 引数 | ファイルタイプの場合の初期内容(オプション) | - |
よく使うタイプ一覧
| タイプ | 意味 |
|---|---|
d |
ディレクトリを作成(なければ)、年齢超過ファイルを --clean で削除 |
D |
d と同じだが --remove で中身ごと削除 |
f |
ファイルを作成(なければ) |
f+ |
ファイルを作成または上書き |
x |
--clean / --remove の対象から除外 |
e |
既存ファイル・ディレクトリのパーミッションを設定 |
z |
パーミッション・SELinux ラベルを設定 |
定期クリーンアップをどう動かすか?
systemd-tmpfiles-clean.timer が自動的に周期実行される。状態確認:
$ systemctl status systemd-tmpfiles-clean.timer
● systemd-tmpfiles-clean.timer - Daily Cleanup of Temporary Directories
Loaded: loaded (/lib/systemd/system/systemd-tmpfiles-clean.timer; static)
Active: active (waiting) since Mon 2024-01-01 00:00:00 UTC; 3h ago
Trigger: Tue 2024-01-02 00:15:30 UTC; 20h left
手動でクリーンアップを即時実行:
$ sudo systemctl start systemd-tmpfiles-clean
--clean は年齢フィールドが設定されているエントリのみ削除対象とする。年齢フィールドを - にしたエントリは手動・自動いずれの削除も受けない。
カスタムルールの実践例
例 1: アプリ専用一時ディレクトリを作成・管理する
# /etc/tmpfiles.d/myapp.conf d /tmp/myapp 0750 myapp myapp 1d
/tmp/myapp を myapp:myapp 所有・0750 で作成し、1日経過したファイルを削除。
例 2: /var/tmp 配下のログを7日で削除する
# /etc/tmpfiles.d/clean-var-tmp.conf d /var/tmp/app-logs 0755 root root 7d
例 3: /run 配下に PID ディレクトリを起動時に作成する(削除なし)
# /etc/tmpfiles.d/myapp-run.conf d /run/myapp 0755 myapp myapp -
年齢 - なので削除されない。起動時に必ず作成される。
例 4: 特定パスを削除対象から除外する
# /etc/tmpfiles.d/exclude.conf x /tmp/persistent-cache
--clean 時に /tmp/persistent-cache をスキップする。
設定を即時反映・確認する
# 作成ルールを即時実行(新しいディレクトリを生成) $ sudo systemd-tmpfiles --create /etc/tmpfiles.d/myapp.conf # ドライランで削除対象を確認 $ sudo systemd-tmpfiles --clean --dry-run /etc/tmpfiles.d/myapp.conf
--dry-run は実際には削除せず、何が削除対象になるかを出力する。本番実行前に必ず確認する。
よくあるトラブルと対処
削除が起きない
年齢フィールドが - になっていないか確認。また --clean は**ファイルの最終アクセス時刻(atime)**を基準にする。書き込みタイムスタンプ(mtime)ではない。
# ファイルの atime を確認 $ stat /tmp/myfile | grep Access
noatime マウントオプション使用時は atime が更新されず、実際より古く見える。意図的に atime を更新してテストするには touch -a /tmp/myfile を使う。
作成したルールが反映されない
設定ファイルの構文を直接検証する:
$ sudo systemd-tmpfiles --create /etc/tmpfiles.d/myapp.conf
エラーが出なければ正常。journalctl でエラーログも確認:
$ journalctl -u systemd-tmpfiles-setup
/usr/lib/tmpfiles.d/ のルールを上書きしたい
/etc/tmpfiles.d/ に同名ファイルを置くと上書きされる(優先順位: /etc > /run > /usr/lib)。
# システム提供ルールを確認 $ cat /usr/lib/tmpfiles.d/tmp.conf # 上書き用ファイルを作成して編集 $ sudo cp /usr/lib/tmpfiles.d/tmp.conf /etc/tmpfiles.d/tmp.conf
やってはいけないこと
/usr/lib/tmpfiles.d/内のファイルを直接編集(パッケージ更新で上書きされる)Dタイプを重要なディレクトリ配下に対して年齢なしで設定(--removeで中身が全消去)