DockerでDevhubを利用してみる。

#経緯
@volpe28v さんが作成しているDevHub という開発ツールがとても便利なので、Dockerで動かしてみました。
Dockerhubに登録されたDevHubのイメージは古いものが多かったので、簡単にDockerFileを作成しました。

キーワード
docker DevHub mongodb

#Dockerfile（その１）
ビルドしやすいようにMulti Stage機能を使ってビルドの成果物とmongodbのみのイメージを作成。
mongodbの起動を待つために「wait-start.sh」を挟んでDevHubを起動する。

```
FROM node:9.5.0-alpine AS base
RUN apk add --no-cache git && \
git clone https://github.com/volpe28v/DevHub && \
cd DevHub && \
git checkout d4c24c0fdf72386a2003e8eb0f337f7b50294cca && \
npm install && \
npm run build

FROM base AS release
RUN apk add --no-cache mongodb supervisor && \
rm /usr/bin/mongoperf && \
mkdir /etc/supervisord.d

VOLUME /data/db

COPY --from=base /DevHub /DevHub
WORKDIR /DevHub
RUN mkdir -p /var/log/DevHub/

EXPOSE 3000

RUN ( \
  echo "#!/bin/sh" && \
  echo "set -e" && \
  echo "until nc localhost 27017 -z ; do" && \
  echo "  echo 'Waiting for mongo'" && \
  echo "  sleep 1" && \
  echo "done" && \
  echo "echo 'mongo is up'" && \
  echo "exec node app.js" \
) > /DevHub/wait-start.sh
RUN chmod +x /DevHub/wait-start.sh

RUN ( \
  echo "[supervisorctl]" && \
  echo "[supervisord]" && \
  echo "autostart=true" && \
  echo "redirect_stderr=true" && \
  echo "nodaemon=true" && \
  echo "[program:mongodb]" && \
  echo "command=/usr/bin/mongod" && \
  echo "priority=1" && \
  echo "autostart=true" && \
  echo "redirect_stderr=true" && \
  echo "[program:devhub]" && \
  echo "command=/DevHub/wait-start.sh" && \
  echo "directory=/DevHub" && \
  echo "priority=2" && \
  echo "autostart=true" && \
  echo "redirect_stderr=true" && \
  echo "stderr_logfile = /var/log/DevHub/err.log" && \
  echo "stdout_logfile = /var/log/DevHub/out.log" \
) > /etc/supervisord.conf

ENTRYPOINT ["supervisord", "--nodaemon", "--configuration", "/etc/supervisord.conf"]

```
#Multi Stage機能
FROMを複数用意して、baseの成果物をreleaseに配備しようと思ったが、あまり容量を削れなかったので「/DevHub」をそのまま持ってきた・・・
~~もう少しきれいに整理出来たらgithubに上げたい。~~
削れなかった経緯をメモ（2017/2/15)
### 容量が大きいnode_modules のライブラリ（単位kb)
```
2524    ./bootstrap
2984    ./moment
3432    ./es5-ext
4124    ./grunt-legacy-log-utils
4204    ./grunt-legacy-util
5048    ./globule
5804    ./jquery-ui
5836    ./watchpack
8968    ./webpack
22824   ./emojify.js
```
### DockerFileの容量削減バージョン
webpack,watchpackとnpmをアンインストールしてみる。

```
FROM node:9.5.0-alpine AS base
RUN apk add --no-cache git && \
git clone https://github.com/volpe28v/DevHub && \
cd DevHub && \
git checkout d4c24c0fdf72386a2003e8eb0f337f7b50294cca && \
npm install && \
npm run build

FROM base AS release
RUN apk add --no-cache tzdata
COPY --from=base /DevHub /DevHub
RUN cd /DevHub
WORKDIR /DevHub
RUN npm uninstall webpack watchpack 
RUN npm uninstall npm -g
EXPOSE 3000

ENTRYPOINT ["node","app.js"]

```
|パターン| RUN コマンド| SIZE (非圧縮)| 
|:---|:---|:---|
|アンインストール前 |何もしない|257MB|
|webpackとwatchpack をuninstall|RUN npm uninstall webpack watchpack |257MB|
|webpackとwatchpackとnpm をuninstall|RUN npm uninstall webpack watchpack && \ npm uninstall npm -g|266MB |

なんでかアンインストールしたほうが容量が増えたので、あきらめていったんDockerhubにあげました。

# MongodbなしDockerfile（その２）
[Github](https://github.com/ranran999/DevhubAlpine/tree/noMongodb)

```
FROM node:9.5.0-alpine AS base
RUN apk add --no-cache git && \
git clone https://github.com/volpe28v/DevHub && \
cd DevHub && \
git checkout d4c24c0fdf72386a2003e8eb0f337f7b50294cca && \
npm install && \
npm run build

FROM base AS release
RUN apk add --no-cache tzdata

COPY --from=base /DevHub /DevHub
WORKDIR /DevHub
EXPOSE 3000

ENTRYPOINT ["npm","start","--"]
```
シンプルにAlpineのNodeイメージにDevHubをインストール
MongoDBは公式のDockerイメージがあるのでそちらを利用する想定。
ENTRYPOINTでDevHubの起動オプションが渡せなかったのに悩んだが[こちら](https://qiita.com/tiny-studio/items/ce28bf84c76aba53122f)の記事を参考に「--」をつけることでうまいことオプションを渡せた。

## RUNコマンド

```
docker run -d --name mongo  mongo:3.2.19-jessie
docker run -d -p 3000:3000 --link mongo:mongo -e  "MONGODB_URI=mongodb://mongo/some_dbname" -e "TZ=Asia/Tokyo" ranran9/devhub-alpine:noMongodb -t SOME_TITLE
```
mongoという名前でMongodbを立ち上げて、DevHubのイメージにリンクさせる。
DevHubはHerokuのMongodbに対応しているので、環境変数：MONGODB_URIを渡せば先ほど起動したMongodbに任意のDB名をつけて実行できる。

### メリット：
ちょっと軽い（215 MB）
１つのMongodbインスタンスにDB名を変えて複数のDevhubを実行することができる。

### デメリット：
DockerCompose等を使わないと、「--restart=always」のような自動実行構成ができなさそう。
シンプルにするためMongodbの起動チェックを外したのは早まったかもしれない・・・

# Mongodb同梱Dockerfile（その３）
[Github](https://github.com/ranran999/DevhubAlpine/)

```
FROM node:9.5.0-alpine AS base
RUN apk add --no-cache git && \
git clone https://github.com/volpe28v/DevHub && \
cd DevHub && \
git checkout d4c24c0fdf72386a2003e8eb0f337f7b50294cca && \
npm install && \
npm run build

FROM base AS release
RUN apk add --no-cache mongodb supervisor tzdata  && \
rm /usr/bin/mongoperf && \
mkdir /etc/supervisord.d

VOLUME /data/db

COPY --from=base /DevHub /DevHub
WORKDIR /DevHub
RUN mkdir -p /var/log/DevHub/

EXPOSE 3000
COPY wait-start.sh .
RUN chmod +x /DevHub/wait-start.sh
COPY supervisord.conf /etc/

ENTRYPOINT ["supervisord", "--nodaemon", "--configuration", "/etc/supervisord.conf"]
```
（その１）のDockerfileからshellをファイルにして、MongodbをイメージにとりこんだDockerfile


## RUNコマンド

```
docker run -d -p 3000:3000  -e "DEVHUB_TITLE=TITLE" -e "TZ=Asia/Tokyo" ranran9/devhub-alpine
```

### メリット：
Dockerインスタンス１つでDevHubをすぐ利用できる。

### デメリット：
ちょっと重い（273MB）

#更新履歴
2017/2/15 Dockerイメージ容量削減の謎メモを追記
2017/2/15 公式のGithubが更新されたので（d4c24c0fdf72386a2003e8eb0f337f7b50294cca ）Dockerhub側も最新化