エラーメッセージ
誰にでも起こり得ることです。スムーズなデータ取得を期待してRAG(検索拡張生成)パイプラインを起動したところ、ターミナルに接続エラーが表示されることがあります。ベクトルデータベースのクライアントを初期化した瞬間にすべてがクラッシュします。通常、トレースバックは以下のようになります:
weaviate.exceptions.WeaviateConnectionError: Failed to connect to Weaviate at http://localhost:8080.
Error: HTTPConnectionPool(host='localhost', port=8080):
Max retries exceeded with url: /v1/.well-known/ready
(Caused by NewConnectionError: Failed to establish a new connection: [Errno 111] Connection refused)
接続エラーの原因は?
簡単に言うと、このエラーはPythonスクリプトがhttp://localhost:8080のドアを叩いているものの、誰も応答していないことを意味します。Docker化されたRAGパイプラインを使用している場合、この無応答は通常、以下の4つの問題のいずれかに起因します:
- **コンテナが存在しない:**WeaviateのDockerコンテナが実行されていないか、起動シーケンス中にクラッシュしています。
- **「localhost」の罠:**Pythonをコンテナ内で実行していますが、ホストマシンではなく、コンテナ自身の小さな環境内でWeaviateを見つけようとしています。
- **スクリプトの実行が早すぎる:**Pythonコードは動作準備ができていますが、Weaviateがインデックスや重い機械学習モジュールの読み込みでまだビジー状態です。
- **ポートの競合:**他のサービス(開発サーバーなど)がポート8080を占有しているか、
docker-compose.ymlのポートマッピングが間違っています。
ステップバイステップの解決策
1. コンテナの状態を確認する
まずは基本から始めましょう。システム上でWeaviateが実際に動作しているか確認してください。ターミナルで以下を実行します:
docker ps
リストからweaviateイメージを探します。見つからない場合は、サービスを再度起動してください:
docker-compose up -d
メモリ制限やOpenAIなどのプロバイダーのAPIキーの欠落により、コンテナがサイレントに終了することがあります。コンテナがすぐに消えてしまう場合は、ログを確認して原因を探ります:
docker-compose logs weaviate
2. Dockerネットワークの溝を埋める
PythonアプリとWeaviateの両方がDockerで実行されている場合、localhostは敵になります。Dockerネットワーク内では、各コンテナは自分自身をlocalhostと見なします。隣のコンテナと通信するには、サービス名を使用する必要があります。
docker-compose.ymlを確認してください。おそらく以下のようになっています:
services:
weaviate:
image: semitechnologies/weaviate:1.24.1
ports:
- "8080:8080"
app:
build: .
depends_on:
- weaviate
Pythonの接続文字列を更新する必要があります。汎用的なアドレスを、YAMLファイルで定義されたサービス名に置き換えてください:
# Docker内では失敗します
client = weaviate.Client("http://localhost:8080")
# こちらは動作します: "weaviate"はサービス名と一致します
client = weaviate.Client("http://weaviate:8080")
3. データベースに準備の時間を与える
ベクトルデータベースはすぐには起動しません。ハードウェアによりますが、Weaviateがプラグインの初期化や既存シャードの検証を行うのに5〜15秒かかることがあります。スクリプトがclient.is_ready()を早く呼び出しすぎると、/v1/.well-known/readyエンドポイントはリクエストを無視します。
パイプラインの弾力性を高めるために、Pythonの設定に簡単なリトライループを追加します:
import weaviate
import time
from weaviate.exceptions import WeaviateConnectionError
def connect_with_retry(url, retries=10, delay=2):
for i in range(retries):
try:
client = weaviate.Client(url)
if client.is_ready():
print("Weaviateに接続されました!")
return client
except WeaviateConnectionError:
print(f"Weaviateを待機中... ({i+1}/{retries} 回目の試行)")
time.sleep(delay)
raise Exception("20秒経過後も接続に失敗しました。")
client = connect_with_retry("http://localhost:8080")
4. ポートマッピングを監査する
docker-compose.ymlが実際にデータベースをホストマシンに公開しているか確認してください。ポートマッピングはホスト:コンテナの形式である必要があります。以下のようになっているはずです:
ports:
- "8080:8080"
競合を避けるために最初の数字を(例:"9000:8080"に)変更した場合は、Pythonクライアントでもhttp://localhost:9000を使用するように更新する必要があります。
修正の確認方法
RAGのロジックに戻る前に、簡単なcurlコマンドで状況を確認しましょう。これにより、ターミナルからデータベースにアクセスできるかどうかが確認できます:
curl -i http://localhost:8080/v1/.well-known/ready
HTTP/1.1 200 OKが返ってくれば成功です。依然として「Connection Refused」が表示される場合は、PythonコードではなくDockerの設定に原因があります。curlが成功したら、Pythonで簡単な動作確認を行い、クライアント接続が安定していることを確認してください。
予防のためのヒント
- **ヘルスチェックを使用する:**Docker ComposeのWeaviateサービスにヘルスチェックを追加します。これにより、Pythonアプリがデータベースが完全に正常な状態になるまで待機してから開始されるようになります。
- **環境変数を使用する:**URLをハードコードしないでください。
.envファイルを使用することで、ローカルテスト用のlocalhost:8080と本番環境用のweaviate:8080を簡単に切り替えられるようになります。 - ログを監視する:
docker-compose logs -fを実行したターミナルウィンドウを開いておきます。これが、発生した接続トラブルを素早くキャッチする最も簡単な方法です。

