Cloud Runに設定した環境変数をNuxt製アプリに反映する方法

どーも、ぐるたか@guru_takaです。

Cloud Run上で環境変数を設定し、Nuxt製アプリをデプロイする方法を紹介します。めちゃくちゃ詰まったので、備忘録も兼ねています。

MEMO
Cloud Runへのデプロイ方法は割愛します。 以下の記事に、Cloud RunでNuxt製アプリをデプロイする方法をまとめているので、ぜひ参考にしてみて下さい! SSRモードのNuxt製アプリをCloud Runでデプロイする方法

Cloud Runに環境変数を設定する方法

まず、Cloud Runに環境変数を以下のように設定します。

まずは、「新しいバージョンをデプロイ」をクリック!

その後、環境変数を適宜、設定すれば完了です。

参考 環境変数の使用 | Cloud Functions のドキュメント | Google Cloud

Cloud Runに環境変数を登録するだけではNuxt製アプリに反映されない

1番詰まったポイントです。Netlifyやherokuのように、サーバー側に環境変数を入力すれば普通に動くだろう…という気持ちでした。

いざやってみると、「え、環境変数が全く反映されない…(滝汗)」と、焦るばかり。

ググる&試行錯誤した結果、色んな知見と代替案、また根本的な解決方法がわかったので、紹介していきます

Cloud Runに環境変数を登録するだけではダメな理由

結論からいうと、dockerのイメージをビルド→ランする時点で、Nuxtファイル内のprocess.env.~~~~が置き換わる仕様だからです。

その結果、DockerのCMD ["npm", "run", "start"])実行時(ランタイム)に、環境変数を渡したくても、すでにprocess.env.~~~~が置き換わっているので、何も反応しないのです。

代替案と問題点

まず、超簡単な代替案が2つ浮かびました。

  • Clurd Runにデプロイする時、.envもアップロードする
  • DockerfileENV ~~~と直書きし、環境変数を設定する

上記2つのやり方によって、環境変数は設定できます。しかし問題として

  • .envをアップロードすると、外部に漏洩する恐れあり
  • Dockerfileに環境変数を直書きすると、イメージ1つで環境を切り替えできない
  • チーム開発する際、環境変数の管理が大変

が挙げられるので、オススメできません。

やはり1番スマートなのは、process.env.~~~~が置き換わるタイミングが、Nuxtのコンパイル時ではなく、ランタイム時であればベストであり、万事解決するわけです!

方法を探してみると、色々な記事で紹介されているnuxt-envというモジュールで、無事に解決できました🎉
参考 Nuxtでdockerを利用した際に環境変数が反映されない問題をnuxt-envで解決する | 毒男日記

nuxt-envを使った具体的な対応策

公式リポジトリは以下のリンクからチェックできます!

最初の紹介文に記載されているいる通り、Nuxtがランタイムする時に環境変数を切り替えてくれます。
参考 samtgarson/nuxt-env: Inject env vars for your Nuxt app at runtime

まずは、以下のようにインストールします。

コマンドライン
$ npm install --save nuxt-env

そして、以下のようにnuxt.config.jsを設定します。

nuxt.config.js
//必須
require('dotenv').config()
~~~~~~~~~~~~~
  modules: [
    'other-nuxt-module',
    [
      'nuxt-env',
      {
        //環境変数のkeyを入れていけばOK!
        //.envのkeyを入れないと、ランタイム時に反映されないので注意
        keys: ['~~~', '~~~',...]
      }
    ]
  ],
~~~~~~~~~~~~~

modules内に'@nuxtjs/dotenv'はいらないのですが、require('dotenv').config()は必須なのでご注意下さい!

あとは、公式に記載されている使い方をすればOKです。以下のサンプルは、公式readmeの引用になります。

まず、クライアント側では、this.$env.KEYを使いましょう。

any-component.vue
export default {
  computed: {
    testValue () { return this.$env.TEST_VALUE }
  }
}

サーバー側では、app.$env.KEYを使えばOKです!

any-component.vue
export default {
  asyncData ({ app }) {
    console.log(app.$env.TEST_VALUE)
  }
}

this.$env.KEYprocess.env.KEYにしたい場合は、以下の記事を参考にpluginを定義すれば可能です!
参考 【Nuxt.js】nuxt-envを少し使いやすくする | Qrunch(クランチ)

ただし、あくまでクライアント側のみです。サーバー側ではprocess.env.KEYではなく、app.$env.KEYでないと反映されないので注意しましょう!

参考リンク

参考 docker-composeの環境変数.envをNuxt.jsに渡す方法 - DJ lemon-Sour's diary (prod.hisasann) 参考 環境変数の使用 | Cloud Functions のドキュメント | Google Cloud

コメントを残す