砂漠のデータ分析

機械学習 / 画像処理 / 自然言語処理

はじめてのdocker | データ分析環境を用意してみた

背景

pythonでデータ分析環境を準備する時、色んなツールを使ってパッケージをインストールする場合があると思う。

  • brewyumでインストールするライブラリ
  • pipcondaでインストールするライブラリ
  • ソースコードからbuildするライブラリ

上記のように様々な手段でライブラリがインストールされた環境を別のマシンで再現するのが面倒くさいのでなんとかしたい。

全てがcondaのパッケージ管理で完結するならcondaのenvironment.yml(Managing environments — Conda documentation)を使えばいいけど、condaだけで完結しないケースが増えてきたので困った。

やってみた事

  • dockerにデータ分析環境を作ってみる。
  • 試しにこんな環境を作ってみる。
    • pyenv + minicondaのインストール
    • boostのインストール + dlibのインストール

dlibは、C++製の画像による物体認識ツール。
anacondaでインストール出来る( Dlib :: Anaconda Cloud )が、これは最新のversionでは無い(2017年12月24日時点)ので、sourceを落として来てビルドする。その環境をdocker image化して再現可能な環境にしてみる。

注釈

  • これを書いている者はdockerについてほぼ何の予備知識も持たない。この記事はやってみた事の記録であって、あまり整理された情報じゃないですごめんなさい。
  • ここに書いてある内容には間違いや不正確な点が含まれるかも知れない。

前提

  • ホストOS: MacOS 10.11.6

Dockerのインストール

まずMacにDockerをインストールする。

> brew install docker
> brew cask install docker

/Applications/Docker.appができるので、これをクリックして起動する。

Docker環境をHomebrewで手軽に作成 - Qiita

起動確認

docker psというコマンドで起動確認が出来る。

> docker ps
CONTAINER ID  IMAGE  COMMAND  CREATED  STATUS  PORTS  NAMES

上記のようにCONTAINERの一覧が表示されなかったら、インストールできてないか、もしくは、dockerのデーモンが起動してない可能性を疑ってみるといいかも。

コンテナイメージのpull

docker pullというコマンドでコンテナイメージをpull(イメージをダウンロードして使える状態にすること)ができる。

> docker pull ubuntu 

docker imagesで取得したコンテナイメージの一覧を表示。

> docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
ubuntu              latest              00fd29ccc6f1        9 days ago          111MB
alpine              latest              e21c333399e0        3 weeks ago         4.14MB

alpineというのはdocker向きの軽量なLinuxディストリビューションらしく、たしかにサイズがたった4.1MBしかない。index | Alpine Linux

興味はあったけど、よく知らないけどalpineのパッケージ管理ツールでデータ分析関連のパッケージで無いやつがあったりしてハマるのが嫌だったので今回はとりあえずUbuntuにしてみた。

コンテナの起動

> docker run -it --name "python-dlib" ubuntu     

"python-dlib"というのは、このコンテナに付けた名前です。 今日は、こいつの上にPython + miniconda + dlibな環境を準備していきます。

apt-getを実行してdocker commitする

とりあえず起動したコンテナ上に何が入ってるんだろう。 aptは入っているがpythonとかgitは無いっぽい事が分かる。

root@be6e91df27f0:/# apt -v
apt 1.2.24 (amd64)
root@be6e91df27f0:/# python -V
bash: python: command not found
root@be6e91df27f0:/# git
bash: git: command not found

とりあえずgitを入れてみる。

root@be6e91df27f0:/# apt-get update
root@be6e91df27f0:/# apt-get install git -y
root@be6e91df27f0:/# git --version
git version 2.7.4

dockerでは、コンテナに対して行った変更をdocker commitコマンドでイメージに反映できるらしいのでやってみる。

ホストマシン上で、docker commitコマンドを叩く。 この時、CONTAINER IDを指定する必要があるのでdocker psコマンドで調べておく。

> docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
be6e91df27f0        ubuntu              "/bin/bash"         8 minutes ago       Up 8 minutes                            python-dlib
> docker commit be6e91df27f0 "install-apt_git"

docker imagesを見ると、新たなコンテナイメージが作成されている事が分かる。

> docker images
REPOSITORY          TAG                 IMAGE ID            CREATED              SIZE
install-apt_git     latest              fbff7fa6f76d        About a minute ago   240MB
ubuntu              latest              00fd29ccc6f1        9 days ago           111MB
alpine              latest              e21c333399e0        3 weeks ago          4.14MB

引き続き色々インストールしてみる。

pyenv-installerでpyenvをインストール。

参考: Pyenvの使い方 - Qiita

root@be6e91df27f0:/# apt-get install curl -y
root@be6e91df27f0:/# curl -L https://raw.githubusercontent.com/pyenv/pyenv-installer/master/bin/pyenv-installer | bash
root@be6e91df27f0:/# echo 'export PATH="$HOME/.pyenv/bin:$PATH"' >> ~/.bashrc
root@be6e91df27f0:/# echo 'eval "$(pyenv init -)"' >> ~/.bashrc
root@be6e91df27f0:/# echo 'eval "$(pyenv virtualenv-init -)"' >> ~/.bashrc
root@be6e91df27f0:/# source ~/.bashrc
root@be6e91df27f0:/# pyenv -v
pyenv 1.2.0

次に minicondaをインストール

root@be6e91df27f0:/# pyenv install  miniconda3-4.3.30
Downloading Miniconda3-4.3.30-Linux-x86_64.sh...
-> https://repo.continuum.io/miniconda/Miniconda3-4.3.30-Linux-x86_64.sh
Installing Miniconda3-4.3.30-Linux-x86_64...

BUILD FAILED (Ubuntu 16.04 using python-build 20160602)

Inspect or clean up the working tree at /tmp/python-build.20171224075203.7994
Results logged to /tmp/python-build.20171224075203.7994.log

Last 10 log lines:
/tmp/python-build.20171224075203.7994 /
/tmp/python-build.20171224075203.7994/Miniconda3-4.3.30-Linux-x86_64 /tmp/python-build.20171224075203.7994 /
WARNING: bzip2 does not appear to be installed this may cause problems below
PREFIX=/root/.pyenv/versions/miniconda3-4.3.30
Miniconda3-4.3.30-Linux-x86_64.sh: line 333: bunzip2: command not found
tar: This does not look like a tar archive
tar: Exiting with failure status due to previous errors

エラーった。

bunzip2: command not foundと言われているので、入れる。

root@be6e91df27f0:/# apt-get install bzip2 -y

再びやったら通った。

root@be6e91df27f0:/# pyenv install  miniconda3-4.3.30
...
Installed Miniconda3-4.3.30-Linux-x86_64 to /root/.pyenv/versions/miniconda3-4.3.30

miniconda環境に切り替える。

oot@3fb9ed676e35:/# pyenv global miniconda3-4.3.30 
(miniconda3-4.3.30) root@3fb9ed676e35:/# python -V
Python 3.6.3 :: Anaconda, Inc.

この辺で再びdocker commitしておく。 これで、minicondaのインストールのみ終わった状態のdocker imageが出来た。これはこれで他の用途に使えるだろう。これは便利だ...

> docker commit 3fb9ed676e35 "setup-miniconda-py36"

dlibのインストール

dlibをソースコードからインストールする方法について、ここに大変親切な解説が載っていたので、この方法でインストールする。

installing_dlib_on_macos_for_python.md · GitHub

boostのインストール
cmakeのインストール

# apt-get install libboost-all-dev -y
# apt-get install cmake
# apt-get install build-essential

dlibのリポジトリをcloneしてくる。

# git clone https://github.com/davisking/dlib.git

ビルドしてインストール。

# cd dlib
# mkdir build; cd build; cmake .. -DDLIB_USE_CUDA=0 -DUSE_AVX_INSTRUCTIONS=1; cmake --build .

# cd ..
# python3 setup.py install --yes USE_AVX_INSTRUCTIONS --no DLIB_USE_CUDA

dlibの最新版が入った。

(miniconda3-4.3.30) root@0698b5cfb786:/# python
Python 3.6.3 |Anaconda, Inc.| (default, Oct 13 2017, 12:02:49) 
[GCC 7.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import dlib
>>> dlib.__version__
'19.8.99'

docker imageの保存

さて、途中から薄々気づいていたがdocker imageの構築は、今回のように直接コンテナのshellを操作するのではなく、Dockerfileと呼ばれるDSLを記述することによって構築されることが望ましいようだ。

Dockerfileはテキストベースで、軽量で共有しやすく、設定内容が明示的だからである。

とは言え、shellの操作によって作られたdocker imageを共有する方法もなくはないようだ。

docker saveコマンドを使うことで、docker imageがファイルとして出力できる。

> docker save setup-dlib:latest > setup-dlib.tar

また、docker loadでこのファイルを読み込んでimageとして使う事ができる。

> docker load < setup-dlib.tar

差し当たりではあるが、これで、様々な手段でライブラリを導入した環境を保存、再構築可能になった。

まとめ

  • dockerを使うことで分析環境の保存、再現が可能になる。
  • 課題
    • Dockerfileを使ったイメージの構築。
    • ホストOSとファイルを共有したい時どうするんだろう。
    • Alpine Linux気になる。
    • とりあえず動いたけど色々前提知識が無い。