yagish履歴書は、システム1人、デザイン1人、イラスト1人、計3人の小さなチームで作っていて、開発は非常に身軽なので、本番公開時もローカルの開発環境+Firebase本番環境だけだった。
でもさすがに大きな変更を本番でやるのは怖いので、手間と費用をなるべく抑えつつ、Firebaseを使ったステージング環境を構築することにした。
開発環境はVue CLI 3で構築。
環境変数
これは3ファイルで分ける
.env.production .env.development .env.staging
ステージング環境について公式ドキュメントに書いてあるので、参考にする。
cli.vuejs.org
.env.staging
NODE_ENV=production VUE_APP_TITLE=My App (staging)
ただNODE_ENVを上書きしてしまうので、ステージングの時に切り替えたい部分でNODE_ENV === 'staging'を判定に使うことができないため、VUE_APP_MODEという変数を追加して使うことにした。
あんまりきれいじゃない。
.env.staging
VUE_APP_MODE=staging
ビルド時に書き出しディレクトリを変えて、Dockerコンテナは一つで済ませる
開発環境はDockerコンテナで行っているが、これを本番、ステージングなどで分けてしまうと面倒くささが圧倒的に増すのでやりたくない。
開発サーバーの実行、ステージング用ビルド、本番用ビルドもすべて一つのコンテナで行う。
まず、buildコマンドを明示的にbuild-staging、build-productionでそれぞれ--modeをつけて分ける。
package.json
{ "name": "yagish", "version": "1.1.0", "private": true, "scripts": { "serve": "vue-cli-service serve", "build-staging": "vue-cli-service build --mode staging", "build-production": "vue-cli-service build --mode production", // etc... }, // etc...
これだけだとビルドしたファイルが同じdistディレクトリに入ってしまい、間違えてステージングのファイルを本番にデプロイなんてことも起きそうなので分ける。
書き出し先ディレクトリはvue.config.jsのoutputDirで行う。
上記で書いた環境変数を使ってディレクトリを変える関数を作って切り替えた。
vue.config.js
const getOutputDir = () => { if (process.env.VUE_APP_MODE === "production") { return 'dist-production' } else if (process.env.VUE_APP_MODE === "staging") { return 'dist-staging' } } module.exports = { outputDir: getOutputDir(), // etc...
この設定でステージングはdist-stagingディレクトリに、
本番はdist-productionに書き出されるようになった。
distディレクトリは間違わないよう消しておいた
Firebaseにデプロイ
次にFirebase Hostingでデプロイ先プロジェクトを分ける設定。
もちろん事前に本番用、ステージング用でプロジェクトを作っておく。
公式にあった
Firebase CLI リファレンス | Firebase
firebase use --add
でステージング、本番用の設定を追加しておく
firebae.jsonに書くpublicはdeploy時、-pオプションで上書きできるのでこれで分ける。
最終的にステージングへのビルド、デプロイは下記2つで完了する
yarn build-staging firebase deploy --project your-staging-project-name -p dist-staging
本番はこんな感じ
yarn build-production firebase deploy --project your-production-project-name -p dist-production
これを実行中の開発用Dockerコンテナでexecするためシェルスクリプト化した。
staging_deploy.sh
sudo docker exec -it \ $(sudo docker ps -a -q --filter="name=your-container-name") \ yarn build-staging sudo docker exec -it \ $(sudo docker ps -a -q --filter="name=your-container-name") \ firebase deploy --project your-staging-project-name -p dist-staging date
本番用はビルドでこけたらデプロイしないように止める必要がありそう。
API用のGKEとロードバランサーは本番と同じのを使う
GCPのHTTPSロードバランサーは最低2000円/月ぐらいしてしまうので、分けるのは避けたい。
またドメインを分けるとSSL証明書とかの手間も増えるのでドメインも同じにしたい。
今回はHTTPSロードバランサーの設定でアクセスしてきたパスでバックエンドを分けた。
/api → 本番用バックエンド
/api-staging → ステージングバックエンド
というように振り分けるようにして、APIではどちらのパスも同じ処理へルーティングして同じコンテナでどちらでも動くようにした。
Vue側は環境変数で切り分ける。
まだ使ったことないけどIngressを使えばもっと簡単にできそうなので調査中。
CORSの設定
許可ドメインの設定はFirebaseや、GoogleのAPIキー、Cloud StorageとかDjangoとか使ってるサービスごとにやるので何気にめんどう。
chromeのdeveloper consoleのエラーを見ながら設定しておく。
Vue.jsとFirebaseで作るミニWebサービス (技術書典シリーズ(NextPublishing))
- 作者: 渡邊達明
- 出版社/メーカー: インプレスR&D
- 発売日: 2018/07/13
- メディア: Kindle版
- この商品を含むブログを見る