目的
- Nuxt.js + Typescript + Docker + CircleCI を使って、環境変数を設定してNuxtプロジェクトをビルドします。
環境
-
Node: v10.15.2
- nodenvを利用し、プロジェクトごとにバージョンを指定することがおすすめです。
-
Docker: version 18.09.2
利用するパッケージ
cross-env
cross-env
はyarn or npm スクリプト実行時に環境変数を定義できます。
今回はcross-env
とNODE_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