注目キーワード
  1. react
  2. docker
  3. インターン

NEM NISのDocker Imageを作る

LCNEMでの遊び心をもっていろいろ触ってみようというテーマの元、テスト勉強の合間にNEM NISのDocker Imageを作成してみました。

Docker Hubにて公開しています!ぜひ動かして遊んでみてください!

下準備

Docker内でのはdebianにしました。特に深い意味はないですが、dockerのベースのOSとしてよく使われているイメージなのでこのようにしてみました。
また、NISはjavaで動くサーバーなのでjavaのインストールも必要です。最初はjavaの公式docker imageを用いてたのですが、なんかうまくいかなかったのでdebianのイメージを元にして手動でjavaをインストールすることにしました。

Dockerfile

FROM debian↲
RUN apt-get update && apt-get install openjdk-8-jdk -y && apt-get install curl -y↲

RUNはbuild時に実行されるコマンドです。
javaを触ったことがないのでどのjavaを使えばいいのかがよくわからず、これであっているのか不安だったのですがとりあえず動いたのでこれでおkってことにしいます。

公式のdebianにcurlコマンドが入っておらずあとでtarを落としてくときに必要なのでここでインストールしています。

これで、javaが動くcontainerが用意できました。

NISをダウンロードしてきて展開する

https://nem.ninja/ に最新のNISやDBが設置されています。ここから必要な物をダウンロードしてきます。
nis-0.6.96.tgzを今回は使いました。nis-[version].tgzとなっているようです。これをダウンロードしてきて展開します。

Dockerfile

...
RUN curl -o nis-0.6.96.tgz https://nem.ninja/nis-0.6.96.tgz \↲
    && tar zxvf nis-0.6.96.tgz↲

/の直下に配置してしまっているのでも少し設計を考え直す必要はありそうです。/root/nisにWORKDIRに設定しました。(後述)

これで起動の準備は整いました。

コンテナ起動時にNISを起動する

今回はコンテナの起動時にNISを起動するように設定しました。
Dockerfile

...
CMD cd package \
    && ./nix.runNis.sh

CMDはdocker runのときに実行されるコマンドです。

コンテナを作成する

さて、ここまで記述したら実際に動かしてみたいと思います。
まずは、buildしてnem-nisというimageを作成します。

$ docker build ./ -t nem-nis

docker build ./でカレントディレクトリにあるDockerfileからdocker imageを作成します。そのままだとimageの名前が勝手につけられて管理がめんどくさいので、-tnem-nisという名前をつけました。より丁寧にするには、nem-nis:latestなどのようにversionのタグをつける方がdockerらしいです。

そして、このImageを元にコンテナを作成します。

$ docker run --rm -d -p 7890:7890 --name nis-container nem-nis

docker run nem-nisだけでも動くのですが、他のオプションをつけないとコンテナの中に入ってしまってなぜか抜けられなくなるのと、コンテナ外からNISにアクセスできなくなります。
順番に、オプションの説明をすると、
- --rm: コンテナが終了したときにコンテナを自動で削除→コンテナの乱立を防ぐ
- -d: daemon実行
- -p [解放したいport]:[そこにアクセスがあったときに接続するコンテナ内のport]: 外部とコンテナ内の接続
- --name: 名前をつけて管理しやすくする。(同じ名前のコンテナを作成しようとするとエラーが出るので注意が必要)
という感じです。

これで、:7890だけを解放したコンテナが立ち上がるはずです。ただしデータベースの同期が行われるので少し時間がかかるようです。そして、ここのログを取れていないので内部のデバッグがしにくい状況です、、

動作確認

$ curl localhost:7890/status
{"code":5,"type":4,"message":"status"}

こんな感じで返ってきたらおkです!
apiの詳細は公式のドキュメントを読みましょう。

$ docker exec -it nis-container /bin/bash

でコンテナの中に入ってみるのも楽しいです。

[追記] WORKDIRの設定

Dockerfileを以下のように書き換えて、WORKDIRを/root/nis/packageにしました。

FROM debian

RUN apt-get update && apt-get install openjdk-8-jdk -y && apt-get install curl -y
WORKDIR /root/nis
RUN curl -o nis-0.6.96.tgz https://nem.ninja/nis-0.6.96.tgz \
    && tar zxvf nis-0.6.96.tgz
WORKDIR package

CMD ./nix.runNis.sh

WORKDIRを設定しておくことで、docker execしたときにそのディレクトリから入ることができます。

詰まったところ

javaがなかなか入らない

apt-get install oracle-java8-jdkとかやとうまくはいりませんでした。参考にした記事がUbuntuベースだったのでその辺りが関係しているのかも?
公式のjava imageも動かないし、、
なんせjavaを触るのが初めてでnemにたどり着くまでが結構しんどかった、、

tarが展開できない

tarを展開しようとすると、

gzip: stdin: not in gzip format
tar: Child returned status 1
tar: Error is not recoverable: exiting now

みたいなエラーがでて全然展開できませんでした。調べてみてもtarの展開のコマンド(tar zxvf hoge.tgz)はあってそうでさらに調べると、tarが壊れている可能性があるって書いててそんなことがあるのかと思ったらこれが原因でした。
というか、参考にしたサイトの情報が古かったのかホストやファイル名が変わっていました。

http://www.nem.ninja/nis-ncc-0.6.84.tgz

https://nem.ninja/nis-0.6.96.tgz

まさかのtarとなにも関係ないところの問題で無駄に時間がかかってしまいました。

portの設定ができない

docker runまでは動いていたのであとはportの解放の設定するだけ、と思っていたのにportを指定した瞬間コンテナが起動すらしなくなりました。
portを解放することでどこか不具合が生じたのかなと思ったのですが、単に指定の仕方が悪かっただけのようです。

最初は、

$ docker run nem-nis --rm -d -p 7890:7890 --name nis-container nem-nis

のように、オプションを後ろにつけていました。しかし、docker runは二つの引数を取ることができ、オプションのはずが二つ目の引数として認識され結果エラーとなっていました。

この二つ目の引数は、実行時のコマンドを指定するものでDockerfileのCMDを上書きしてしまうようです。
そのため、bin/sh$ --rm -d -p 7890:7890...という訳のわからないコマンドが実行されたことになりバグってしまったのです。

$ docker run --rm -d -p 7890:7890 --name nis-container nem-nis

のように書くことで解決できます。

課題

ディレクトリ構成

このままではroot直下に諸々配置されてしまうことになるので、どこに配置するかを考えないといけません。
/home/nemというディレクトリが自動で生成されるのでこいつとの関連も考えた配置にした方が良さそうかなと。

ログ

今のところshellをコンテナの起動と同時にフォアグラウンドで実行して、そのコンテナをdaemonで実行しているので実質的にログをみる手段がありません。
標準出力先を変更したいのですが、javaバイトコードでのやり方がわからずどうしよってなってます。誰か教えてください、、

起動設定

今回はお試しに起動時にNISの起動までやっていますが、公開用のimageとなるとこれを元にコンテナをカスタマイズしたいという用途もあると思うので、起動はしないようにすべきです。
そうなってくると、起動用のMakefileでも仕込んどくのがいいのかそれとも環境変数とか初期のディレクトリをよしなにしとくのがいいのか、と考えるべきことがたくさんあります。
なんせdocker imageの公開も初めてなのでわからないことだらけです。有識者の方ご教授お願いいたします。。

終わりに

Docker Hubにて公開しています!ぜひ動かして遊んでみてください!

Dockerfileとかは僕のリポジトリにあります。
Dragon-taro/nis-docker

参考サイト
https://blog.44uk.net/2017/03/20/nem-setup-on-raspberrypi-to-harvest/