🧨

【Next.js】getServerSideProps内で API実行するとError: connect ECONNREFUSEDになる

2023/10/07に公開

Next.jsを触っていた際にgetServerSideProps内でAPIを実行したところ、ECONNREFUSEDのエラーが発生して、エラー解消に少し躓きました。

実行環境

  • Docker
  • Next.js(v13.2.3)
  • golang(v1.18)

エラー内容

ECONNREFUSED
ユーザーがサーバーに接続しようとしているが、ポートに接続できないことを示します。
サーバーによって接続が拒否される。

コード

実際のコードは以下である。
getServerSideProps内で APIを実行し、初期値として渡す流れである。

export async function getServerSideProps() {
  const response = await axios.get('http://localhost:8080/test1')
  return {
    props: {
      initialData: response.data.data.temporaryUserId,
    }
  };
}

しかし、ボタン押下などでAPI実行すると成功する。

axios.get('http://localhost:8080/test1') 

原因

フロントエンドのサーバーからAPI実行する場合は、コンテナ側のポートを指定する必要があるため。
ブラウザからAPI実行する場合は、localhostで良い。
いろいろ調べていたところ、コンテナ側のポートを指定するのはlocalhostをコンテナ名に変更してあげれば良いことがわかった。

エラー解消へ

今回のバックエンド側のdocker-compose.ymlファイルでは「app」コンテナであるので以下に変更すれば、エラーが解消される。

axios.get('http://app:8080/test1') 

docker-compose.ymlの一部です。

services:
  app:
    container_name: app
    ports:
      - 8080:8080

appに変更したが、まだエラーが出る、、。

こちらに関しては異なるdocker-compose.ymlでコンテナ間の通信ができていないため、まだエラーになることがわかった。
今回はフロント、バックそれぞれでdocker-compose.ymlを持っていて、フロントのコンテナからバックのコンテナに対して通信するので、同一のネットワーク上にコンテナが存在していなければならない。

以下のようにdocker-compose.ymlを修正した。

  • フロント側(一部省略)
services:
  go-test-app-frontend:
    container_name: "go-test"
    networks:
      - mynetwork
networks:
  mynetwork:
    external: true
  • バック側(一部省略)
services:
  app:
    container_name: app
    ports:
      - 8080:8080
    networks:
      - mynetwork
networks:
  mynetwork:
    external: true

それぞれのymlファイルに networks 項目を設定し、各コンテナに接続するネットワークを指定しています。
networks に共通のネットワーク(mynetwork)を追加することで、コンテナ間の通信が可能になります。また、mynetworkはdocker-composeで管理されていないため、servicesと同じ階層に networks を設定しました。
最後にdocker-composeで管理されていない外部のネットワークなので external: true を設定しました。

docker-compose起動前に以下のコマンドを実行し、ネットワークの作成する。

docker network create mynetwork

これでそれぞれのdocker-composeを起動し、確認するとエラーが解消され、getServerSideProps内で実行している APIが成功しました!

Discussion