Dockerで処理をまとめておく

やりたいこと

処理をまとめて簡単に動かせるようにしておきたい。

環境設定とか毎回するの面倒なので、コマンド一発で動かせるくらいにしておきたい。

解決策

Docker使う。

ソースコードを動かせる状態にしておいて、Dockerの仮想環境の中で稼働させる。

そもそもDockerとは

仮想環境を作成する作成できるプラットフォーム。以上。

今回の設定

なので、処理システムをDockerの環境にぶっこんで、DockerコンテナがJsonを標準入力で受け取って、Jsonを標準出力で返すようにすればいい。

具体的な処理内容

具体的には、形態素解析+複合語抽出を行う

形態素解析にはMecab、複合語抽出にはTermExtractを利用する。

TermExtractはすでに作者さんがありがたくもDocker環境化してくれているので、楽。

今回は、このDockerファイルをそのまま継承することにする。

要件など

TermExtractはcontainer内部に学習済みのDBファイルを持つので、定期的にDBファイルをContainerから取り出して、管理できるようにしておく。

作業ログ

pythonでシステム組んで、Dockerfileに記述

TermExtractgit cloneしてくる。

すでに、Mecabのインストール環境は整っているので、特に設定は不要。

Pythonスクリプトで、TermExtractorのラッパー的なものを書く。

処理の流れはこんな感じ

  1. 標準入力でJsonを受け取る。system.pyという名前にしておく。
  2. TermExtractorを呼び出して、複合語抽出
  3. 複合語抽出の結果使って、Mecabで単語分割
  4. Jsonで結果を返却

システム作ったら、Dockerfileにpythonスクリプト群をコピーするレシピを記述する。

Dockerfileコマンドについては参考記事

2 Dockerfileをビルド

TermExtractのDockerは/var/lib/termextract を共有ディレクトリに使うので、ローカルマシンでディレクトリを作っておく。

buildコマンドでdocker imageをビルドする。

docker build -t naoa/termextract .

ビルドできたら、ログインを確認する。

docker run -v /var/lib/termextract:/var/lib/termextract -i -t naoa/termextract /bin/bash

CentOsのcontainerにログインできるはず。

-v /var/lib/termextract:/var/lib/termextractはローカルマシンとContainerの共有ディレクトリを設定している。

-iは標準入力を開きっぱなしにするコマンド

Jsonで入力を与えて、出力を受け取るテストをする。

cat ./dockerfiles/resources/received.json |\
docker run -v /var/lib/termextract:/var/lib/termextract \
-a stdin -a stdout -a stderr -i naoa/termextract python2.7 system.py

system.pyJsonを標準入力でうけとって、いろいろやってから、Jsonを標準出力で返すスクリプト。いまはcontainerの/直下に置いてある。

3 DBのデータを引き継いで利用できるようにする。

前述のようにTermExtractはcontainer内部にDBデータを残すので、新しいcontainerを作りまくっても意味がない。同じcontainerを呼び出して、処理をさせないと、真価が発揮できない。

まず、containerを起動させる。

docker run -v /var/lib/termextract:/var/lib/termextract -i -t naoa/termextract /bin/bash

ログインを確認したら、exitでログアウトする。

この状態だと、containerがExitになっているので、containerを再起動する。

その前に、いまさっき、閉じたばかりのcontainer IDを確認する。

% docker ps -a                              
CONTAINER ID        IMAGE                     COMMAND                CREATED             STATUS                      PORTS               NAMES
36880ed4a975        naoa/termextract:latest   "/bin/bash"            4 minutes ago       Exited (0) 3 minutes ago                        pensive_hawking     

container IDがわかったので、再起動を行う。

docker start 36880ed4a975

これで、containerが再起動した。

最後に、再起動させたcontainerを使って処理をさせる。

cat dockerfiles/resources/received.json |\
docker exec -i 1cb049204e0d python2.7 system.py

docker execは起動中のイメージを呼び出すコマンド。

-iをつけておくと、標準入力がONになる。

最後に、実行したいbashコマンドを書いて実行する。

Jsonが標準出力で返ってくるはず。

これで、データを引き継ぎしながら処理を行えるコンテナが使えるようになった。

最後に

環境設定がめんどうなソフトウェア群はdockerでまとめてしまっていいと思う。

特に実行時間を気にしないbatch処理なら、速度よりも楽さをとるべきでないっすかねー。