この設定をしていなかったせいで、解決に一日、時間を費やしたので共有します。
使用しているGradioのバージョンは4.42.0です。
背景と発生した事象
Dockerを用いて、FastAPIでサーバーを立てて、Gradioのmount_gradio_app
でアプリケーションを紐付け、そのポートへCaddyでリバースプロキシを設定していました。
機能を実装し、いざ本番環境へデプロイすると、開発環境とローカルのDocker上で動いていたアプリケーションが、動かなくなるという事態が発生しました。
具体的には、カスタムパスでマウントしているアプリのみ、Gradioコンポーネントは描画されるけれど、コンポーネントに紐付けた関数は実行されないという現象でした。
その時のアプリケーションを簡単に書くとこうでした。
from fastapi import FastAPI
import uvicorn
import gradio as gr
import main
import share
app = FastAPI()
app = gr.mount_gradio_app(app, share.main(), path="/share/")
app = gr.mount_gradio_app(app, main.main(), path="/")
if __name__ == '__main__':
uvicorn.run(app, port=7777, host="0.0.0.0")
share.main()
とmain.main()
はGradio.Blocks
を返します。
これはローカルでは問題なく機能しましたが、リバースプロキシを通して実行される本番環境ではうまく動かなくなります。
解決策
ではどのように解決したかを示します。以下のようにroot_pathを追加しました。
from fastapi import FastAPI
import uvicorn
import gradio as gr
import main
import share
app = FastAPI()
app = gr.mount_gradio_app(app, share.main(), path="/share/", root_path="/share")
app = gr.mount_gradio_app(app, main.main(), path="/")
if __name__ == '__main__':
uvicorn.run(app, port=7777, host="0.0.0.0")
Gradioの公式ドキュメントでroot_pathの項目を見ると、以下のように記載されています。
root_path: この FastAPI アプリケーションのパブリックデプロイメントに対応するサブパスです。例えば、アプリケーションが "https://example.com/myapp" で提供されている場合、root_path は "/myapp" に設定する必要があります。http:// または https:// で始まる完全な URL を提供することもでき、その場合はそのまま使用されます。通常、これは(カスタムの path を使用している場合でも)提供する必要はありません。ただし、FastAPI アプリをプロキシの背後で提供している場合、プロキシがリクエストヘッダーに Gradio アプリへの完全なパスを提供しない可能性があります。その場合、ここでルートパスを提供することができます。
プロキシが間に挟まると機能しなくなる可能性があるので、root_pathを設定してくださいということが記載されていますね。
まとめ
Gradioは使いやすくて大変ありがたいですが、何かの拍子で本番環境では動かなくて困ってしまう時がよくあります。またGradioの知見が貯まったら共有しますので、フォローよろしくお願いいたします。