Nuxt.js + Typescript + Docker + CircleCI で環境変数を設定して環境構築する


目的

  • Nuxt.js + Typescript + Docker + CircleCI を使って、環境変数を設定してNuxtプロジェクトをビルドします。

環境

  • Node: v10.15.2

    • nodenvを利用し、プロジェクトごとにバージョンを指定することがおすすめです。
  • Docker: version 18.09.2

利用するパッケージ

cross-env

cross-envはyarn or npm スクリプト実行時に環境変数を定義できます。
今回はcross-envNODE_SETTINGSという環境変数を用いて環境の切り替えを行います。

記事の主となるファイル


.
├── Dockerfile # NODE_SETTINGS引数を受け取り、yarnスクリプトを実行します
├── README.md
├── assets
├── .circleci
│   ├── config.yml # Dockerイメージ生成時に --build-args でNODE_SETTINGS引数を引き渡します
├── components
├── config # 環境ごとの変数を定義したファイルを格納するディレクトリです
│   ├── README.md
│   ├── development.ts # 開発環境用の環境変数を定義するファイルです
│   └── production.ts # 商用環境用の環境変数を定義するファイルです
├── css
├── layouts
├── middleware
├── nuxt.config.ts # NODE_SETTINGSに従ってconfigファイルを読み込みます
├── package.json # 環境ごとのscriptを追加します
├── pages
├── plugins
│   └── axios.ts # 環境変数の使用例を記述します
├── server
├── static
├── store
├── tests
├── ts-shim.d.ts
├── tsconfig.json
├── tslint.json
└── yarn.lock

各種インストール

cross-envをinstall

今回はyarnを利用してパッケージの管理をしていきます。


$ yarn add cross-env

(npmを利用する際はこちらのコマンドをご利用ください)


$ npm install cross-env

使用方法

1. 環境ごとの変数を定義したファイルを作成する

今回は以下の2つの環境を作成できるようにします。
作成する環境に従って、 config/{環境名}.tsファイルを作成します。

環境名 備考
developmemt 検証環境
production 商用環境
  • config/development.ts

module.exports = {
  API_HOST: 'https://development-api-url/'
}
  • config/production.ts

module.exports = {
  API_HOST: 'https://production-api-url/'
}

環境ごとにどちらのファイルを読み込むのかは後述で説明します。

2. Dockerfileの編集

Dockerfileの編集を行います。
イメージ生成する際、NODE_SETTINGS変数を受け取り、yarnスクリプトを実行します。



FROM node:10.15.2
# ビルド時に設定する環境変数を受け取っています
ARG ENV_SETTINGS="development"

COPY . /app
WORKDIR /app

RUN apt-get update
RUN yarn install && \
    # 環境ごとのyarnスクリプトを実行
    yarn run build:${ENV_SETTINGS}

ENV HOST 0.0.0.0
EXPOSE 3000

# 環境ごとのyarnスクリプトを実行(※注意1)
CMD yarn start:${ENV_SETTINGS}

こうすることにより、


docker build --build-arg ENV_SETTINGS=${development or production} -t {tag名} .

を実行することで、環境ごとのDockerイメージを生成することができます。

(注意1)
exec形式だと、変数の展開を行わないので、${ENV_SETTINGS}を正しく読み取ることができません。

シェル 形式と異なり、 exec 形式はコマンド・シェルを呼び出しません。つまり、通常のシェルによる処理が行われません。例えば CMD [ "echo", "$HOME" ] は $HOME の変数展開を行いません。シェルによる処理を行いたい場合は、 シェル 形式を使うか、あるいはシェルを直接使います。例: CMD [ "sh", "-c", "echo", "$HOME" ] 。

(公式リファレンス)

3. package.jsonの修正(script追記)

環境ごとのyarnスクリプトを実行し、NuxtプロジェクトにENV_SETTINGS環境変数を渡します。

{
  "scripts": {
    "dev": "nuxt",
    "build": "nuxt build",
    "start": "nuxt start",
    "build:development": "cross-env ENV_SETTINGS=\"development\" nuxt build",
    "start:development": "cross-env ENV_SETTINGS=\"development\" nuxt start",
    "build:production": "cross-env ENV_SETTINGS=\"production\" nuxt build",
    "start:production": "cross-env ENV_SETTINGS=\"production\" nuxt start",
  }
}

4. Nuxt.jsの設定ファイル(nuxt.config.ts)の設定ファイルを編集

yarnスクリプトから渡されたENV_SETTINGS環境変数によって、読み込むファイルを決めます。


// 渡されたENV_SETTINGSを格納しています。ENV_SETTINGSが設定されていなければdevelopmentを格納します。
const environment = process.env.ENV_SETTINGS || 'development';
// 環境ごとの設定ファイルを読み込んでいます。
const envSet = require(`./config/${process.env.ENV_SETTINGS}.ts`)

const config = {
  plugins: [],
  modules: [],

  // 以下の設定を追記してください。
  /*
  ** Load configuration file according to ENV_SETTINGS variable
  */
  env: envSet
  // ここまで

}

export default config

5. 環境変数を使用する

Nuxtプロジェクトの中では、process.env.{環境変数名} で利用することができます。

  • (例)axios.ts

import axios from 'axios'

export default axios.create({
  baseURL: process.env.API_HOST
})

6. (補足)circleCIの設定を編集

circleCIを用いて自動デプロイを行う場合、以下のような処理を追加します。

version: 2
jobs:
  build:
    docker:
      - image: docker:18.09.3
    steps:
      - run:
        name: ...

      - run:
          # Dockerイメージ作成時にENV_SETTINGSを引き渡しています。
        # 今回は、gitのブランチがmasterの場合はproduction, master以外の場合はdevelopmentを格納しています。
          name: Build
          command: |
            env_settings='development'
            if [[ "${CIRCLE_BRANCH}" = 'master' ]]; then env_settings='production'; fi
            docker build --build-arg ENV_SETTINGS=${env_settings} -t {tag名} .
      - run:
          name: Push
          command: docker push {tag名}

  deploy:
   ...

workflows:
   ...

参考にさせていただいた記事

https://qiita.com/TakahiRoyte/items/c152ad8baa191ed1f8ae
https://qiita.com/noonworks/items/179c71deaf3280fa5a1e