スポンサーリンク

導入

開発中のWebアプリケーションで、なぜか消えない表示に悩まされた経験はありませんか?

今回は、`kouchou-ai`というプロジェクトで「AIによるレポート作成中です」という表示が消えなくなり、その原因を徹底的に調査・解決した過程をブログ記事としてまとめました。同じような問題に直面した方の参考になれば幸いです。

事象

`kouchou-ai`の管理画面(`http://localhost:4000`)でレポート作成を開始したところ、「AIによるレポート作成中です。完了までしばらくお待ちください。」という表示が出続け、何度アプリケーションを再起動しても消えませんでした。

スポンサーリンク

初期調査と誤解

まず、問題解決のためにいくつかの一般的なデバッグ手法を試みました。

1. API経由での停止:

バックエンドAPIの DELETE /admin/reports/{slug}

エンドポイントを使ってレポートの停止を試みましたが、「レポートが見つからない」というエラーで失敗しました。

2. Dockerコンテナの再起動:

docker compose down でコンテナを停止し、docker compose up -d

で再起動。しかし、管理画面の表示は消えませんでした。

3. Dockerボリュームの削除:

docker compose down -v

を実行し、Dockerボリュームも削除して再起動。それでも表示は消えませんでした。この時点で「データは完全に消えたはずなのに…」という大きな疑問が生まれました。

4. ブラウザキャッシュとフロントエンドの再ビルド:

ブラウザのキャッシュクリア、シークレットモードでのアクセス、さらにはフロントエンド(client-admin)のDockerイメージ再ビルドまで試しましたが、状況は変わりませんでした。

原因の深掘り

表示が消えない根本原因を探るため、アプリケーションの内部動作を詳細に調査しました。

1. フロントエンドの表示ロジック:

client-adminapp/page.tsx を確認すると、fetch(`${getApiBaseUrl()}/admin/reports`)

というコードでバックエンドからレポート一覧を取得していることが判明しました。しかし、ブラウザの開発者ツール(Networkタブ)にはこのリクエストが見当たりませんでした。これはNext.jsのSSR(Server-SideRendering)やRSC(React ServerComponents)の機能により、サーバーサイドでAPIリクエストが実行され、その結果がHTMLに埋め込まれてクライアントに送られてい*ためでした。

そして、このHTMLコンテンツの中に、status: "processing"

となったレポート情報が埋め込まれていることを発見しました。これが「AIによるレポート作成中です」という表示の直接の原因でした。

2. バックエンドのデータ永続化:

HTMLに埋め込まれた「処理中」のレポート情報がどこから来ているのかを特定するため、バックエンドのデータ永続化の仕組みを調査しました。

* server/src/config.py で、レポートのステータスが settings.DATA_DIR / "report_status.json"

というファイルに保存されることが判明。

* settings.DATA_DIR はホスト側の ./server/data ディレクトリを指していました。

* compose.yaml を確認すると、api サービスはホスト側の ./server ディレクトリをコンテナ内の

/appバインドマウントしていました。

核心的な原因

docker compose down -v コマンドは、Dockerの名前付きボリュームは削除しますが、

ホスト側のディレクトリをコンテナにマウントしている「バインドマウント」は削除しません。

したがって、report_status.json ファイルはホスト側の ./server/data/report_status.json

に保存されており、docker compose down -v を実行しても削除されずに残っていたのです。

api サービスは起動時にこの残っていた report_status.json を読み込み、その中に含まれる processing 状態のレポート情報を再度メモリにロードしていました。そして、client-admin はサーバーサイドでこの情報を取得し、HTMLに埋め込んでクライアントに送っていたため、何度再起動しても表示が消えなかった、というわけです。

解決策

原因が特定できたため、解決策はシンプルでした。

1. 現在起動中のコンテナを停止:

docker compose down

. ホスト側の `report_status.json` ファイルを直接削除:

rm ./server/data/report_status.json

注意: このコマンドは、kouchou-ai プロジェクトのルートディレクトリで実行してください。)

. コンテナを再起動:

docker compose up -d

4. ブラウザのキャッシュを再度クリアし、http://localhost:4000 にアクセス。

この手順を実行したところ、無事に「AIによるレポート作成中です。」という表示が消え、管理画面が正常な状態に戻りました!

教訓と学び

今回のデバッグを通じて、以下の重要な教訓を得ました。

* Dockerのボリュームとバインドマウントの違い: docker compose down -v

が削除するのは名前付きボリュームのみであり、バインドマウントされたホスト側のデータは削除されないことを再認識しました。アプリケーションのデータ永続化の仕組みを正確に理解することが重要です。

* アプリケーションのデータ保存パスの確認:

問題発生時には、アプリケーションがどこにデータを保存しているのか(特に設定ファイルやステータスファイル)をまず確認することが解決への近道です。

* フロントエンドとバックエンドの連携:

Next.jsのSSR/RSC環境では、ブラウザのNetworkタブに表示されないサーバーサイドのAPIリクエストが存在するため、デバッグ時にはその挙動を考慮に入れる必要があります。HTMLコンテンツに埋め込まれたデータも重要なヒントになります。

まとめ

一見すると単純な表示の問題でしたが、その裏にはDockerの仕組み、アプリケーションのデータ永続化、そしてNext.jsのレンダリングメカニズムが複雑に絡み合っていました。今回の経験が、同様の問題に直面した開発者の方々の一助となれば幸いです。


この記事が気に入ったら『目黒で働く分析担当の作業メモ』ご支援をお願いします!

※OFUSEに飛びます


おすすめの記事