VueCLI4をdocker-composeで環境構築する際のすゝめ

## はじめに
『**VueCLI4**を**Docker**、**docker-compose**にて環境を構築したい！』と思うときがありますよね〜

- バックエンドでDocker使ってる！
- PCに直接ダウンロードしたくない！
- 環境が壊れるのが嫌だ！

理由は様々です(｡･_･｡)

そんな中環境を構築していくのですが、**Docker**や**docker-dompose**を用いてVue CLI4の環境を構築する際に、僕的に少し手間取った部分があったので、そんな部分も解説しつつ、まとめていこうと思っております。

## 開発環境
- Ubuntu:18.04
- VSCode
- VueCLI:4.1.2
- Node:12.14.1
- npm:6.13.4
- 主はVue初心者


## まず完成形のディレクトリ構成図を確認
何を作るにしろ完成図が思い浮かばなければ、難しいと思うので、先に載せておきます(/･ω･)/

```directly:完成形ディレクトリ構成図
sample-project
　     ├ vue-sample
　     │　  ├ dockerfile
　     │　  └ vue createによって作成させるファイル&フォルダ群
　     └ docker-compose.yml
```

今回は上図を意識できていれば完璧です。(※まだ作らないで！)

この配置を解説すると、プロジェクト内に他のアプリケーション(コンテナ)を作成することを意識して、docker-composeをsample-projectディレクトリ直下に置いて、あくまでアプリケーションの１つとしてVueのvue-sampleアプリケーションを置いている形です。

## 実際に作業をしていく！
作業をしていきたいのですが、チョット待ってください！！実は簡単にはあの構成図通りには作れません。理由は後々。

### 最初の構成図を確認
まずこの構成図に従ってフォルダと中身のないファイルを作成してください。

```directly:未完成ディレクトリ構成図1
sample-project
　     ├ dockerfile
　     └ docker-compose.yml
```

### Dockerfileを記述
それではまずDockerfileから記述していきます。

```dockerfile:Dockerfile
FROM node:12.14.1

WORKDIR /code

RUN npm install -g @vue/cli
# COPY ./package*.json /code/
# RUN npm install
```

- FROMにて[DockerHub[1]](https://hub.docker.com/_/node)からベースイメージを取得しています。
- WORKDIRにて作業ディレクトリを決めています。今回だとコンテナ内のcode下を作業ディレクトリとしています。
- １つ目のRUNにてnpmを使ってVueCLIをインストールしています。
- COPYにてpackage.jsonとpackage-lock.jsonをコンテナ内にコピー。[package-lockもCOPYする理由はコチラ[2]](http://bitjudo.com/blog/2014/03/13/building-efficient-dockerfiles-node-dot-js/)
- 最後のRUNにてpackage.jsonに書かれているすべてのパッケージをinstallします。

下２つのプログラムは```vue create```した後でないと意味がありません。なので今はコメントアウトしております。

### docker-composeを記述
次にdocker-composeです。

```yml:docker-compose.yml
version: '3'

services:

  front:
    build:
      context: ./
    command: "npm run serve"
    volumes:
      - ./vue-sample/:/code/
    ports:
      - "8080:8080"
```

frontでコンテナ名をfrontとします。
contextでDockerfileの在り処であるカレントディレクトリ示す。
commandで```docker-compose up```した時にサーバーを立ち上げれるように```npm run serve```を書いておきます。
volumesでコンテナ内のcodeがホストのvue-sampleアプリケーションにマウントされるようにする。(vue初心者なので、すべてをマウントしてますが、経験者であれば改変したほうが良きです。)
portsでホストとDockerのportを書く

### docker-composeでbuildしよう！
次にdocker-compose経由でDockerfileの内容をbuildしていきます。

```cli:CLI
user@group:~/sample-project$ docker-compose build front
```

成功すればこんなのが出てきます。

```cli:CLI
Successfully tagged vuesample1_front:latest
```

### docker-composeでvue createしよう！
```vue create```を実行すると問答無用で新しいアプリケーションフォルダを作成されます。またこのとき大量にnode_modulesが作成されます。
主はそのせいで、『VSCodeがワークスペース足りないよ〜』と通知されたので、Ubuntuの設定ファイルをいじりました。笑
[参考文献はコチラ(VSCode公式Document)[3]](https://code.visualstudio.com/docs/setup/linux#_visual-studio-code-is-unable-to-watch-for-file-changes-in-this-large-workspace-error-enospc)

気持ちの準備ができたら、以下のコマンドを実行してください。

```cli:CLI
user@group:~/sample-project$ docker-compose run --rm front vue create vue-sample
```

上のコマンドを実行するといくつかの選択肢が出てきます。恐らくどの選択肢でもOKですが、主の選んだ選択肢はコチラ

```cli:CLI
?  Your connection to the default yarn registry seems to be slow.
   Use https://registry.npm.taobao.org for faster installation? No


Vue CLI v4.1.2
? Please pick a preset: default (babel, eslint)
? Pick the package manager to use when installing dependencies: NPM
```

node_modulesが大量にインストールされてしまいましたね。それは正常な動作なので大丈夫です。

ではLinux系の方はとりあえずvue-sampleはroot権限になっているので、Rオプションを使って全てuserにchownします。※Macはどうなのかな？？

```cli:CLI
user@group:~/sample-project$ sudo chown -R user:user vue-sample
```

ではvue-sampleフォルダの中身を見てみましょう。

おや？同じフォルダが重なっていますね。これは```vue create```とdocker-composeのvolumeがそれぞれvue-createしていることによって引き起こされています。

```directly:未完成ディレクトリ構成図2
sample-project
　     ├ vue-sample
　     │　   └ vue-sample
　     │　         └ vue createされたファイル/フォルダ群
　     ├ dockerfile
　     └ docker-compose.yml
```

### vue-sampleフォルダを１つに。
これが少し面倒で、今のままではディレクトリの構造が汚く、Docker関係のファイルのPathがうまく通らなくなってしまいます。なので下図のようにしたいです。

```directly:未完成ディレクトリ構成図3
sample-project
　     ├ vue-sample
　     │　    └ vue createされたファイル/フォルダ群
　     ├ dockerfile
　     └ docker-compose.yml
```

次の動作を行ってください。

1. package.jsonやnode_modulesが入っている<font color="green">vue-sample</font>フォルダを切り取る
2. sample-project下の<font color="blue">vue-sample</font>の名前を<font color="blue">vue-sample1</font>に書き換える
3. sample-project下に切り取った<font color="green">vue-sample</font>を貼り付ける
4. 未完成ディレクトリ構成図3の出来上がり

この順番で行うことによって、この一連の流れを膨大な量のnode_modulesを消さずに済みます。

### Dockerfileの位置を変える
では最初に見せた完成図にします

Dockerfileをvue-sample下に移動します。

```directly:完成形ディレクトリ構成図
sample-project
　     ├ vue-sample
　     │　  ├ dockerfile
　     │　  └ vue createによって作成させるファイル&フォルダ群
　     └ docker-compose.yml
```

するとこの形が出来上がっているのではないでしょうか？

あとはDockerfileを動かしたことによって、Pathがうまく通ってないので、docker-composeを書き換えます。

### docker-composeを書き換える

```yml:docker-compose.yml
version: '3'

services:

  front:
    build:
      context: ./vue-sample #変えた
    command: "npm run serve"
    volumes:
      - ./vue-sample/:/code/
    ports:
      - "8080:8080"
```

これによりvue-sampleディレクトリ下にいたDockerfileの場所を教えることができました。

### Dockerfileのコメントアウトを外す

```dockerfile:Dockerfile
FROM node:12.14.1

WORKDIR /code

RUN npm install -g @vue/cli
COPY ./package*.json /code/
RUN npm install
```

これでプログラムを書く作業は終わりです！！
早速buildしていきましょう。

```cli:CLI
user@group:~/sample-project$ docker-compose build front
```

## ついにサーバーを立ち上げる！
ラストです。サーバーを立ち上げましょう(/･ω･)/

```cli:CLI
hiroto@hinatazaka43:~/vue/vue-sample-1$ docker-compose up -d front
Starting vuesample1_front_1 ... 
Starting vuesample1_front_1 ... done

hiroto@hinatazaka43:~/vue/vue-sample-1$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
コンテナID  　　      vuesample1_front    "docker-entrypoint.s…"   About an hour ago   Up 35 seconds       0.0.0.0:8080->8080/tcp   vuesample1_front_1
```

しっかりポートも通っていることを確認したら、```http://localhost:8080```にアクセスしてみましょう！

![Screenshot from 2020-01-11 22-49-22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436088/19764278-45f6-f89a-2849-1095ebf6d797.png)

お疲れ様でした(｡･_･｡)

## さいごに
最後まで読んでいただきありがとうございました。個人的に納得できない点があったので、他の方の文献も色々とありましたが、自分の結論をまとめました。
Vue.jsについてあまり詳しくないので、volumesについて詳しい事を書けなかったのが心残りです…笑 なにか良い方法を発見できたら、更新致します(｀･ω･´)ゞ
また間違っている点や感想などでもございましたら、お気軽にコメントください！！

DjangoやAWS,Dockerなどのバックエンドを勉強していたり、機械学習にも少し手を出している姿をTwitterで発信しているので、フォローして頂ければ喜びます！！[@heacet43](https://twitter.com/heacet43)

## 参考文献
[1] node - Docker Hub [https://hub.docker.com/_/node]
[2] Building Efficient Dockerfiles - Node.js - bitJudo [http://bitjudo.com/blog/2014/03/13/building-efficient-dockerfiles-node-dot-js/]
[3] Running Visual Studio Code on Linux [https://code.visualstudio.com/docs/setup/linux#_visual-studio-code-is-unable-to-watch-for-file-changes-in-this-large-workspace-error-enospc]