
2026/04/03 23:42
**課題:** *本番環境でディスク容量が不足しています。*
RSS: https://news.ycombinator.com/rss
要約▶
Japanese Translation:
記事では、4 GB RAMと40 GBの Hetzner サーバーで NixOS を動かしていた環境が、2 つの設定ミスによりディスク容量を使い果たしたケースを説明しています。まず、Nix ストア(
/nix/store)と Plausible Analytics の ClickHouse データベースが約 23 GB を消費し、nix-collect-garbage が空き領域を確保できず、ジャーナルログのみがクリーンアップ可能でした。Nix ストアを別の 15 GB ボリュームに移動したことで使用量はほぼ半分になりましたが、重いダウンロード時にはディスク使用率が 100 % に達していました。次に、2.2 GB のファイルダウンロードが失敗した原因は、nginx が応答を一時ファイルにバッファリングしていたこと(デフォルトの proxy_max_temp_file_size は 1024 m)でした。lsof +L1 を実行すると、削除済みファイルで約 14.5 GB が nginx に保持されていることが確認でき、問題を裏付けました。バッファリングを無効化(proxy_buffering off; proxy_max_temp_file_size 0;)することでダウンロード失敗は解消し、一時ファイルの使用も排除されました。これらの変更後、Grafana のメトリクスが改善し、ディスク使用率は約 20 % 程度に落ち着き、再び急激な増加は起こりませんでした。本投稿では、Nix ストアの移動と nginx バッファリング設定の正しい調整の両方が、小規模ホスティング環境でダウンタイムを防ぎ、保守コストを削減するために不可欠だったことを強調しています。本文
昨晩、シンプルなサーバーを立ち上げました。
顧客がデジタル版「Kanjideck」のファイルをダウンロードできるようにしたものです。
サーバーは NixOS(4 GB RAM、40 GB ディスク)を動作させた小型の Hetzner マシン上にホストしています。
この中でダウンロード可能なファイルの一つは 2.2 GB です。
構成は次の通りです。
- 静的ファイルを配信する Haskell プログラム(認可処理付き)
- nginx のリバースプロキシがリクエストを Haskell プログラムへ転送
最初にパニック
ファイルがようやく利用可能になったと発表して数分も経たないうちに、数百人の顧客が一斉にサーバーを訪れました。
ログはスクリーンから飛び散り、あるメッセージが何度も繰り返し表示されることに気付きました。
Mar 31 20:43:03 mogbit kanjideck-fulfillment[2528300]: user error (Unexpected reply to: MAIL "<...> at kanjideck.com", Expected reply code: 250, Got this instead: 452 "4.3.1 Insufficient system storage\r\n")
誰もファイルにアクセスできず、メールでの報告が殺到しました。
Grafana では 40 GB / 40 GB(すなわち
/dev/sda が 100 % 使用)という状態でした。スペースを早急に確保しないとメールサーバーも書き込み不能になりかねません。
du -sh を実行すると、最大の二つの原因が判明しました。
| パス | サイズ |
|---|---|
(Plausible Analytics, clickhouse データベース) | 8.5 GB |
(サーバー構成・インストール・実行ファイル) | 15 GB |
これらを削除することにしました。
Nix ストアのクリア
最初の試み:
$ nix-collect-garbage -d
結果:
removing old generations of profile /nix/var/nix/profiles/system error: opening lock file '/nix/var/nix/profiles/system.lock': No space left on device
Nix ストアはデバイス上に空きが無いのでクリアできませんでした。
まずスペースを確保する必要がありました。
ログの削減
$ journalctl --vacuum-time=1s
これで十分なスペースが確保され、再度 Nix ストアをクリーンアップできます。
ClickHouse データベースの縮小
system.query_log テーブルを truncate しようとしました:
$ clickhouse-client -q "TRUNCATE TABLE system.query_log"
結果:
Received exception from server (version 24.3.7): Code: 243. DB::Exception: Cannot reserve 1.00 MiB, not enough space.
再び空きが無くなりました。
Nix ストアを別ボリュームにマウント
Hetzner が追加容量のインスタンスを提供しないため、別途ボリュームを購入しました。
- ファイルシステム作成:
mkfs.ext4 -L nix /dev/sdb - NixOS Wiki の手順でストアを移動し、以下の宣言的設定を追加:
fileSystems."/nix" = { device = "/dev/disk/by-label/nix"; fsType = "ext4"; neededForBoot = true; options = [ "noatime" ]; };
再起動後、
/nix/store は新しいボリューム上に移動し、ルートディスクはようやく十分な空きが確保されました。Grafana の赤い表示も消え、エラーメッセージのストリームも止まりました。
ファイルシステム使用率は 50 % 前後(ユーザーが 2.2 GB ファイルをダウンロードすると約 60–65 %)にとどまりました。
Nginx の根本原因調査
大容量ファイルのダウンロードバグ
ユーザーから、2.2 GB ファイルが途中で停止し完了できないという苦情が寄ってきました。
proxy_max_temp_file_size を確認すると、デフォルトは 1024 m です。これを 5000 m に増やすと、2.2 GB ファイルの配信に成功しました。
高負荷時のディスクスペース急上昇
その日の後半、ディスク使用率が一瞬で 100 % に戻りました。
lsof +L1 を使ってリンクが切れたまま開かれているファイルを調べました。
$ lsof +L1 | grep nginx
結果は 14.5 GB の削除済みファイルが nginx に保持されていることを示しました(一時プロキシバッファ)。
サイズ合計:
$ lsof +L1 | awk '/nginx/ {sum += $7} END {print sum/1024/1024/1024 " GiB"}' 14.5528 GiB
これらは nginx がレスポンスをディスクにバッファリングしているために作成された一時ファイルです。
プロキシ設定の修正
Nginx の設定を次のように更新しました:
"<...>.kanjideck.com" = base { "/" = { proxyPass = "http://127.0.0.1:" + toString(ports.kanjideck-fulfillment) + "/"; extraConfig = '' proxy_buffering off; proxy_max_temp_file_size 0; ''; }; };
nginx をリロードすると、Grafana は即座に改善し、サーバーは再び軽量化。ディスク使用率は 20 % にまで低下しました。
結論
- サーバーは起動後約 20:40 〜 23:00 の最初の二時間、アクセスリクエストに応答できませんでした。
- 大容量(2.2 GB)のファイルはダウンロードできず、他のファイルは利用可能でした。
- これら両方の問題は nginx リバースプロキシの設定ミスによるものでした:
が大きいファイルに対して低すぎたproxy_max_temp_file_size- バッファリングが有効だったため、ディスク上に大量の一時バッファが蓄積
プレッシャーの下ではこうした細部を見落としやすく、経験があればパニックや「空き容量不足」のエラーを回避できたでしょう。