フロントエンドのコンテナイメージを作ったことないバックエンドエンジニアが偉そうに「フロントエンドのコンテナもDev, QA, Stage,Prod環境で同じものを使うべき」と言ったのに出来なくて赤っ恥をかいたという話。
何が起きていたか
上に書いた通りなんですが、フロントエンドのコンテナイメージを環境ごとに作成していました。作成していたコンテナイメージはSingle Page Applicaion(以下SPA)でWebブラウザ上で動作するフロントエンドです。バックエンドエンジニアとしては環境ごとにコンテナイメージを生成するのは気持ちが悪いですよね。「Stage環境とProd環境で違うコンテナイメージを使ってたら、テストしたものと違うのをProd環境にデプロイするんだから信頼性なくない?」って気持ちになるのではないかと思います。これは良くないと思い、「全部の環境で同じコンテナイメージを利用しましょう」と提案しました。
何が問題だったのか
各環境で別のコンテナイメージを作成しなければならなかった理由は 環境毎にバックエンドのホスト名が違うから でした。
バックエンドエンジニアなら「ホスト名を環境変数に入れればいいじゃん」となると思います。しかし、フロントエンドはWebブラウザ上で動作します。サーバ上で動作していないので、サーバの環境変数をそのまま使うことはできません。こうなるとサーバの環境変数をブラウザ上に注入する仕組みが必要になります。
何故できなかったのか
今回のSPAの構成は React + Next.js + Nginx でした。 React + Next.js のレベルではSPAの生成方法として以下の3つがあります。
- Statis Site Generation(SSG)
- Server Side Rendering(SSR)
- Client Side Rendering(CSR)
Next.jsではSSGがパフォーマンス的に推奨されています。今回のフロントエンドでもSSGが採用されていました。ビルド時に export
をして事前に静的HTMLを作成していました。SSGでは export
時に静的HTMLを生成し、それをNginxからWebブラウザに配布します。このため、Webブラウザの配布時にホスト名を変更するという方法は利用できなくなります。
SSRを利用するにはWebサーバをNode.jsに変更しなければなりません。また静的HTMLを使う場合はSSRは使えません。今更サーバを変更できず、かつ静的HTMLを使うことも変更できなかったのでSSRは使えませんでした。
最後の方法はCSRです。これを使えば各環境で同じコンテナイメージを利用可能でした。ただし以下の2つの理由から不採用になりました。
- 修正が多く、そのコストとリスクを払う価値がなかった
- ホスト名を取得するためにHTTP通信が発生するためユーザ体験を損なう可能性があった
最初にCSRでホスト名を取得する方式をとっておけばコンテナイメージを同一にできる可能性はあったのですが、今更変えられない状況でした。
赤っ恥をかいた
バックエンドエンジニアがフロントエンドの流儀も知らずに偉そうなことを言って赤っ恥をかきました。とても恥ずかしかったですが、知らない事やわからない事をそのままにしておくと、成長もありません。敢えて恥をかきに行き、知識を増やしましょう。