Docker for macでVue.js環境を作る

Docker for macでVue.js環境を作ったので、ハマったところや手順をメモしておきます。

#Docker for macインストール
[DockerのGettingStarted](https://docs.docker.com/docker-for-mac/)を参考に進めば簡単にインストールできます。
versionの確認も載ってます。

#Dockerfileの作成
今回はOSはUbuntuでやろうと思ったので、
以下の感じでDockerfile作成しました。

```Docker
FROM ubuntu:latest
RUN mkdir /practice1
COPY ./practice1 /practice1
WORKDIR /practice1
```

#dockerイメージの作成
今の状態だとVue.jsの環境は一切含んでいないのですが、後ほど作成したコンテナ上でVue.js環境を構築したあとで`docker commit`でイメージを再作成する予定です。

```
docker build -t yorinton/vue:v1.0
```

#dockerコンテナの作成

```
docker run -i -t -p 80:80 -v /Users/katsuki_y/Develop/vue/practice1:/practice1 [イメージID]
```

#vue.js環境の構築

```console
//apt-getパッケージリストの更新(これをやらないとエラーになる時がある)
#apt-get update

//sudoのインストール
#apt-get -y install sudo

//curlのインストール(node.jsのインストールに必要)
#sudo apt-get -y install curl

//node.jsのインストール(公式サイト参照)
#curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -
#sudo apt-get install -y nodejs

//vue-cliのインストール(vue.js公式参照)
#npm install --global vue-cli

//webpackを使って新規プロジェクト作成
#vue init webpack [プロジェクト名]
//以下のようにインタラクティブに質問に答えることで環境が構築されていく
? Project name vue-pj
? Project description A Vue.js project
? Author yorinton
? Vue build standalone
? Install vue-router? Yes
? Use ESLint to lint your code? Yes
? Pick an ESLint preset Standard
? Set up unit tests Yes
? Pick a test runner jest
? Setup e2e tests with Nightwatch? Yes
? Should we run `npm install` for you after the project has been created? (recommended) nom

//プロジェクトフォルダに移動
#cd [プロジェクト名]

#npm install

//webpack-dev-server起動
//これでブラウザで表示できるようになる
#npm run dev
```

#コンテナからイメージの作成
コンテナに変更を加えVue.jsの環境が出来たのでそこからイメージを作成します。

```
docker commit [コンテナID]
```
これで構築済みのVue.js環境を`docker run`コマンドですぐに立ち上げられるようになりました。

#ハマったポイント

##コンテナで立ち上げたサーバーにホスト側からアクセス出来ない

■問題点
コンテナで`npm run dev`コマンドを実行した時に、vue.jsプロジェクトに入っているwebpackでデフォルトで設定されている`http://localhost:8080`にアクセスできるようになります。

しかし、今回`docker run`コマンドは以下のようなオプションを設定しました。

```
docker run -i -t -p 80:80 -v /Users/katsuki_y/Develop/vue/practice1:/practice1 [イメージID]
```

`-p 80:80`でゲスト側(コンテナ)の80番ポートをホスト側(Mac)の80番にバインドする設定にしています。

そのため、ホスト側(Mac)から`http://localhost:8080`にアクセス出来なかったようです。

■調査
まずDockerコンテナの80番がホスト側のどのhost、portにバインドされているかを調べました。

```
docker ps
```
`POSTS`の部分を見ると、

```
PORTS
0.0.0.0:80->80/tcp
```
ホスト側の`0.0.0.0:80`にゲスト側の80番ポートをバインドしていることがわかります。

なので、`http://localhost:8080`にホスト側からアクセス出来ないようになっているようです。



次に`npm run dev`を実行した時に、

```
webpack-dev-server --inline --progress --config build/webpack.dev.conf.js
```
という文章が表示されており、`webpack-dev-server`が起動されていることがわかります。また、その設定は、`build/webpack.dev.conf.js`に記載されているようです。

■対策

仮説として、この設定で80番ポートを設定すればいいのではと考えました。

`build/webpack.dev.conf.js`を見ると、設定情報は`/config`ディレクトリから読み込んでいるようでした。
`/config`ディレクトリにはいくつかファイルがありましたが、`index.js`にhost、portを設定する項目がありました。

<変更前>

```javascript
//index.js
host: 'localhost', // can be overwritten by process.env.HOST
port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
```


<変更後>

```javascript
//index.js
host: '0.0.0.0', // can be overwritten by process.env.HOST
port: 80, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
```

上記のように変更したところ無事ホスト側(Mac)からアクセスすることが出来ました。
※hostを`localhost`のままにしたところアクセス出来なかったので上記のようにhostも変えました。

多分`docker run`コマンドの`-p`のところをうまく変えれば解決出来たと思うのですが、`-p 80:8080`等いくつか試してみたのですがうまく行かなかったので今回は`webpack-dev-server`の方の設定を変えることで対処しました。

次はVue.js環境の構築まで含めたDockerfileを作成しようと思いますが、`vue init webpack [プロジェクト名]`実行後にインタラクティブに入力したり、選択していく部分をどうRUNコマンドで表現するかで悩んでいます。
もしやり方ご存知の方いらっしゃればコメント頂けると嬉しいです！
(出来たら別途Qiitaに書きます)

以上。