mutoxu-N
@mutoxu-N

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

別のDockerコンテナからFastAPIのDockerコンテナに接続できない

解決したいこと

Dockerを使ってFastAPIを起動しています。

起動スクリプト
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8080"]

既存のリバースプロキシ(nginx)を用いて、FastAPIをHTTPS化したいと考えています。リバースプロキシはHTTPS化済みです。

発生している問題

リバースプロキシのDockerコンテナから host.docker.internal:8080 へアクセスすることが出来ません。

 20#20: *18 upstream timed out (110: Connection timed out) while connecting to upstream

問題のコード

servers.conf の抜粋
server {
    # FastAPIにアクセスできない
    location /test/ {
        proxy_pass http://host.docker.internal:8080/docs;
    }
    
    # 他のサーバーにはアクセスできる
    # location /ok/ {
    #     proxy_pass http://host.docker.internal:8888/;
    # }
}

自分で試したこと

  • 他のサービスには、このリバースプロキシを経由してアクセスすることができます (host.docker.internal が正常に機能しています。)
  • LAN内の別のPCから、ローカルIPアドレスを使用してFastAPIへアクセスすることができます(http://192.168.xxx.xxx:8080/docsはアクセス可能)
  • リバースプロキシのコンテナ内で curl http://host.docker.internal:8080/ はタイムアウトになります

他のサービスで、リバースプロキシが動作しているため、FastAPIの設定が問題だと考えていますが、以下のサイトを参考に --host を設定しても問題が解決しませんでした。

0

3Answer

host.docker.internal -> localhost に変更すればつながりそうな気がします。

確認の手順としては「リバースプロキシのコンテナ」でhost.docker.internalの名前解決ができるかどうか確認すればよいでしょう。

host.docker.internal は Docker Desktop(Windows, Mac用だけ?)にて、Dockerネットワークからホストを参照する際に使う特殊ドメインですが、ネットワークタイプが host の場合には定義されていなさそうな気がします。

1Like

Comments

  1. @mutoxu-N

    Questioner

    localhost に変更すると 502 Bad Gateway が表示されました。(localhost はコンテナ自身を指してしまうため、ホストは参照しない気がします。)

    リバースプロキシのコンテナ内での host.docker.internal の名前解決はできています。他のDockerコンテナで動作しているサービスに host.docker.internal でアクセスできているので、リバースプロキシ側は問題なく動作していると思います。

    ネットワークモードは特に設定していないため、おそらく None になっていると思います。

※この記事は機械翻訳により日本語に翻訳されています。

この問題は、nginxのDockerコンテナからFastAPIのDockerコンテナに、host.docker.internal:8080経由でアクセスできないことが原因のようです。

host.docker.internalはDockerコンテナからホストマシン上で動作するサービスにアクセスするためのものですが、今回の場合、FastAPIのサービスもDockerコンテナ内で動作しています。そのため、nginxコンテナからhost.docker.internal:8080にアクセスすると、ホストマシンのポート8080に接続しようとしますが、これは直接FastAPIコンテナに接続することにはなりません。

FastAPIコンテナのポート8080をホストマシンのポート8080にマッピングしているため、LAN内からはFastAPIにアクセスできますが、ホストマシンがDockerコンテナからの接続を許可していない可能性があります(ファイアウォールやネットワーク設定の影響)。

この問題を解決するための推奨方法は、ユーザー定義のDockerネットワークを作成し、nginxコンテナとFastAPIコンテナの両方をそのネットワークに接続することです。これにより、コンテナ間でコンテナ名をホスト名として直接通信できます。

解決手順は以下の通りです:

  1. Dockerネットワークを作成:

    docker network create my-network
    
  2. FastAPIコンテナをこのネットワークに接続して起動:

    docker run -d --name fastapi_container --network my-network -p 8080:8080 your_fastapi_image
    
  3. nginxコンテナも同じネットワークに接続して起動:

    docker run -d --name nginx_container --network my-network -p 443:443 your_nginx_image
    
  4. nginxの設定ファイルで、アップストリームサーバーをコンテナ名で直接指定:

    server {
        location /test/ {
            proxy_pass http://fastapi_container:8080/docs;
        }
    }
    

これにより、nginxはDockerネットワークを介して直接FastAPIコンテナと通信できます。

また、FastAPIアプリケーションが0.0.0.0で待ち受けており、必要なポートがDockerfileで公開されていることを確認してください。

1Like

それぞれの docker-compose.yml にネットワーク設定を記載して、アドレスにコンテナ名を指定すると無事動作しました。

0Like

Your answer might help someone💌