- APIサーバーをDockerコンテナで構築
- Nuxtでフロントエンド構築(Dockerコンテナ)
- NuxtはSSR(サーバーサイドレンダリング)を使用
- docker-composeでAPIサーバー・Nuxtサーバー同時に立ち上げて実装
という環境で、webアプリケーション制作環境を構築していたのですが、なぜか、asyncDataにてAPIサーバーからデータ取得する際に404になる事象があったため、解決法を紹介します!
原因はコンテナ間通信だった・・・
先に結論からお伝えしますと、asyncDataはSSR(サーバーサイドレンダリング)する際にサーバーサイドで実行されるので、初回の通信時のみサーバーサイドでAPIサーバーにデータ取得しに行くことが原因でした。
今回の構築環境でいうと、
- 初回通信(SSR)は、Nuxtコンテナ→APIコンテナ
- 2回目以降の通信は、ブラウザ→APIコンテナ
そのため、2回目以降の通信はブラウザでAPIコンテナのエンドポイントを叩くように、エンドポイントを設定すればよいのですが、初回通信時のみはコンテナ間通信のエンドポイントを設定しなければいけませんでした。
対策
この事象を解決するために、2つの実装を行いました。
- APIサーバー用コンテナとNuxt用コンテナを同一Docker networkに設定して、コンテナ間通信を可能にする
- Nuxtのconfigを変更して、SSRとそれ以外でエンドポイントを切り替えるようにした。
コンテナ間通信を可能にする
Dockerコンテナ間通信を可能にするのは、すごく簡単で、
- Dockerコンテナ同士を同一のnetworksに登録する
- コンテナ名でアクセスする
の、2つだけです。
docker-compose.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
version: '3' services: api: ... container_name: api ports: - '3000:3000' networks: - app_network nuxt: ... container_name: nuxt ports: - 3010:3000 networks: - app_network networks: app_network: |
このように、同一ネットワークに両方のコンテナを設定し、
- SSR時は、http://api:3000/にアクセス
- その他のときは、http://localhost:3000にアクセス
するようにします。
nuxt.config.jsにSSR用のエンドポイントとブラウザ用のエンドポイントを設定する
axiosを使っているのならば、以下の記述でSSR用のエンドポイントとブラウザからのエンドポイントを切り替えることができます。
nuxt.config.js
1 2 3 4 5 6 7 8 |
modules: [ '@nuxtjs/axios' ], axios: { baseURL: "http://api:3000/", browserBaseURL: "http://localhost:3000" }, |
dockerで環境構築すれば、ローカル環境を汚さずに開発ができる!
Nuxtサーバーをローカルマシンで立ち上げれば、このような苦労はなかったです。
しかし、Dockerで環境構築することにより、
- 複数に開発の際に環境差異をなくす
- ローカル環境を汚さずにアプリケーション開発ができる
というメリットがあります!
ぜひ、DockerでNuxt環境を構築してみてください!