前回は権限トラブルやコンテナ分離の悩みを紹介しました。今回は、監視・ログ管理やコンテナ間通信で直面した問題を、具体的な体験談と設定例を交えて解説します。
ログ管理の落とし穴
本番コンテナが無事立ち上がったと思ったら、Nginxのエラーログがどこにあるかわからず迷いました。また、本番ではボリュームマウントやコンテナユーザ権限の影響でアクセスできない場合があります。
実際、tailを使ってログを監視しようとしても「Permission denied」の連続で詰みました。
解決策として、以下のようにホスト側にマウントし、権限を揃えることでログ監視が可能になりました。
volumes: - ./logs/nginx:/var/log/nginx - ./logs/php:/var/log/php
sudo chown -R 33:33 ./logs
こうしてtail -f でリアルタイムにエラーを確認でき、原因切り分けも迅速になりました。特にPHP-FPMのログはNginxと別コンテナなので、まとめて外部に出すのが運用上非常に重要です。
ログ管理のベストプラクティス
そもそも論、のログファイルはどのように管理するべきでしょう。
結論から言えば、ベストプラクティスとして、コンテナ内ではログをファイルに保存せず、標準出力(STDOUT)と標準エラー出力(STDERR)に流すように設計します。これにより、ホスト側のロギングドライバーやログ収集ツールで一元管理しやすくなります。
とは言え、初めからコンテナだけを想定しているアプリケーションでもないかぎり、ログファイルへ出力を実装しているものがほとんどではないでしょうか。そんな時には前述のように、ログフォルダをホストにマウントして、ホスト側で監視できるようにする、というのが現実解だと思います。
コンテナ間通信の複雑さ
PHPコンテナからNginxコンテナへのアクセスも一筋縄ではいきません。開発ではlocalhostで通信できましたが、本番ではDockerネットワークを経由する必要があります。
docker-compose.ymlのネットワーク設定を以下のように整理しました:
networks:
app-network:
driver: bridge
services:
web:
networks:
- app-network
php:
networks:
- app-network
これでPHPコンテナから通信可能になります。しかし、ロードバランサーを入れたり、Nginxを複数立ち上げたりすると、通信経路やDNS解決がさらに複雑になります。
通信できない問題
本番運用とは異なりますが、開発環境でアプリケーションに接続できなくなる、という事を何度も経験しました。ちなみに開発環境ではWindoesのWSLでコンテナ環境を動かし、VS Codeを使って開発を行うスタイルです。
ひとたび通信できなくなると、設定を修正したり、コンテナを再起動したり、再構築したり、いろいろな手を打っても効果ありませんでした。
今では開き直って、WSL –Shutdownで再起動。通信できない問題のほとんどの場合はこれで解決しました。(原因究明は行っていませんので根本解決にはなっていませんが)
監視ツール
現実的な本番運用では、CPU使用率、メモリ使用量、ディスクI/O、ネットワークトラフィック といったメトリクス監視が必須になります。cAdvisor (コンテナアドバイザー)や Prometheusといった様々な監視用ツールが選択肢になると思います。
今回は社内システムという事もあり、費用対効果の側面からログ監視と、クラウドの標準監視機能のみで運用しています。
今回の運用環境での学び
- ログは外部に出し、権限とマウントを最初に確認する
- コンテナ間通信はネットワーク名やサービス名を明示して接続する
- 開発と本番の差異を意識し、設定ファイルや環境変数は管理しておく
次回は、再デプロイやスケール、環境差異など、さらに踏み込んだ本番運用の教訓を紹介します。