Difyコードノードのデータベース接続でエラー、パラメータは問題なし

Difyでデータベースに接続し、データを自動的にMySQLにインポートしたいのですが、接続パラメータには問題ないにもかかわらず、常にエラーが発生します:

データインポート結果

:cross_mark: データベースのインポートに失敗しました: (pymysql.err.OperationalError) (2003, “Can’t connect to MySQL server on ‘111.8.160.135’ (\[Errno 101\] Network is unreachable)”)
(Background on this error at: https://sqlalche.me/e/20/e3q8)

DifyはDockerにデプロイされており、ローカルでPythonコードを実行してMySQLに接続し、データインポートをテストすると成功するのですが、このエラーを解決できません。解決策を教えてください。

@Dify_Forum_Helper フォローアップしてください

エラーメッセージ自体を見ると:

(pymysql.err.OperationalError) (2003, “Can’t connect to MySQL server on ‘111.8.160.135’ ([Errno 101] Network is unreachable)”)

これはアカウントやパスワードのようなパラメータエラーではなく、ネットワークにまったく接続できないというエラーです。Difyが動作しているDockerコンテナ内でのみ発生し、ホストマシンで直接Pythonを実行すると接続できることから、コンテナネットワークが111.8.160.135:3306に到達できないと判断できます。

以下のいくつかの方向で一つずつ確認してください(特に1、2番に注目してください):


1. ホストマシンはこのMySQLにアクセスできますか?

まずホストマシンで確認してください:

# ホストマシンで実行
telnet 111.8.160.135 3306
# または
nc -vz 111.8.160.135 3306
  • ここで接続できない場合:データベースが配置されているネットワーク/ファイアウォールの問題であり、DifyやDockerとは関係ありません。
  • ホストマシンが接続できる場合:ステップ2に進んでください(Dockerコンテナのネットワーク問題です)。

2. Difyのコンテナ内でネットワークをテストする

Dify APIを実行しているコンテナを見つけます。通常、名前は dify-api または dify-server のようになっています。コンテナに入ってテストします:

docker ps  # apiが配置されているコンテナIDまたは名前を見つける
docker exec -it <api_container_name_or_id> bash   # または sh
# コンテナ内部で実行:
apt-get update && apt-get install -y telnet netcat-openbsd || apk add --no-cache busybox-extras
telnet 111.8.160.135 3306
# または
nc -vz 111.8.160.135 3306
  • コンテナ内でも同様に接続できない場合(タイムアウト/Network is unreachable)、それはDockerコンテナから外部MySQLへのルーティング/ファイアウォールの問題であると断定できます。
  • よくある原因:
    • 会社/サーバールームのファイアウォールがホストマシンのIPアドレスからのアクセスのみを許可し、Dockerブリッジネットワークからのアクセスを許可していない。
    • クラウドプロバイダーのセキュリティグループが特定の送信元IPのみを許可しており、DockerのNAT後の出口IPがホワイトリストに含まれていない。
    • ホストマシンで firewalld / iptables ルールが有効になっており、Dockerネットワークインターフェースの外部アクセスを制限している。

解決策(例):

  • MySQLサーバー側/ファイアウォール/セキュリティグループで、ホストマシンの出口IPが属するネットワークセグメントまたはDockerブリッジネットワークセグメントからのアクセスを許可する。
  • または、DockerがNAT出口を使用しており、実際にはホストマシンのIPが出力されていることを確認し(ほとんどの場合がこれです)、MySQL側でこのIPがホワイトリストに登録されていることを確認する。
  • 内部ネットワークの特殊な環境(例えば、1台の踏み台サーバーからのアクセスのみを許可している場合)であれば、DifyをDBに直接接続できる同じマシンで実行するか、ネットワークプロキシ/内部ネットワークトンネリングを設定することを検討してください。

3. コードノードで使用しているMySQLアドレスを確認する

現在のエラーは次のとおりです:

Can't connect to MySQL server on '111.8.160.135'

さらにいくつか確認してください:

  1. ポートは3306ですか
    • MySQLがデフォルトの3306ではない場合、コードで port=xxxx を明示的に指定する必要があります。
  2. MySQLが同じホストマシン上にある場合localhost または 127.0.0.1 を使用しないでください:
    • コンテナにとって 127.0.0.1 はコンテナ自身であり、ホストマシンではありません。
    • MySQLがホストマシン上にある場合、127.0.0.1 ではなく、Dockerブリッジから見えるホストマシンのIP(例:ホストマシンの内部IP、または同じローカルネットワーク内のホストマシンのIP)を使用する必要があります。
  3. MySQLが別のDockerコンテナで実行されており、Difyと同じ docker-compose.yml にある場合、推奨される設定は次のとおりです:
    services:
      dify-api:
        # ...
        depends_on:
          - mysql
        networks:
          - dify_net
    
      mysql:
        image: mysql:8
        # ...
        networks:
          - dify_net
    
    networks:
      dify_net:
        driver: bridge
    
    その場合、コードノードの hostには mysql(サービス名) を記述し、ポートは3306とします。

4. Dockerコンテナのネットワークモードを確認する

docker-compose.yml でDify APIコンテナに特別な設定があるか確認してください:

  • もし使用している場合:
network_mode: host

その場合、コンテナはホストマシンネットワークを直接使用します。このとき:

  • コンテナ内から 111.8.160.135:3306 へのアクセス動作は、ホストマシンとほぼ同じになります。

  • それでもnetwork unreachableの場合、その経路自体に問題があることを意味します(再度ステップ1に戻って確認してください)。

  • デフォルトのブリッジネットワークの場合:

    • ホストマシンのファイアウォールが docker0 ネットワークインターフェースの外部アクセスを許可しているか確認してください。
    • または、MySQLサーバー側で送信元ネットワークセグメントを許可してください。

5. こちらでさらに判断するために補足していただきたい情報

上記の手順でも解決しない場合は、以下の重要な情報を貼り付けてください:

  1. docker-compose.yml 内のDify関連サービス(特にapi)の設定。
  2. MySQLのデプロイ場所:
    • 公開ネットワークのマシンですか?クラウドRDSですか?それとも同じホストマシン上のDockerコンテナですか?
  3. ホストマシン上とDifyコンテナ内でそれぞれ nc -vz 111.8.160.135 3306 を実行した結果のスクリーンショットまたは出力。

まとめ

  • エラーはネットワークに到達できないことを示しており、アカウント、データベース名、パスワードの問題ではありません。
  • ホストマシンのPythonからは接続できるのに、Docker内のコードからはできない場合、根本原因はほぼ間違いなくDockerコンテナからMySQLへのネットワーク/ファイアウォール/ルーティングの制限です。
  • まずコンテナ内で直接 telnet / nc を使って接続をテストし、到達可能かどうかに応じてセキュリティグループ、ファイアウォール、またはdocker-composeのネットワーク設定を調整してください。

まずステップ1と2をテストし、その結果と一部の設定を貼り付けていただければ、具体的な変更方法を一緒に確認できます。

1\. ホストマシンはこのMySQLにアクセスできますか?

ホストマシンで接続に成功しました。

2\. Difyのコンテナでネットワークをテストする

dify-apiコンテナへの接続も成功しました

  1. コードノードで使用しているMySQLアドレスを確認
    コード内のアドレス、ポートは問題ありません。

  2. Dockerコンテナのネットワークモードを確認
    設定ファイルに特殊な設定がないか確認しました。

私のMySQLは、同じホストマシン上のDockerコンテナにデプロイされています。

サンドボックスには追加の制限があります。詳細はサンドボックスのFAQをご覧ください。