ベイジアンメタ分析のためのDockerファイル作成法

本記事は,Stan advent calender 2018の8日目の記事になります。

Dockerとは

Dockerは,コンテナ型の仮想環境を作成・配布・実行するためのプラットフォームです。私のぼんやりとした理解では,RやRstudioなどのアプリとそれを動かすための最小限の仮想環境を1つの箱に入れて使えるようにするものです。Windowsを使っていても,Macを使っていても,すぐに同じRやRstudioを動かす環境を作ることができます。これは,研究の再現性を高めるためにも非常に重要なことになります(そして,とても便利です)。Docker自体は,以下の書籍が大変勉強になりました。オススメです。

Docker/Kubernetes 実践コンテナ開発入門

Docker/Kubernetes 実践コンテナ開発入門

StanにおけるDockerの活用については,@kazutanの記事が大変参考になります(昨年のStan Advent Calendarで紹介されています)。Dockerさえインストールされていれば,数分でStanやその他の便利なパッケージが入ったRStudioを使えるようになります。ただ,いつも自分が使っているパッケージがこのDockerには入ってないと思う人もいるかもしれません。そこで,今日は,この便利な@kazutanのDockerを自分色に染めることをテーマにします。

qiita.com

自家製Dockerの作成方法

1 偉大な先人の肩によじ登る(Dockerfileを読む)

まず,kazutan/stan-dのDockerfileを読むところから始めます。

FROM rocker/tidyverse

# Change environment to Japanese(Character and DateTime)
ENV LANG ja_JP.UTF-8
ENV LC_ALL ja_JP.UTF-8
RUN sed -i '$d' /etc/locale.gen \
  && echo "ja_JP.UTF-8 UTF-8" >> /etc/locale.gen \
    && locale-gen ja_JP.UTF-8 \
    && /usr/sbin/update-locale LANG=ja_JP.UTF-8 LANGUAGE="ja_JP:ja"
RUN /bin/bash -c "source /etc/default/locale"
RUN ln -sf  /usr/share/zoneinfo/Asia/Tokyo /etc/localtime

# Install Japanese fonts
RUN apt-get update && apt-get install -y \
  fonts-ipaexfont

# Install packages
# rstanarmが2017/12/21からコンパイルでコケる。pythonがらみっぽいので外す
RUN Rscript -e "install.packages(c('githubinstall','rstan','ggmcmc','bayesplot','brms'))"

CMD ["/init"]

1行目をみるとFROM rocker/tidyverseとありますので,rocker/tidyverseがベースになっているのが分かります。さらに,rocker/tidyverseのベースは・・・とたどっていくとrocker/r-verにたどりつきます。このrocker/r-verの1行目に,FROM debian:stretchとありますので,どうやら,このDockerfileは,LinuxDebian 9.0(コードネーム: stretch)の上に,RやRstudioをインストールしたものに,tidyverseなどのパッケージをいれたものをベースにしていると考えられます。重要なのは,LinuxDebian 9.0の上で動いていることです。

# Change environment to Japanese(Character and DateTime)# Install Japanese fontsの部分は,日本語環境の設定になります。自分用のDockerfileでもそのまま引き継ぐと良いかと思います。

自家製Dockerのためには,# Install packagesが重要になります。RUN Rscript -e "install.packagesを使って,Rスクリプトを走らせてパッケージをインストールします。ここでは,'githubinstall','rstan','ggmcmc','bayesplot','brms'がインストールされるのが分かります。なお,rocker/tidyverseがベースなので,tidyverse関連のパッケージはすでに入っています。

このような感じで,すでにあるDockerfileをベースにしながら,自分に必要なアプリやパッケージを追加することができます。

2 Docker fileを自分流にいじる

さて,自分流のDockerfileを作ってみましょう。作成はお好きなテキストエディタをお使いください。今回は,たまたま私がネットワークメタ分析の勉強をしていたので,ネットワークメタ分析のためのDockerfileを作ることにします。以下が,kazutan/stan-dに追加したいRパッケージです。

  • devtools
  • rjags
  • gemtc
  • netmeta
  • ggnetwork
  • tidybayes

基本的には,RUN Rscript -e "install.packages(c(...))"に必要なRパッケージを入れればよいのですが,ベイズ流のネットワークメタ分析を簡単にやってくれるgemtcはJAGSベースのパッケージなので,JAGSも別途入れる必要があります(当たり前ですが,rjagsもJAGSが必要です)。「あれ,DockerでJAGSをどうやっていれればいいの?」ってなりますが,大元がLinuxDebianだったのを思い出します。ということで,Debian系でのJAGSのインストール方法をググったり,merliseclyde/docker-jagsを参考にして,以下のようにしました。なお,libglpk-devは何かのパッケージで必要だったので,追加しました(何かは忘れた)。

# Install JAGS & libglpk(for dependencies of gemtc)
RUN apt-get update && apt-get install -y \
    jags \
    libglpk-dev \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*

さて,以下のように自分用のDockerfileができました。Dockerfileという名前をつけて保存ください(拡張子は不要です)。実際は,次のローカル環境でのbuildをしてみて,うまくいくかチェックしつつ作成をします。

FROM rocker/tidyverse
MAINTAINER "Yoshihiko Kunisato" ykunisato@psy.senshu-u.ac.jp
# This Dockerfile was created based on kazutan/stan-d

# Change environment to Japanese(Character and DateTime)
ENV LANG ja_JP.UTF-8
ENV LC_ALL ja_JP.UTF-8
RUN sed -i '$d' /etc/locale.gen \
  && echo "ja_JP.UTF-8 UTF-8" >> /etc/locale.gen \
    && locale-gen ja_JP.UTF-8 \
    && /usr/sbin/update-locale LANG=ja_JP.UTF-8 LANGUAGE="ja_JP:ja"
RUN /bin/bash -c "source /etc/default/locale"
RUN ln -sf  /usr/share/zoneinfo/Asia/Tokyo /etc/localtime

# Install Japanese fonts
RUN apt-get update && apt-get install -y \
  fonts-ipaexfont

# Install JAGS & libglpk(for dependencies of gemtc)
RUN apt-get update && apt-get install -y \
    jags \
    libglpk-dev \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*

# Install R packages
RUN Rscript -e "install.packages(c('devtools','rjags','gemtc','rstan','ggmcmc','bayesplot','tidybayes','brms','netmeta','ggnetwork'))"

CMD ["/init"]
3 ローカル環境でうまくいくかチェック

Dockerfileができたら,ローカル環境で試します。ターミナルを起動して(Macユーザーの場合,Winの方はくぐってください)。Dockerfileの置いてあるフォルダに移動します(Macユーザーなら,ターミナルにcd って打ち込んでからDockerfileのあるフォルダをターミナルにドラッグすればcdの後にパスが入るので,それで移動できます。さらに、lsと打ち込んでDockerfile があればオッケーです)。Dockerfile のあるフォルダに移動できたら,以下を打ち込みます。netmetaはこちらでつける名前なので,何でも良いです。無事,buildができたら完了です。私が初めて試した時はJAGS周りのインストールで何度か失敗して,Dockerfileを何度か書き直しました。とはいえ,linuxでRを使うときの情報は多いので,それほど大変な試行錯誤でもなかったです。

docker build ./ -t netmeta
4 Githubリポジトリと連携したDocker hubリポジトリの作成

ローカルでうまくいったら,docker hubにアップします。ただ,そのままアップするより,githubと連携させて,githubリポジトリにREADMEとDockerfileを置いて,そこに変更が加えられたらdocker hubも自動更新されるようにすると便利です。やり方は以下が分かりやすかったです。これが上手くいくと,githubの内容がdocker hubで自動更新され,docker hub上でbuildされます。ここでbuildされるので,他のユーザーはそのイメージをpull(ダウンロード)して,すぐに使えるようになります。

nekopunch.hatenablog.com

ykunisato/netmeta-rの使用法

さて、早速使ってみましよう!

(1) 以下から,Docker Desktopをダウンロードしてインストールする。

www.docker.com

(2) ターミナル(Macユーザー)を開く

(3) ターミナルに以下を打ち込んで、イメージをpullする

docker pull ykunisato/netmeta-r

(4) ターミナルに以下を打ち込んで、コンテナーをrunする。パスワードとコンテナ名はご自身の好きなように設定ください。

docker run -e PASSWORD=パスワード -p 8787:8787 -v ~:/home/rstudio -d --name コンテナ名 ykunisato/netmeta-r

(5) ブラウザを開いて,urlバー(アドレスバー)に,http://localhost:8787/ とタイプする

(6) ブラウザ上にRstudioが出てくるので,IDにrstudio,パスに上記で設定したパスワードをいれる。

これだけで,ご自身のパソコンで簡単にネットワークメタ分析をするための環境が構築できました。

最後に

Dockerについて,最初に@kazutanから聞いたときは,あまりその重要性には気づけませんでした。ただ,一度使ってみると,どこでも同じ解析環境を作ることができるのは非常に便利なことに気づきます。少なくともパソコンを2台以上使用される方は,是非とも活用してみてください!

Enjoy!