WSL環境のDockerを使った形でLaravelとInertiaのReact環境を作るのはできたが、SSRを行おうと思ったら割りとハマった。
ようやくなんとかなったので、そのまとめ。
これまでの内容
Ineratiaの導入(not SSR)
状況
以下のようにWSLにDockerがあり、PHP、nginx、mysql、mysqladminのコンテナがそれぞれ立っている状態です。
WSL以外ではもしかしたら問題なく動くかもしれません。
SSRのサーバー(Inertia SSR server)はLocalPC上でnodeで立ち上げます。
先に解決策
接続先の問題
基本的な設定は公式サイト通りで動くはずだと思います、
Docker利用の場合は少し特殊で、InertiaのSSRではデフォルトで http://127.0.0.1:13714
に接続しようとしますが、接続を試みるPHPコンテナから見て、127.0.0.1
は自分(PHPコンテナ)なので、ローカルPCにたどり着けません。
そのため下記設定を入れます(ファイルはなければ新規追加)。
(私は本番はコンテナ運用ではない状態なので、GitHubには上げないようにしています。)
<?php
return [
'ssr' => [
'enabled' => true,
'url' => 'http://host.docker.internal:13714',
],
]
host.docker.internal
については下記
ポートの問題
上の設定だけではエラーが出ます。PHPのコンテナからローカルのInertia SSR serverに接続できていなかったのが原因で、接続できない理由はWindowsがポートを受けつけていなかったからのようです。
そのためポートを開ける(受け付けるようにする)ことで解消します。
下記はPowershellなので、Windows限定です。
# 受けつけていないことの確認(ポート13714)
> netstat -a
アクティブな接続
プロトコル ローカル アドレス 外部アドレス 状態
TCP 0.0.0.0:80 DESKTOP-2PSEFKJ:0 LISTENING
TCP 0.0.0.0:135 DESKTOP-2PSEFKJ:0 LISTENING
TCP 0.0.0.0:445 DESKTOP-2PSEFKJ:0 LISTENING
TCP 0.0.0.0:3306 DESKTOP-2PSEFKJ:0 LISTENING
TCP 0.0.0.0:5040 DESKTOP-2PSEFKJ:0 LISTENING
TCP 0.0.0.0:5357 DESKTOP-2PSEFKJ:0 LISTENING
TCP 0.0.0.0:7680 DESKTOP-2PSEFKJ:0 LISTENING
TCP 0.0.0.0:8080 DESKTOP-2PSEFKJ:0 LISTENING
(略
# WSLのIPの確認
> wsl -e hostname -I
***.***.***.***
# ポートを開ける(要管理者権限) ***.***.***.***は上のIP
> netsh interface portproxy add v4tov4 listenaddress=* listenport=13714 connectaddress=***.***.***.*** connectport=13714
# 確認
> netsh interface portproxy show all
ipv4 をリッスンする: ipv4 に接続する:
Address Port Address Port
--------------- ---------- --------------- ----------
* 13714 ***.***.***.*** 13714
# curl host.docker.internal:13714
{"status":"NOT_FOUND","timestamp":1681899352326}
サーバーからちゃんとNot Foundが返ってきています(このNotFoundはサーバーが正しく返している形です)。これで通常通りSSRの実装を行えばSSRの形で表示されるようになります。
調査
これまで
上の記事に書いたことですが、下記のようなことが起きていました
- 設定はしたがSSRにならない
- SSR用サーバーにログを仕込むと、サーバーにアクセスが行っていない
- SSR用サーバーを叩くところにログを仕込むと、叩く際に
Failed to connect
で失敗している
PHPコンテナ内で動かせば動く
PHPのコンテナ内でyarn installし、そこで
$ php artisan inertia:start-ssr
とすればPHPからこのSSRサーバーには接続できるので動かすことができます。(ここまで上の記事)
しかし、ファイルの操作の面で手間だったり、ファイルの権限の面で怪しい挙動をしていたのでもう少し調査しました。
コンテナからローカルに接続できない?
やりたいことはphpコンテナからLocalPCに立てたnode port13714のサーバーに接続することです。
// 両方取れる
# curl http://localhost:80
# curl http://localhost:13714
{"status":"NOT_FOUND","timestamp":1681905338769}
↑このエラーが出るのが正しい
ローカルでこういう状態であればWSLでは普通コンテナ側からは host.docker.internal
で取れるはずです。
80ポートのHTTPのものは取得ができますが、13714では取得できません。
// これは取れる
# curl http://host.docker.internal:80
// これが取れない
# curl http://host.docker.internal:13714
curl: (7) Failed to connect to host.docker.internal port 13714: Connection refused
どうして……
// これも同じように返る
# curl http://host.docker.internal:11111
curl: (7) Failed to connect to host.docker.internal port 11111: Connection refused
この適当なポートで叩いても同じように返る状態で、結局は受けつけているところまで達していないのでは?
というので初めに書いた解決策へ移っていきます。
> netstat -a
アクティブな接続
プロトコル ローカル アドレス 外部アドレス 状態
TCP 0.0.0.0:80 DESKTOP-2PSEFKJ:0 LISTENING
TCP 0.0.0.0:135 DESKTOP-2PSEFKJ:0 LISTENING
TCP 0.0.0.0:445 DESKTOP-2PSEFKJ:0 LISTENING
TCP 0.0.0.0:3306 DESKTOP-2PSEFKJ:0 LISTENING
TCP 0.0.0.0:5040 DESKTOP-2PSEFKJ:0 LISTENING
TCP 0.0.0.0:5357 DESKTOP-2PSEFKJ:0 LISTENING
TCP 0.0.0.0:7680 DESKTOP-2PSEFKJ:0 LISTENING
TCP 0.0.0.0:8080 DESKTOP-2PSEFKJ:0 LISTENING
TCP 0.0.0.0:9000 DESKTOP-2PSEFKJ:0 LISTENING
TCP 0.0.0.0:28252 DESKTOP-2PSEFKJ:0 LISTENING
たとえばここに存在してる28252ポートを叩くと違う返り方をする、というか返ってきません。
// これは返ってこない
# curl http://host.docker.internal:28252
というので動きが変わったので、やはりここが怪しそうですね。
下記を参考に設定したところ、つながるようになりました
# WSLのIPの確認
> wsl -e hostname -I
***.***.***.***
# ポートを開ける(要管理者権限)
> netsh interface portproxy add v4tov4 listenaddress=* listenport=13714 connectaddress=***.***.***.*** connectport=13714
これを行うことで無事取れました↓
# curl host.docker.internal:13714
{"status":"NOT_FOUND","timestamp":1681899352326}
これでinertiaの向き先を host.docker.internal
にすれば動きますね。
inertiaの接続周りは特に設定ファイルはないのですが、自分で足せば動きます
config下に適当にinertia.phpを作ります
<?php
return [
'ssr' => [
'enabled' => true,
'url' => 'http://host.docker.internal:13714',
],
]
ちなみにデフォルト値等の設定は \vendor\inertiajs\inertia-laravel\config\inertia.php
にあります。