Dockerfileチラシの裏

docker初心者なので、自作Dockerfileを半年後の自分用にチラシの裏しておきます。なるべく、 __素のOSを元にする__ 事と、__外部fileを用いず極力Dockerfileに閉じて記載する__ をモットーにチラ裏します。

## 全体的なDockerfileハマりポイント
### Dockerfileは1行づつ個別の設定になる
`Docker build`でimage作成時、Dockerfileの __1行ごと__ にShellが起動してDocker imageに操作います。そのため、Current directoryや環境変数が行を跨いで引き継がれません。`ENV`で環境変数を指定するか、&&で連結して1行で記載すると回避できます。

```
動かない例
#RUN git clone https://github.com/hoge/fuga.git
#RUN cd fuga
#RUN npm init

回避策
#RUN git clone https://github.com/hoge/fuga.git && cd fuga && npm init

```

### CMD, ENTRYPOINTのPathについて
RUN, CMD, ENTRYPOINTが期待通りに動かない場合に、pathが正しく設定されていない場合が多いです(少なくとも自分は)。Dockerfile内のWORKDIRで、(期待する)Current directoryの設定をしてあげてください。



## Nodejs
git hubからnodejsのcoffee baseのappをcloneして、(nodejsの永続化toolである)PM2で起動させるDockerfile。

``` Dockerfile
FROM ubuntu:14.04
RUN apt-get update
RUN apt-get install -y nodejs npm git git-core curl
RUN npm install -g coffee-script
RUN npm install -g pm2

RUN git clone https://github.com/xxx/yyyy.git && cd ./yyyy && npm install
RUN update-alternatives --install /usr/bin/node node /usr/bin/nodejs 10

WORKDIR /yyyy/
CMD pm2 start --no-daemon /yyyy/bin/www.coffee

#in the case you want to see the debug log
#CMD pm2 start /yyyy/bin/www.coffee && pm2 logs

EXPOSE 80
```

ハマッたポイント

* `apt-get install nodejs`でいれた場合、[`RUN update-alternatives` しないとubuntu上では`node`コマンドが動かない](https://gist.github.com/thom-nic/724a2af410e90a654e35)
* `WORKDIR` を設定してあげないと、node appのpathが解決されずapp実行時にerrorで落ちる
* RUNは1行毎にしかCurrent directoryが保持されないので、`RUN git clone`の行は && で繋げて1行で記載する必要が有る


## mongo DB
mongo DBを立ち上げて、DBを初期化する (collectionを作ってあげたり、mongoimportでDB Dataを読み込む)

``` Dockerfile
FROM ubuntu:14.04
RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 7F0CEB10
RUN echo 'deb http://downloads-distro.mongodb.org/repo/ubuntu-upstart dist 10gen' > /etc/apt/sources.list.d/mongodb.list
RUN apt-get update
RUN apt-get install -y mongodb-org=2.6.5 curl

VOLUME ["/data/db"]
CMD ["mongod"]

# Expose ports. 27017 for normal db access, 28017 for http access
EXPOSE 27017
EXPOSE 28017
```

ハマッたポイント

* `VOLUME ["/data/db"]`してあげないと、mongodの起動が失敗する
* Dockerfile上でmongoimportする処理も記述できないか試行錯誤してみたが、上手く行かず。  
  結局、以下の回避策をとりました。
 * host linux側に、`mongodb-org-shell`と`mongodb-org-tools`をapt-get installでいれる
 * MongoのDockerを、`docker run -p 27017:27017 -d xxxxx`で立ち上げる
 * host linux上で、mongo importを実行する  
  `mongoimport --host localhost:27017 --db test_db--collection test_collection --file test.json`
 * host linux上で、mongo cliを操作する

```
#mongo localhost:27017
>use test_db
>db.test_collection.findOne()
```


## Kibana4 + Elasticsearch + fluentd

Kibana4とElasticsearchとfluentdをSetupするDockerfile。
KibanaはVer4から、Nodejs baseのappとなりPort 5601で待ち受ける仕様に変更になったので注意です。
あと、td-agent.confファイルは別途用意して下さい。

```
FROM ubuntu:14.04
RUN apt-get update -y

#Install Elasticsearch
ENV ELASTICSEARCH_VERSION elasticsearch-1.4.4
RUN apt-get install -y curl openjdk-7-jdk
RUN mkdir /opt/elasticsearch
RUN curl -sL "https://download.elasticsearch.org/elasticsearch/elasticsearch/${ELASTICSEARCH_VERSION}.tar.gz" | tar xz -C /opt/elasticsearch --strip=1
echo 'http.cors.enabled: true'  >> /opt/elasticsearch/elasticsearch.yml


#Install Kibana4
ENV KIBANA_VERSION 4.0.0-linux-x64
ENV KIBANA_ES_URL http://localhost:9200

RUN apt-get install -y curl
RUN mkdir /opt/kibana
RUN curl -sL "https://download.elasticsearch.org/kibana/kibana/kibana-${KIBANA_VERSION}.tar.gz" | tar xz -C /opt/kibana --strip=1
RUN sed -i "s;^elasticsearch_url:.*;elasticsearch_url: ${KIBANA_ES_URL};" "/opt/kibana/config/kibana.yml"
RUN chmod -R 777 /opt/kibana


#Install Fluentd and plugins
RUN apt-get install -y libcurl4-openssl-dev git-core build-essential ruby-dev
RUN curl -L http://toolbelt.treasuredata.com/sh/install-ubuntu-trusty-td-agent2.sh | sh
RUN /opt/td-agent/embedded/bin/fluent-gem install fluent-plugin-elasticsearch fluent-plugin-map
RUN ulimit -n 65536
COPY td-agent.conf /etc/td-agent/td-agent.conf


#Install Supervisor and config
RUN apt-get install -y supervisor
RUN touch /etc/supervisord.conf
RUN echo '[supervisord]'  >> /etc/supervisord.conf
RUN echo 'nodaemon=true'  >> /etc/supervisord.conf
RUN echo '[program:elasticsearch]'                  >> /etc/supervisord.conf
RUN echo 'command=/opt/elasticsearch/bin/elasticsearch' >> /etc/supervisord.conf
RUN echo 'stdout_logfile=/dev/fd/1'   >> /etc/supervisord.conf
RUN echo 'stdout_logfile_maxbytes=0'  >> /etc/supervisord.conf
RUN echo '[program:td-agent]'         >> /etc/supervisord.conf
RUN echo 'command=/usr/sbin/td-agent' >> /etc/supervisord.conf
RUN echo 'stdout_logfile=/dev/fd/1'   >> /etc/supervisord.conf
RUN echo 'stdout_logfile_maxbytes=0'  >> /etc/supervisord.conf
RUN echo '[program:kibana]'             >> /etc/supervisord.conf
RUN echo 'command=/opt/kibana/bin/kibana' >> /etc/supervisord.conf
RUN echo 'stdout_logfile=/dev/fd/1'   >> /etc/supervisord.conf
RUN echo 'stdout_logfile_maxbytes=0'  >> /etc/supervisord.conf


# expose port for elasticsearch
# enble 9300 if you need cluster
EXPOSE 9200

# expose port for fluentd
# enable 24224 if you need to expose to host

# expose port for kibana4
EXPOSE 5601


CMD /usr/bin/supervisord -c /etc/supervisord.conf
```

ハマッたポイント

* kibana4は、Nodeやexpressなどを全てinstallerに抱えている状態なので、Nodeなどを別途installは必要無く、`/kibana/bin/kibana`というshell scriptを実行するだけで良い
* Elasticsearch v1.4からCORSの設定を考慮する必要が有る。今回の場合Reverse proxyの後ろにKibana4, ESを配置するので、`echo 'http.cors.enabled: true'  >> /opt/elasticsearch/elasticsearch.yml`の記載を追加している


## Growthforecast + fluentd
GrowthforecastとfluentdをSetupするDockerfile。

```
FROM ubuntu:14.04
RUN apt-get update -y


#Install Growthforecast
RUN apt-get install -y curl perl
RUN apt-get -y build-dep rrdtool
RUN curl -L http://cpanmin.us | perl - --sudo App::cpanminus

RUN cpanm -n GrowthForecast
RUN mkdir /opt/growthforecast


#Install Fluentd and plugins
RUN apt-get install -y libcurl4-openssl-dev git-core build-essential ruby-dev
RUN curl -L http://toolbelt.treasuredata.com/sh/install-ubuntu-trusty-td-agent2.sh | sh
RUN /opt/td-agent/embedded/bin/fluent-gem install fluent-plugin-growthforecast fluent-plugin-dstat fluent-plugin-map --no-ri --no-rdoc -V
RUN ulimit -n 65536
COPY td-agent.conf /etc/td-agent/td-agent.conf


#Install Supervisor and config
RUN apt-get install -y supervisor
RUN touch /etc/supervisord.conf
RUN echo '[supervisord]'  >> /etc/supervisord.conf
RUN echo 'nodaemon=true'  >> /etc/supervisord.conf
RUN echo '[program:td-agent]'             >> /etc/supervisord.conf
RUN echo 'command=/usr/sbin/td-agent' >> /etc/supervisord.conf
RUN echo 'stdout_logfile=/dev/fd/1'  >> /etc/supervisord.conf
RUN echo 'stdout_logfile_maxbytes=0'  >> /etc/supervisord.conf
RUN echo '[program:growthforecast]'             >> /etc/supervisord.conf
RUN echo 'command=/usr/local/bin/growthforecast.pl --data-dir /opt/growthforecast --front-proxy=172.17.42.1' >> /etc/supervisord.conf
RUN echo 'stdout_logfile=/dev/fd/1'  >> /etc/supervisord.conf
RUN echo 'stdout_logfile_maxbytes=0'  >> /etc/supervisord.conf

# expose port for Growthforecast
EXPOSE 5125


CMD /usr/bin/supervisord -c /etc/supervisord.conf

```

ハマッたポイント

* GrowthforecastはPerl上で動いて居るが、Perl知識0なので、余計なlibrary等が入って居ないか不明
* Growthforecast containerをnginxの後ろで動かす場合には、[ここにあるtips](http://d.hatena.ne.jp/suu-g/20130629/1372528325)の対応が必要。
 * nginx側に設定が必要
 * growthforecast起動時に、nginxのIPを`--front-proxy`で渡す必要がある。`172.17.42.1`はContainerから見たHostのIP address。固定値で良いのか不安。
* Containerを起動したら、`curl -F number=10 http://localhost:5125/api/hoge/huga/value`を何回か実行して、Growthforecast上のUIに表示されるか確認すると良い。`number=10`の値は適宜変えて下さい。