自宅で運用しているPi-holeのWeb UI(http://127.0.0.1:8053/admin)に一切繋がらなくなっていることに気付いた。Connection reset by peer が返ってくるだけで、ブラウザからもcurlからも中身は見えない。
一方でDNS解決(53番ポート)は正常に動いていて、実害は無かった。docker ps を見る限りコンテナはhealthy表示だったので油断していたが、調べてみると発生自体は6日前の2026-08-01に遡ることが分かった。
healthyなのにWeb UIだけ死んでいた
まず疑ったのは、ホスト側のポートマッピングかファイアウォールの問題だった。
上から順に切り分けていくことにした。
docker ps -aコンテナはUpかつhealthyと表示されていて、一見正常に見えた。
ただしこのヘルスチェックはDNSの応答だけを見ているもので、Webサーバーの生死は関知していないことに後で気付く。
dig @127.0.0.1 example.comDNS解決は問題なく通った。少なくとも53番ポート周りは無関係だと判断できる。
curl http://127.0.0.1:8053/admin/こちらはConnection reset by peerで失敗する。ホスト側からWeb UIへの接続だけが死んでいる状態だ。
ポートマッピングの問題かどうかを切り分けるため、コンテナ内部からも直接叩いてみた。
docker exec pihole curl 127.0.0.1:80コンテナ内部からも到達できなかった。これで「ホスト側のポートマッピングがおかしい」という仮説は外れ、コンテナ内のWebサーバープロセス自体が応答していないと分かった。
実際、コンテナ内でpihole-FTLプロセスを確認すると、本来あるはずのWebサーバー用スレッドが存在していなかった。
ログから原因を特定する
プロセスの状態だけでは埒が明かないので、docker logsを遡ってWebサーバー関連のログを探した。
docker logs pihole | grep -i webserver2026-08-01 15:55、証明書の自動更新のタイミングでこんなエラーが残っていた。
WARNING: No web server ports configured!
ERROR: Start of webserver failed! Web interface will not be available!これで話が繋がった。Pi-holeは自己署名TLS証明書をデフォルトで47日ごとに自動再生成し、期限切れ2日前になると証明書を再生成してWebサーバーを再起動する仕様になっている。
この環境はHTTPSを使わずHTTP運用のみだが、TLSポート(443)の初期化に絡む処理が失敗し、HTTP(80)を含めたWebサーバー全体の起動が巻き添えで失敗したとみられる。DNS機能はWebサーバーとは別スレッドで動いているため、こちらは影響を受けなかった。
応急処置:コンテナを再起動する
原因が分かれば応急処置は単純だった。
docker restart pihole再起動でWebサーバーが正常に起動し、Web UIが復旧した(HTTP 302を確認)。
恒久対応:TLS証明書の自動更新自体を無効化する
そもそもHTTPS運用をしていないので、TLS証明書の自動更新機能自体が不要だと判断した。docker-compose.ymlのpiholeサービスに以下を追加する。
environment:
...
FTLCONF_webserver_port: "80o,[::]:80o" # 443(TLS)ポートでのリッスンをやめる
FTLCONF_webserver_tls_validity: "0" # 証明書の自動再生成を無効化webserver_portから443os/[::]:443osを除外し、Webサーバーが起動時にTLSソケットを開こうとしないようにしたwebserver_tls_validity: 0により、証明書の期限切れ間近の自動再生成処理そのものを止めた(設定ファイルのコメントいわく、0日指定時は約30年の固定証明書を生成し以後更新しない)
適用は以下のコマンドで実施した。
cd /home/hoge-user/docker/dnscrypt-pihole && docker-compose up -d piholeこのホストにはdocker composeプラグインが入っておらず、docker-compose(standalone, v5.4.0)を使う必要がある点に注意。
適用後、/etc/pihole/pihole.tomlの[webserver]セクションでport = "80o,[::]:80o"、[webserver.tls]のvalidity = 0が反映されていることを確認し、Web UI(302応答)・DNS解決ともに正常であることを確認済みだ。
oとsフラグの意味
デフォルト値80o,443os,[::]:80o,[::]:443osに含まれるoやsは、Webサーバーエンジン(CivetWeb)が解釈するポートごとのフラグだ。
| フラグ | 意味 |
|---|---|
s(secure) | そのポートをTLS/SSL(HTTPS)で待ち受ける。例: 443sは443番をHTTPS用に開く |
o(optional) | そのポートで待ち受けられなくてもエラー扱いにしない。通常は指定ポートにbindできないと起動失敗になるが、oを付けると「開ければ開く、開けなくても無視して続行する」という緩い扱いになる |
参考までにr(redirect)というフラグもあり、そのポートへのHTTP通信を最初に設定されたSSLポートへリダイレクトする。今回は未使用だ。
これを踏まえると、デフォルトの80o,443os,...は「80番(HTTP)は開けなくてもエラーにしない/443番(HTTPS)も開けなくてもエラーにしない」という設定(443osはo+sの組み合わせ)になります。
今回の変更後は80o,[::]:80oとし、443番の指定自体を削除しました。これによりPi-holeはTLSソケットを開かなくなり、証明書の生成や自動更新を一切行いません。80番にはoを残していますが、実運用上必ずbindされることが前提です。
また、./etc-pihole_data/tls.pemは今後自動更新されなくなるため、将来HTTPS運用に戻す場合は設定の戻しや証明書の手動管理が必要になる点に注意してください。
まとめ
| 項目 | 内容 |
|---|---|
| 症状 | Pi-hole Web UIに接続できないが、DNS解決は正常。コンテナはhealthy表示のまま |
| 原因 | TLS証明書自動更新処理中のWebサーバー再起動失敗により、Webサーバーが停止 |
| 応急処置 | docker restart pihole |
| 恒久対応 | FTLCONF_webserver_portから443番を除外し、FTLCONF_webserver_tls_validity: "0"で証明書自動更新を無効化 |
docker psのhealthyはDNSの死活しか見ていないため、Web UIだけが死んでいても「正常」と誤認しやすいです。
同様の症状が出た場合はdocker logs pihole | grep -i webserverでWebサーバーの起動ログをいち早く確認しましょう。
今回の構成(自宅や社内など閉じたネットワークの個人・内部利用)ではあえてHTTP運用とし、Web UIへのアクセスも限定しています。LAN内や信頼できる範囲の利用なら、非HTTPSでも十分なセキュリティ要件を満たせます。
将来的に外部公開やインターネット越しでのアクセスが必要になった場合は、その時点でHTTPS対応や証明書運用の見直し(自動更新の復活や手動管理)を検討してください。