【Next.js】getServerSideProps内で API実行するとError: connect ECONNREFUSEDになる
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