Django、nuxt.js、expressなどを利用したサンプル環境を次のような構成で構築してみました。
nuxt.js・・・SSR・フロントエンド
express、Django・・・APIサーバー
Djangoはホストマシンで稼働
nuxt.js,experssはDockerで稼働
MySQLは別コンテナで稼働
各リソース(Django,express,nuxt)の学習用に検討しながら組んだものですが、
この記事ではリソース間の通信部分について整理してみました。
Django、express、nuxtの諸々の部分はまた別途整理したいと思います
###ホストマシンからDockerコンテナへの通信
Dockerを開発で使っていると一番よく使うケースと思いますが、
所定のポートを紐付けてコンテナを立ち上げてlocalhostでアクセスします。
MySQLコンテナ
docker run \
・・・
-p 13306:3306 \ #localhostの13306をコンテナ内の3306にバインド
・・・
-itd mysql:5.7
node.jsコンテナ
docker run \
・・・
-p 3000:3000 \ #localhostの3000をコンテナ内の3000にバインド
-p 3001:3001 \ #localhostの3001をコンテナ内の3001にバインド
・・・
node:latest
nuxt.jsからexpressへのアクセスは3001ポートでアクセスします
(ここは、ブラウザからの通信も、nuxt.jsのSSRでも同じでいけます)
async fetch(context): Promise<void> {
・・・
const api_host = 'http://localhost:3001'
・・・
const response = await (context as any).$axios.$get(
api_host + ・・・
)
###ホストマシン内での通信
Djangoはホストマシン内のPythonの仮想環境で動かしています
ブラウザからの通信は同じホスト内通信なので、localhost:8000となります
これも普通ですね
ですが、この構成の時、nuxt.jsのSSR(process.server==true時)では
localhost:8000 では通信できません(後述)
async fetch(context): Promise<void> {
let api_host: string
//サーバーサイドレンダリングのとき
if (process.server) {
api_host = ??????
}
//ブラウザからのアクセスの時
else {
api_host = 'http://localhost:8000'
}
const response = await (context as any).$axios.$get(
api_host + ・・・
)
###同一コンテナ内での通信
nuxt.jsのサーバーサイドレンダリング時に、nuxt.jsから同一コンテナ内のexpressに通信します
同一コンテナ内で3001でlistenしているexpressなので、localhost:3001で通信できます
(ブラウザからの通信時と同じです)
###コンテナ間通信
node.jsコンテナからMySQLの別コンテナに通信します
この場合、コンテナ名でアクセスすれば3306ポートでアクセスできます
###コンテナからホストマシンへの通信
この記事の本題のような部分です
この絵の中で、node.jsコンテナのlocalhostはコンテナ内を指します
では、nuxt.jsからSSRでDjangoへアクセスする術があるのか、ということになり詰まりました。
結論としては、
Docker Desktop Mac 環境ではこのホスト名でアクセスができました
http://host.docker.internal:8000
ただ、これはおそらく Docker Desktop(windows版でも?)で利用可能なホストのようです
windowsでも同じ構成のアプリを構築しているのですが、諸事情でwindowsでは Docker Desktopは
インストールしていなくて、virtualboxのcentosにDockerを入れて使っています。
この時は、コンテナ内からホストマシンへのアクセスにhost.docker.internal
は有効ではありませんでした。
コンテナから、virtualboxのcentosを通り越して、Windowsに通信する必要がありそうですが、
この解決については以下の記事がドンピシャで参考にさせていただきました
Windows + VirtualBox + Docker で動作しているコンテナからホスト OS へのアクセス
virtualboxのcentosで以下を叩きます
$ ip r
default via 10.0.2.2 dev eth0 proto dhcp metric 100
10.0.2.0/24 dev eth0 proto kernel scope link src 10.0.2.15 metric 100
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1
172.18.0.0/16 dev br-25ec00a7e9f1 proto kernel scope link src 172.18.0.1
172.19.0.0/16 dev br-94818cb53527 proto kernel scope link src 172.19.0.1
192.168.33.0/24 dev eth1 proto kernel scope link src 192.168.33.11 metric 101
default via
がデフォルトゲートウェイになるようで、
このIP10.0.2.2
を通してコンテナからWindowsへの通信ができました
http://10.0.2.2:8000
nuxt.js上では、Mac,windowsの環境毎に、.envで接続用のホストを定義して利用しています。
このあたりのコードの詳細は別途まとめたいと思っています。