今更ながらDockerに入門する〜環境ごとにNuxt.jsを動かす〜

初Qiita投稿です。藤原脩平です。
普段は社内で自社サービスの開発をしております。フロント(Vue.js, Nuxt.js),バックエンド(Java, Spring)両方頑張っています。
仕事以外ではUXの勉強をひたすらにやっています。
ここら辺をテーマにいろいろ書いていこうかなぁ、と考えております。

今日はNuxt.jsのお話。

## なんで書こうと思ったの？
業務でNuxt.jsを使っていますが、環境別にconfigファイルを読み込む必要が。
（ローカルに環境変数を設定して動作確認して・・・）ってのは、ちょっとナンセンスだなーと。そんな時、頭によぎったのが彼。
![docker.png](https://qiita-image-store.s3.amazonaws.com/0/309087/10301190-373c-5b7c-1b99-94ad557031bf.png)

そう、Dockerならね。

Docker使ったことないし、この機会に触ってみようかな！と思い立って、本題に入ります。

## 事前準備
### そもそもDockerとは？
先人の知恵を借りましょう。
[こちら](https://knowledge.sakura.ad.jp/13265/)が分かりやすかったです。

### Dockerのインストール方法
公式の知恵を借りましょう。
今回は、Docker for Macを使いました。
https://docs.docker.com/docker-for-mac/install/

## Nuxt.jsの準備
### Nuxt.jsで環境別configファイルを用意する
利用したコードはこちらです。
https://github.com/kdmoaa/docker-nuxt

今回は以下の環境を用意しました。

 - development:開発環境
 - staging:ステージング環境
 - production:本番環境

各環境ごとにconfigファイルを用意します。
サンプルとして開発環境のファイルを載せます。

```env.development.js
module.exports = {
  envVar: 'development' // ここにAPIなどを定義して環境ごとに切り分けたり
}
```

Nuxt.jsで環境変数を参照して利用するファイルを切り分けます。

```nuxt.config.js
const environment = process.env.NODE_ENV || 'development'
const property = require(`./env.${environment}.js`)

module.export = {
// 中略
    env: {                        
        envProp: property.envVar
    }
}
```

コンポーネントからは`process.env.envProp`で参照できます。

```index.vue
<script>
export default {
  data() {
    return {
      env: process.env.envProp
    }
  }
}
</script>
```
#### tips
https://ja.nuxtjs.org/api/configuration-env/#process-env-
公式にも載っていますが、`process.env`だけだと何も返ってこないので要注意。
（試しにできてるかなーと思って`process.env`だけ定義してたら動かなくて困った。）

### cross-envで環境を切り分ける
cross-envとは、Nodeライブラリです。環境変数をもとに実行タスクを変えてくれます。
`npm -i --save cross-env`で取り込み、package.jsonのscriptsにタスクを用意します。

```package.json
{
  "name": "nuxt-docker",
  "version": "1.0.0",
  "description": "My ultimate Nuxt.js project",
  "author": "kdmoaa",
  "private": true,
  "scripts": {
    "dev": "nuxt",
    "build": "nuxt build",
    "build:stg": "cross-env NODE_ENV=\"staging\" nuxt build",
    "build:prod": "cross-env NODE_ENV=\"production\" nuxt build",
    "start": "nuxt start",
    "start:stg": "cross-env NODE_ENV=\"staging\" nuxt start",
    "start:prod": "cross-env NODE_ENV=\"production\" nuxt start",
    "generate": "nuxt generate"
  },
  "dependencies": {
    "cross-env": "^5.2.0",
    "nuxt": "^2.0.0"
  },
  "devDependencies": {
    "nodemon": "^1.11.0"
  }
}

```
環境変数`NODE_ENV`を見て起動タスクを判別してくれます。素敵！！

## dockerの準備
### dockerで多環境を用意する
今回はdocker-composeを利用しました。
おそらくdocker単体で十分事足りるのだろうけど、調べていてとっつきやすそうだったのがdocker-composeでした。
ここら辺の違いはちゃんとまとめて後日書こうかしら。

まずはdocker-compose.ymlを用意します。

```docker-compose.yml
version: "3"
services:
  web:
    build:
      context: ./
    privileged: true
    volumes:
      - "../app/:/usr/local/app"  ## ../app/に存在するNuxtプロジェクトをdockerの/usr/local/app/に配置
    ports:
      - 80:80
      - 3000:3000
    container_name: "nuxt-docker-dev"
    environment:
      - NODE_ENV=development  ## nuxt.config.jsで利用する環境変数 NODE_ENV を定義
```

続いてDockerfileを用意します。


```Dockerfile

FROM centos:7.4.1708

RUN yum -y update

RUN yum -y install epel-release
RUN yum -y install http://rpms.remirepo.net/enterprise/remi-release-7.rpm

RUN yum -y upgrade
RUN yum -y install nginx

RUN curl -sL https://rpm.nodesource.com/setup_9.x | bash -
RUN yum install -y gcc-c++ make
RUN yum install -y nodejs
RUN yum install -y wget
RUN wget https://dl.yarnpkg.com/rpm/yarn.repo -O /etc/yum.repos.d/yarn.repo
RUN yum install -y yarn

ENV HOST 0.0.0.0

CMD ["nginx", "-g", "daemon off;"]

WORKDIR /usr/local/app
```
これで一通りの準備は完了しました。

## さて、動かそう
あとは実行するのみです。

```bash
$ docker-compose build  # dockerを構築
$ docker-compose up -d  # デーモンでコンテナを立ち上げる
$ docker-compose exec web bash  # 実行してコンテナに入る

# ここからdockerコンテナ内で操作
$ yarn install
$ yarn run build  # 環境は指定しなくても勝手に分けてくれる
$ yarn start
```

/develop配下でdocker-composeを実行するとこうなりますし、
<img width="836" alt="development.png" src="https://qiita-image-store.s3.amazonaws.com/0/309087/ed9ffca4-4e4e-4c1d-8087-4f98ed81a175.png">

/staging配下でdocker-composeを実行するとこうなります。
<img width="819" alt="staging.png" src="https://qiita-image-store.s3.amazonaws.com/0/309087/a46a66e5-e996-17ad-6531-cc0cc73a37d4.png">

やったぜ、動いた！

## 参考にしたもの
 - https://knowledge.sakura.ad.jp/13265/
   dockerとは何者か、についてはこちらで勉強させていただきました。

 - https://qiita.com/ProjectEuropa/items/d9ee1b8c96084e3bab55
   docker-compose.ymlやDockerfileの書き方はこちらを参考にさせていただきました。