docker + jsdoc と docker起動ファイルのシェルスクリプトまとめ

[前回][link-1]の続き。

#jsdocの導入

Dockerfileは以下。

```shell:Docker/Dockerfile

FROM node:6.2.2

RUN mkdir -p /usr/src/share
WORKDIR /usr/src

#package.jsonを書き出し
RUN echo '{ "name": "node_jsdoc",  "scripts": { "start": "node webapp/bin/www", "jsdoc":"jsdoc", "gulp":"gulp" }}' > package.json

#タスクランナーインストール
RUN npm install --save-dev gulp 
RUN npm install --save-dev require-dir 
RUN npm install --save-dev gulp-if 
RUN npm install --save-dev gulp-livereload

#JSDOCインストール
RUN npm install --save-dev jsdoc

#gulpfileを書き出し
RUN echo "var requireDir = require('require-dir'); requireDir('share/gulp/jsdoc', { recurse: true }); " > gulpfile.js 

CMD [ "npm","run","gulp"]

```

gulpでソースフォルダを監視。
更新があったらjsdocを更新する。

```js:dev/gulp/jsdoc/task.js
var gulp = require('gulp');
var spawn = require('child_process').spawn;

gulp.task('default', ['jsdoc', 'watch']);

gulp.task('jsdoc',function(){
  spawn('npm',['run-script', 'jsdoc', '--', '-c', './share/jsdoc/conf.json'], {stdio: ['pipe', process.stdout, process.stderr]});
});

gulp.task('watch',['jsdoc'],function(){
  gulp.watch('./share/myExpressGenerator/public/myApp/scripts/source/*', ['jsdoc']);
});
```

jsdoc設定

```json:dev/jsdoc/conf.json
{
    "tags": {
        "allowUnknownTags": true,
        "dictionaries": ["jsdoc","closure"]
    },
    "source": {
        "include": ["./share/myExpressGenerator/public/myApp/scripts/source"],
        "includePattern": ".+\\.js(doc)?$",
        "excludePattern": "(^|\\/|\\\\)_"
    },
    "plugins": [],
    "templates": {
        "cleverLinks": false,
        "monospaceLinks": false
    },
    "opts": {
      "encoding": "utf8",
      "destination": "./share/myExpressGenerator/public/myApp/jsdoc/",
      "recurse": true
    }
}

```

#docker起動shell

同様の処理を関数にまとめた。
オプションでビルドや実行の切り替えを行えるようにした。

```
-b ビルド
-r 実行
-d バックグラウンドで実行
-i dockerにbashでログイン
```

デフォルトでは実行。

```shell/env.sh
#!/bin/bash

# 共有ディレクトリ
path_share_dir="/vagrant/share"

# docker用ディレクトリ
path_Dockerfile_dir="${path_share_dir}/Docker"

# 開発用ディレクトリ
path_dev_dir="${path_share_dir}/dev"

# dockerイメージファイル名(:タグ名)
containerName_express="express" # karmaとexpressで使用

#共通関数

# dockerファイルからビルド
build(){
  local dir=$1
  local imageName=$2

  # 移動してビルド
  cd $dir && docker build -t $imageName .
}

# 前回のコンテナをチェック。残っていれば削除
checkBeforeContainer(){
  local containerName=$1

  # 前回のコンテナが残っているかチェック。
  docker ps -a | grep $containerName >/dev/null 2>&1

  # コンテナが残っている場合は削除。
  if [ $? -eq 0 ]; then
    docker rm -f $containerName
  fi
}

# 引数が指定されていない時はrunを行う
default(){
  if [ $1 -eq 0 ] ; then
    run
    exit
  fi
}

# 指定されたオプションで処理を切り替える。
main(){
  local opt=$1
  local buildDir=$2
  local imageName=$3
  local containerName=$4

  case ${opt} in
    b)
      build ${buildDir} ${imageName}
      ;;
    r)
      run
      ;;
    d)
      run_d
      ;;
    i)
      run_d
      docker exec -it ${containerName} /bin/bash
      ;;
    \?)
      exit 1
      ;;
  esac
}
```

```shell/express.sh
#!/bin/bash 

source "/vagrant/share/shell/env.conf"

imageName="hibo/express"
containerName=$containerName_express
src_dir="${path_dev_dir}/myExpressGenerator"
container_src_dir="/usr/src/app/webapp"
docker_dir="${path_Dockerfile_dir}/express"

run(){
  docker run --name $containerName --rm -it -p 80:3000 -p 35729:35729 -v $src_dir:$container_src_dir $imageName
}

run_d(){
  docker run --name $containerName -d -p 80:3000 -p 35729:35729 -v $src_dir:$container_src_dir $imageName
}


checkBeforeContainer $containerName
default $#

while getopts brdi opt
do
  main ${opt} $docker_dir $imageName $containerName
done
```

```shell/jsdoc.sh
#!/bin/bash 

source "/vagrant/share/shell/env.conf"

imageName="hibo/jsdoc"
containerName="jsdoc"
docker_dir="${path_Dockerfile_dir}/jsdoc"

run(){
  docker run --name $containerName --rm -it -v $path_dev_dir:/usr/src/share $imageName
}

run_d(){
  docker run --name $containerName -d -v $path_dev_dir:/usr/src/share $imageName
}


checkBeforeContainer $containerName
default $#

while getopts brdi opt
do
  main ${opt} $docker_dir $imageName $containerName
done
```

```shell/karma.sh
#!/bin/bash

# 設定ファイルの読込
source "/vagrant/share/shell/env.conf"

imageName="hibo/karma"
containerName="karma"
docker_dir="${path_Dockerfile_dir}/karma"

run(){
  # コンテナの起動
  docker run -it --name $containerName --rm \
             -v $path_dev_dir:/usr/karma/share \
             --link $containerName_express:c1 \
             $imageName /bin/bash -c \
             'npm run-script tests -- ./share/karma/karma.conf.js'
}

checkBeforeContainer $containerName
default $#

while getopts brdi opt
do
  main ${opt} $docker_dir $imageName $containerName
done
```

```shell/mongodb.sh
#!/bin/bash 

source "/vagrant/share/shell/env.conf"

imageName="hibo/mongodb"
containerName="mongodb"
save_dir=/home/vagrant/DataBase/mongodb
docker_dir=$path_Dockerfile_dir/mongodb

run(){
  docker run --name $containerName --rm -it -p 27017:27017 -v $save_dir:/data/db $imageName
}

run_d(){
  docker run --name $containerName -d -p 27017:27017 -v $save_dir:/data/db $imageName
}

checkBeforeContainer $containerName
default $#

while getopts brdi opt
do
  main ${opt} $docker_dir $imageName $containerName
done

#$path_dev_dir/DB/mongodb:/data/db $imageName_mongodb
#/home/vagrant/DataBase/mongodb:/data/db $imageName_mongodb
# /bin/bash
#docker run -it --link mongodb:mongo --rm mongo sh -c 'exec mongo "$MONGO_PORT_27017_TCP_ADDR:$MONGO_PORT_27017_TCP_PORT/test"'
```

```shell/webpack.sh
#!/bin/bash 

source "/vagrant/share/shell/env.conf"

imageName="hibo/gulp_webpack"
containerName="gulp_webpack"
docker_dir="${path_Dockerfile_dir}/webpack"

run(){
  docker run --name $containerName --rm -it -v $path_share_dir:/usr/local/src/share $imageName  /bin/bash -c \
           'npm run-script gulp'
}

run_d(){
  docker run --name $containerName -d -v $path_share_dir:/usr/local/src/share $imageName  /bin/bash -c \
           'npm run-script gulp'
}

checkBeforeContainer $containerName
default $#

while getopts brdi opt
do
  main ${opt} $docker_dir $imageName $containerName
done
```

#docker更新
今回、久しぶりに使用するのでDockerを更新。

```:Vagrantfile
$docker_install = <<SHELL
    # 16.04のバグでaptがlockされている。
    sudo killall -KILL apt.systemd.daily

    sudo apt-get update
    sudo apt-get install apt-transport-https ca-certificates
    sudo apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D
    echo 127.0.1.1 $(hostname) >> /etc/hosts
    echo "deb https://apt.dockerproject.org/repo ubuntu-xenial main" > /etc/apt/sources.list.d/docker.list
    sudo apt-get update
    sudo apt-get purge lxc-docker
    apt-cache policy docker-engine

    sudo apt-get update
    sudo apt-get install -y linux-image-extra-$(uname -r)

    sudo apt-get update
    sudo apt-get -y install docker-engine
    sudo gpasswd -a vagrant docker
SHELL

Vagrant.configure(2) do |config|
  config.vm.box = "bento/ubuntu-16.04"
  
  # ネットワーク設定。
  config.vm.network "private_network", ip: "192.168.50.11"
  
  # 共有するフォルダの設定
  #config.vm.synced_folder '.', '/vagrant', disabled: true

  # 使用するメモリ容量を変更。
  # デフォルトだと512で少ないためdockerのbuildが失敗しやすい
  config.vm.provider "virtualbox" do |vm|
    # メモリを1024MBに設定
    vm.memory = 1024
    # Vagrant1.8から利用出来るLinked Cloneをオンにする。
    vm.linked_clone = true
  end

  # dockerをインストール
  # Dockerフォルダの所有ユーザを変更
  config.vm.provision "shell", inline: $docker_install
  config.vm.provision "shell", inline: <<-SHELL
    sudo apt-get update
    sudo apt-get install -y tmux
  SHELL
end
```

expressを最新のnode.jsにいれようとした時にbody-parserでエラー。
最新のbody-parserは1.15.4だが、1.14.4を指定してエラー回避

```:Docker/express/Dockerfile
FROM node:6.2.2

RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

#gulpfileを書き出し
RUN echo "var requireDir = require('require-dir'); requireDir('webapp/gulp/tasks', { recurse: true }); " > gulpfile.js 

#package.jsonを書き出し
RUN echo '{ "name": "node_express",  "scripts": { "start": "node webapp/bin/www", "gulp":"gulp" }}' > package.json

#タスクランナーインストール
RUN npm install --save-dev gulp 
RUN npm install --save-dev require-dir 
RUN npm install --save-dev gulp-if 
RUN npm install --save-dev gulp-livereload

#サーバーインストール
RUN npm install --save-dev express 
RUN npm install --save-dev cookie-parser 
RUN npm install --save-dev debug 
RUN npm install --save-dev jade 
RUN npm install --save-dev morgan 
RUN npm install --save-dev serve-favicon 

# ウェブソケットインストール
RUN npm install --save-dev socket.io

# DBドライバインストール
RUN npm install --save-dev mongodb

# 認証ミドルウェアインストール
RUN npm install --save-dev passport
RUN npm install --save-dev passport-local
RUN npm install --save-dev passport-twitter

#セッション管理ミドルウェアインストール
RUN npm install --save-dev express-session

# body-parser@1.15.2で行うと
# EXDEV -no 18. cross-device link not permitted がでる。
# renameでのエラー。
RUN npm install --save-dev body-parser@1.14.2

CMD [ "npm","run","gulp", "--","watch" ]
```


#参考にしたページ
[Markdownの書き方][link-2]
[use jsdoc][link-3]
[apt-getが失敗][link-4]

[link-1]:http://qiita.com/hibohiboo/items/fb977fe8ce08ab390bd7
[link-2]:http://promamo.com/?p=3558
[link-3]:http://usejsdoc.org/index.html
[link-4]:http://hiroom2.jimdo.com/2016/05/20/ubuntu-16-04%E3%81%AEapt-update%E3%81%A7appstreamcli%E3%81%8C%E5%9B%BA%E3%81%BE%E3%82%8B/