Dockerコンテナ上でNGSのソフトウェアを実行してみる(Windows10・MacOSXローカル環境編)
きっかけ
近年では、BiocondaのようなBiology関連ソフトウェアに対するパッケージマネージャが登場し、NGS関連のソフトウェアのインストールがグッと簡単になりました(Biocondaが登場する前は、いちいちソースコードからコンパイルする必要があったり、各ソフトウェア固有のインストール方法を理解する必要があったり、とにかく手間がかかっていました…。NGS関連のソフトは依存関係が複雑で本当にやっかい)。
ただ、いろんな人のNGS関連のブログを見ていると、環境によってはBiocondaでうまくインストールできないという事例もあるようです(Biocondaレシピで想定されていなかったパッケージへの依存によるもの?)。確かに、Biocondaは非常に便利なんですが、他の環境でも同じ解析環境を構築しようとすると、再現よく環境を構築できないケースがあることがわかってきました。
そこで、ソフトウェアごとに仮想環境を構築し、各ソフトウェアの動作が保証された環境を色々な解析に使いまわすことで、上記の問題を解決しようと考えました。
そこで、Dockerの出番です。Dockerはコンテナ型仮想化技術の1つであり、ホストOS上で単一のプロセスとして起動します。ホストOSと同じカーネルを共有するため、VMWare, VirtualBoxなどのホスト型仮想化技術と比較して、軽量であるとされています。
「Docker」を全く知らない人のために「Docker」の魅力を伝えるための「Docker」入門
https://qiita.com/bremen/items/4604f530fe25786240db
前置きが長くなりましたが、今回は、Dockerを土台としたシステム基盤をつくることを考えるために、まずはローカル環境でDockerコンテナを動かしてみた (FastQCを実行して見る)という内容になります。
Dockerをベースにした解析パイプラインの活用事例
パッと目についた事例をあげてみました。他にもたくさんあると思います。
High-Throughput Genomics on AWS - LFS309 - re:Invent 2017
AWSのカンファレンス re:Invent 2017で紹介されたNGS解析のパイプライン
https://www.slideshare.net/AmazonWebServices/highthroughput-genomics-on-aws-lfs309-reinvent-2017
Broad Institute: Genomes-in-the-cloud
Broad Instituteで利用されているゲノム解析用のパイプライン
https://hub.docker.com/r/broadinstitute/genomes-in-the-cloud/
BioContainers
バイオインフォマティクス関連のDockerイメージファイルをまとめたもの
https://biocontainers.pro/
ベースとなるDockerイメージの選択
NGSのデータ解析をする上では、必要最小限のLinuxディストリビューションのDockerイメージを使用した方がいいと思います。1つはイメージサイズが小さいほど、Dockerイメージの起動や破棄、ダウンロードなどの取り回しの面で有利だから。もう1つは、軽量コンテナの方が不要なパッケージが少なく、セキュリティ上、潜在的な攻撃を受けにくいからです。
また、ベースイメージを選定する上で、OSにインストールマネージャーがついているかどうかや、ITベンダーなどにより定期的にメンテナンスされているかどうかもポイントになります。
以下では、主要なLinuxディストリビューションについて簡単に比較をして見たいと思います。
Dockerイメージのサイズ
以下が主要なLinuxディストリビューションのDockerイメージのサイズになります。
Linux OS | Compressed size |
---|---|
debian8.10-slim | 30 MB |
debian 8.10 | 53 MB |
ubuntu 18.04 | 35 MB |
centos 7.4.1708 | 73 MB |
上記のデータは、2018-03-13時点のデータです。少し前までは、Debianが軽量なDockerイメージだったので、Debian一択なのかと思っていましたが、Ubuntuも直近ではかなりスリム化を果たしていますね(ちなみに、Anacondaやその他NGS関連のDockerイメージはDebianをベースに作られたものが多い気がします)。
脆弱性レポート
各Dockerイメージのレポジトリのtag
タブから、各バージョンの脆弱性レポートを確認することができます。
スキャンされた各イメージをクリックすると、詳細を見ることができます。以下では、各LinuxディストリビューションのDockerイメージの脆弱性レポートを見ていくことにします。
debian8.10-slim
debian 8.10
ubuntu
centos 7.4.1708
脆弱性レポートまとめ
上記で示した脆弱性レポートの結果をまとめて見ました。いくつのコンポーネントが脆弱性を抱えているかカウントした表が以下の通りになります。
Linux OS | Vulnerability (Components) |
---|---|
debian8.10-slim | 6 |
debian 8.10 | 6 |
ubuntu 18.04 | 0 |
centos 7.4.1708 | 16 |
上記のデータは、2018-03-13時点のデータです。Ubuntuが脆弱性が0なのが際立っている気がします(本当かなって結果になりました)。
現状では、Debian-slimかUbuntuを選択するのが良いのかなと思いました。
Dockerのインストール
自身のパソコンにDockerをインストールします。
以下のURLから、Docker (Community Edition)をダウンロードできます。
https://www.docker.com/community-edition#/download
MacOSXにDockerをインストールして使う場合は以上でインストール完了です。
Windows10環境の場合、既存のコマンドプロンプトやPowershellがどうも使いにくい(個人的な感想ですが)ので、Windows Subsystem for Linux (WSL)を導入して、BashシェルからDockerを扱えるようにしたいと思います。
Windows Subsystem for Linux (WSL)経由でホストOS (Windows10)のDockerを動かす
1. WSLをインストールする
注意: Dockerを使用するにはHyper-Vを利用する必要があるため、OSがWindows10 Proであることが必須です。
Miscrosoft storeからWSLをダウンロード・インストールできるようになったので、ストアからインストールしましょう。今回はUbuntuを導入しました。
WSLを使用するためには、「プログラムと機能」から「Windowsの機能の有効化または無効化」を開き、Windows Subsystem for Linuxにチェックをつけます。
2. DockerをWSLにインストールする
以下のUbuntuへのDockerのインストール方法は、Dockerの公式ドキュメントを参考にしました。詳しくは、そちらを参照のこと。
Get Docker CE for Ubuntu
https://docs.docker.com/install/linux/docker-ce/ubuntu/#install-using-the-repository
WSLのBash shellを起動し、まずaptパッケージをアップグレードしておきます。
$ sudo apt-get update
次のDockerを動かすために必要な各種パッケージをインストールします。
$ sudo apt-get install \ apt-transport-https \ ca-certificates \ curl \ software-properties-common
Dockerの公式のGPGキーを加え、キー情報の確認を行っています。
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - $ sudo apt-key fingerprint 0EBFCD88 pub 4096R/0EBFCD88 2017-02-22 Key fingerprint = 9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88 uid Docker Release (CE deb) <docker@docker.com> sub 4096R/F273FCD8 2017-02-22
Dockerをインストールします。
$ sudo add-apt-repository \ "deb [arch=amd64] https://download.docker.com/linux/ubuntu \ $(lsb_release -cs) \ stable" $ sudo apt-get update $ sudo apt-get install docker-ce
3. WSL側とホストOS (Windows10)側のDockerを連携させる
Docker for Windowsのデーモンに接続するための設定を行います。今の状態では、あくまでホストOS側(Windows10)とWSL側で別々にDockerをインストールしただけなので、WSL側から、ホストOS側のDockerのデーモンプロセスを操作できるのように連携させる必要があります。
以下のように、WSL側のDockerクライアントからホストOS側のデーモンを見れるように、環境変数DOCKER_HOST
を設定します。
$ echo "export DOCKER_HOST='tcp://0.0.0.0:2375'" >> ~/.bashrc $ source ~/.bashrc
最後に、Windows10側のDockerの設定画面を開き、Expose daemon on tcp://localhost:2375 without TLS
にチェックを付けます。これで、WSL側からホストOS側のDockerのデーモンを操作できるようになりました。
参照
Docker for Windowsで快適な環境を得るまでの そこそこ長い闘い
https://qiita.com/YukiMiyatake/items/73c7d6c4f2c9739ebe60
WSL(Bash on Windows)でDockerを使用する
https://qiita.com/yoichiwo7/items/0b2aaa3a8c26ce8e87fe
Docker for WindowsをWSLから使う時のVolumeの扱い方
https://qiita.com/gentaro/items/7dec88e663f59b472de6
VSCodeの総合ターミナルでWSLを使う
VSCodeでは、エディタ内でターミナルを開くことができるので、こちらの標準のターミナルをWSLに変更しておくと便利です。
まず。設定画面から、terminal.integrated.shell.windows
で検索します。
対象の設定に対して "terminal.integrated.shell.windows": "C:\\Windows\\System32\\bash.exe"
のようにWSLのBash.exeのパスを指定します。
総合ターミナルを開いて確認すると、めでたくBashシェルが使えるようになっているはずです!
Dockerファイルの作成
まず、Linux OSのDockerイメージをベースイメージにして、その上にNGS解析のソフトウェアをインストールしたDockerイメージを作成します。
1. Debian9-slimにBiocondaをインストールしたDockerイメージを作成する
Linux OSのDebina9-slim
をベースイメージにして、BiocondaをインストールしたDockerイメージを作成します。
以下のDockerfileは、condaの公式Dockerfileを参考しました。
https://hub.docker.com/r/conda/miniconda2/~/dockerfile/
&&
で処理を連続して行っているのは、レイヤーを減らすためです。また、中間ファイルを削除することでDockerのイメージファイルのサイズを小さくしています。
Dockerfile
# Base image FROM debian:9-slim # Install Miniconda2 & Bioconda RUN apt-get -qq update && apt-get -qq -y install curl bzip2 \ && curl -sSL https://repo.continuum.io/miniconda/Miniconda2-latest-Linux-x86_64.sh -o /tmp/miniconda.sh \ && bash /tmp/miniconda.sh -bfp /usr/local \ && rm -rf /tmp/miniconda.sh \ && conda install -y python=2 \ && conda update conda \ && conda config --add channels r \ && conda config --add channels defaults \ && conda config --add channels conda-forge \ && conda config --add channels bioconda \ && apt-get -qq -y remove curl bzip2 \ && apt-get -qq -y autoremove \ && apt-get autoclean \ && rm -rf /var/lib/apt/lists/* /var/log/dpkg.log \ && conda clean --all --yes ENV PATH /opt/conda/bin:$PATH
次に、DockerfileからDockerイメージを作成します。
$ docker build -t debian9-slim-bioconda2:latest -f Dockerfile .
2. FastQCをインストールしたDockerイメージを作成する
先程作ったDockerイメージをベースにして、FastQCのインストールしたイメージファイルを作成します。
Dockerfile
# Base image FROM debian9-slim-bioconda2:latest # Application entry point # Dejavu fonts are not included with default::openjdk(fastqc recipe). # They are already included with conda-forge::openjdk. # https://github.com/conda-forge/staged-recipes/issues/3164 RUN conda update conda \ && conda install fastqc=0.11.6 \ && conda install -c conda-forge openjdk \ && conda clean --all --yes COPY ./fastqc/run_fastqc_local.py /run_fastqc_local.py ENTRYPOINT ["python", "/run_fastqc_local.py"]
Pythonのコードをエントリポイントに設定します。以下が、そのソースコードになります。
from __future__ import print_function import os import shlex import subprocess from argparse import ArgumentParser def run_fastqc(fastq_path, cmd_args, working_dir): """ Runs fastqc :param fastq_path: Local path to fastq file :param cmd_args: Additional command-line arguments to pass in :param working_dir: Working directory :return: Path to the result folder """ # Prepare fastqc result path fastqc_result_dir = os.path.join(working_dir, '') # Prepare fastqc log path fastqc_log_path = os.path.join(fastqc_result_dir, "log_fastqc.txt") # Prepare fastqc command cmd = "fastqc -o {0} {1} {2}".format( fastqc_result_dir, cmd_args, fastq_path) print(cmd) # Execute fastqc with open(fastqc_log_path, 'w') as log_file: subprocess.check_call(shlex.split(cmd), stdout=log_file) return fastqc_result_dir def main(): argparser = ArgumentParser() argparser.add_argument('--fastq_path', type=str, help="fastq sequence file", required=True) argparser.add_argument('--cmd_args', type=str, help="arguments/options for fastqc", default="") argparser.add_argument('--working_dir', type=str, default="data/") args = argparser.parse_args() print("Creating working directory...") if not os.path.exists(args.working_dir): os.mkdir(args.working_dir) print("Running fastqc...") local_result_dir = run_fastqc( args.fastq_path, args.cmd_args, args.working_dir) print('Save the result in {0}.'.format(local_result_dir)) print("successfully Completed !!") if __name__ == '__main__': main()
次に、DockerfileからDockerイメージを作成します。Pythonのコードも同じディレクトリに置いておきます。
$ docker build -t debian9-slim-bioconda2-fastqc:latest -f Dockerfile .
以下のコマンドで作成したDockerイメージをチェックできます。
$ docker images
Dockerイメージの実行
1. FASTQファイルの準備
適当なFASTQファイルを持っていない場合、以下の記事を参考にしてテストに使うFASTQファイルを用意してください。
2. Dockerコンテナを起動する
FASTQ_FILE
にFASTQファイル、FASTQファイルが置いてあるLOCAL_WORKING_DIR
に作業ディレクトリを指定します。また、DOCKER_IMAGE
に先ほど作成したDockerイメージを、DOCKER_WORKING_DIR
にDockerコンテナ内の適当な作業ディレクトリを指定します。
#!/bin/bash #LOCAL_WORKING_DIR="/Users/imamachinaoto/Desktop/NGS/data" # MacOS LOCAL_WORKING_DIR="/c/Users/imama/Desktop/NGS/fastqc/data" # Windows10(WSL) DOCKER_WORKING_DIR="/data" DOCKER_IMAGE="debian9-slim-bioconda2-fastqc:latest" FASTQ_FILE="RefSeq_hg38_2015-08-19_NM_ultraSlim.fq" docker run --rm -it \ -v ${LOCAL_WORKING_DIR}:${DOCKER_WORKING_DIR} \ ${DOCKER_IMAGE} \ --fastq_path ${DOCKER_WORKING_DIR}/${FASTQ_FILE} \ --working_dir ${DOCKER_WORKING_DIR}
ちなみに、DockerでWSL環境からホストOS(Windows10)のフォルダを見るとき、Cドライブは/mnt/c
ではなく、/c
です。Bashシェルからアクセスするときは、/mnt/c
(WSLにマウントされているCドライブを見る形)なのでパスの違いに注意が必要です。Windowsだと、これで詰まりました…。
コンテナでデータを管理する
http://docs.docker.jp/engine/userguide/dockervolumes.html
上記のシェルスクリプト(もしくは以下で説明するmakeコマンド)を実行することで、FastQCが実行されます。
ホストOSのディレクトリを、Docker上のディレクトリに紐づけておくこと(ボリュームのマウント)で、以下のようにDockerコンテナが破棄されたあとでも、データを永続化させることができます。
Dockerコマンドをまとめたmakefileの作成
Dockerコマンドはイメージファイルの作成やコンテナ起動時など、繰り返し使用します。なので、今回はmakefileにコマンド類をまとめて、make build
やmake start
などを用意することで、コマンド操作が簡単になります。
Windows10やWSLには、makeコマンドがインストールされていないため、あらかじめインストールしておきます。
Windows10でmakeファイルを実行する
WSLを使わない場合のmakeコマンドのインストール方法を示します。Windows10にはコマンドプロンプトからmakeコマンドを使えないので、まずmakeコマンドをインストールします。
1. makeコマンドをコマンドプロンプトに導入する(参考)
以下のURLから、makeをダウンロードします。
http://gnuwin32.sourceforge.net/packages/make.htm
C:\Program Files (x86)\GnuWin32\bin
にmake.exeが保存されているので、パスを通します。
2. WSL環境にmakeコマンドを導入する
WSLのコンソールから、以下のコマンドを実行するだけです。
$ sudo apt-get install make
Windowsでmakeコマンドを使う
https://qiita.com/tokikaze0604/items/e13c04192762f8d4ec85
makefileの例
NAME=debian9-slim-bioconda2-fastqc TAG=0.11.6.local UNDERSCORE_TAG=0_11_6_local LOCAL_WORKING_DIR=/c/dev/NGS/fastqc/data DOCKER_WORKING_DIR=/data DOCKER_IMAGE="fastqc-aws-debian9-slim-bioconda2:0.11.6.local" FASTQ_FILE=RefSeq_hg38_2015-08-19_NM_ultraSlim.fq all: build push build: docker build -t $(NAME):$(TAG) -t $(NAME):latest -f Dockerfile . build-no-cache: docker build --no-cache -t $(NAME):$(TAG) -t $(NAME):latest -f Dockerfile . push: docker push $(NAME):$(TAG) docker push $(NAME):latest start: docker run --rm -it -v ${LOCAL_WORKING_DIR}:${DOCKER_WORKING_DIR} ${DOCKER_IMAGE} --fastq_path ${DOCKER_WORKING_DIR}/${FASTQ_FILE} --working_dir ${DOCKER_WORKING_DIR} rm: docker rm `docker ps -aq` rmi: docker rmi $(NAME):$(TAG) $(NAME):latest
つまづいたポイント
makefileの作成
インデントはスペースではなく、タブにしないとエラーになる。
Visual Studio Codeの場合、makefileと認識されたファイルでは、インデントをタブにするように設定されている。しかし、ファイル名がMakefile
だと下記の設定が適応されない。makefile
と小文字のmにする必要がある。
Docker関連の参考
docker コマンド チートシート
https://qiita.com/voluntas/items/68c1fd04dd3d507d4083
dockerで
https://qiita.com/lirispp/items/06fc74c5bbc64fddf9ab