🚢

コンテナ起動時にNuxtに環境変数を与えるには?

4 min read

困っていること

Nuxt.jsでは環境変数を設定して、APIの接続先を切り替える場合、build時に値が埋め込まれます。
NuxtアプリのDockerコンテナイメージを作成してリポジトリにpushしておき、実行時に環境に応じたAPI接続先でコンテナイメージを起動したい場合、それではうまくいきません。

この記事では、「NuxtアプリのDockerコンテナイメージを起動する際に、環境変数に設定したAPIの接続先を切り替えるには?」について書いています。

やりたいこと

NuxtアプリのDockerコンテナイメージを起動する際、API_URLという環境変数にAPIの接続先を設定し、axiosのbaseURLを環境変数値に設定します。

コマンド実行イメージ
$ docker run -d -e API_URL=http://hoge.staging:2000 -p 3000:3000 webapp:latest

API_URLという環境変数を変えることで本番/ステージング/開発等の接続先を切り替えたい…

実現方法

最初に結論を言うと、nuxt-env を使って実行時の環境変数を取り込めるようにします。

参考記事:

https://dokuo.net/vue-js/nuxt-env/

今回のサンプルソース(GitHub):

https://github.com/hiszuk/nuxt-docker

サンプルプロジェクト作成

今回の動作確認用のサンプルプロジェクトを作成します。

create-nuxt-app

create-nuxt-appでベースとなるプロジェクトを作成。

$ npx create-nuxt-app nuxt-sample

オプションは以下を選びました。

create-nuxt-app v3.4.0
✨  Generating Nuxt.js project in nuxt-sample
? Project name: nuxt-sample
? Programming language: JavaScript
? Package manager: Npm
? UI framework: None
? Nuxt.js modules: Axios
? Linting tools: ESLint, Prettier
? Testing framework: None
? Rendering mode: Universal (SSR / SSG)
? Deployment target: Server (Node.js hosting)
? Development tools: jsconfig.json (Recommended for VS Code if you're not using typescript)
? Continuous integration: None
? Version control system: Git

Rendering modeをSSR/SSGにしないと起動時に環境変数渡すことは出来ません。

Linting tools はお好みで。

nuxt-envインストール

引き続き nuxt-sample ディレクトリに移動し、nuxt-env を入れていきます。

$ cd nuxt-sample
$ npm install nuxt-env

nuxt.config.js設定追加

configファイルにnuxt-env、axios、pluginの設定を追加します。

nuxt-sample/nuxt.config.js
export default {
    // 略
  plugins: [
    { src: '~/plugins/apiurl.js'}
  ],
    // 略
  modules: [
    '@nuxtjs/axios',
    ['nuxt-env', { keys: [{ key: 'API_URL', default: 'http://localhost:2000' }] }]
  ],
    // 略
}
  • plugins/apiurl.js -> 環境変数を取得しaxiosのbaseURLを設定するモジュール
  • ['nuxt-env'... -> 環境変数名API_URLを追加し、初期値としてhttp://localhost:2000を設定

plugin作成

実行時に設定された環境変数の値を取得し、axiosのbaseURLを設定するモジュール

nuxt-sample/plugins/apiurl.js
export default (context) => {
  context.app.$axios.defaults.baseURL = context.app.$env.API_URL
}
  • middleware/pluginで取得する場合 -> app.$env.XXXX
  • vueで取得する場合 -> this.$env.XXXX

動作確認用にindex.vue修正

axiosのbaseURLを取得して、環境変数の内容を表示します。

nuxt-sample/pages/index.vue
<template>
  <div class="container">
    <div>
      <Logo />
      <h1 class="title">nuxt-sample</h1>
      <h3>axios base url => {{ $axios.defaults.baseURL }}</h3></div>
  </div>
</template>

Dockerコンテナ化

以下のようなディレクトリ構成でDockerコンテナ化を行います。

./.dockerignore
./.gitignore
./Dockerfile
./nuxt-sample
    |-- :

イメージのビルド

次のDockefileでNuxt.jsのアプリをコンテナ化します。

Dockerfile
FROM node:14.15.3

# パッケージアップデート
RUN apt-get update

# NUXTソースファイルコピー
WORKDIR /webapp
COPY nuxt-sample /webapp

# ライブラリを取得しビルド
RUN npm install
RUN npm run build

ENV HOST 0.0.0.0

CMD ["npm", "run", "start"]

EXPOSE 3000

ビルドを実行し、sample/webapp:laetst という名前でイメージを作成します。

イメージビルド
$ docker image build -t sample/webapp:latest .

動作確認

  • 環境変数に何も与えない場合はhttp://localhost:2000 となる ⏬
環境変数なし
docker run -d -p 3000:3000 sample/webapp:latest

環境変数なしの動作画面
環境変数なしの動作画面

  • 環境変数にhttp://api.staging:3000 を与えた場合 ⏬
環境変数あり
docker run -d -e API_URL=http://api.staging:3000 -p 3000:3000 sample/webapp:latest

環境変数ありの動作画面
環境変数にhttp://api.staging:3000を設定した場合の動作画面

まとめ

  1. Nuxt.jsで実行時に環境変数を読み込むにはnuxt-envを利用する
  2. nuxt.config.jsのmodulesでnuxt-env設定を追加する
  3. nuxt-env設定ではkeysに環境変数を記述する
  4. 環境変数を利用する場合は$env.XXXXで参照する

勘違いや、もっと良い方法がある場合は、ぜひコメントに。
最後まで読んでいただきありがとうございました。

Discussion

ログインするとコメントできます