6
12

More than 3 years have passed since last update.

Python分析に便利なDockerfile

Posted at

初めに

 この記事は、自分用に作成したPython分析環境を共有するために書いています。Pythonで分析する際は、テーブルデータや画像、自然言語等が主な対象データになると思いますが、今回作成したDockerfileは、Conda、OpenCV、MeCabをインストールする構成にしたので、色々な分析のBaselineにすることが可能です。(自然言語処理をしない場合はMeCab部分のコードを消す等してください。)

 次の章から、作成した環境について説明をしていきますが、Docker等の単語の意味をここでは説明しません。Qiita には良質な解説記事が多くありますので、基本的な単語については、そちらを参考にしてください。

環境

 検証した環境を以下に示します。仮想環境には WSL2 ではなく、VirtualBox を使いました。WSL2 は別のマシンで環境構築した際に苦戦した思い出があるので、今回は VirtualBox + PowerShell で実施しています。

・Windows 10 Pro 64bit
・Docker Desktop 4.0.0 (67817) (Download page)
・Docker Engine 20.10.8
・Docker-compose v2.0.0-rc.2

Docker Desktop for Windows を使っていますが、場合によっては有料となっているため、企業が利用する場合等は注意ください。以下は ITmedia の記事です。
Docker Desktopが有料化へ 従業員数250人未満・年間売り上げ1000万ドル未満の組織などは引き続き無料

Docker インストールはこのあたりを参照ください。インストーラーが少し重いのでダウンロードに多少時間がかかります。(私の場合20分程度)
WindowsでDocker環境を試してみる

フォルダ構成

 Buildする際のフォルダ構成を以下に示します。3つのフォルダ(input / output / notebook)は、分析の際に .ipynbファイルやデータを置く場所です。Image内にこれらのフォルダを含める必要がない(Build の際には使わない)ため、.dockerignore に3つのフォルダ名を記載しています。また、docker-compose.yml に書いてある通り、このフォルダはマウントされるため、Build 完了後に起動する Jupyterlab からこのフォルダが見えるようになります。そのため、Windows とのやり取りはここで行うことが可能です。

Container name/ (ここは何でもOK)
 ┠ input/
 ┠ output/
 ┠ notebook/
 ┠ .dockerignore
 ┠ clean-layer.sh
 ┠ docker-compose.yml
 ┠ Dockerfile
 ┠ requirements_conda.txt
 ┠ requirements_pip.txt

 これら一式を 私のGithub に Upload したので、欲しい人はダウンロードしてご活用ください。

各ファイルの説明

 ここから各ファイルの内容について、要点を絞って解説していきます。

 まずは、docker-compose.yml からです。これは、以下のサイトを参考に作成しました。フォルダ構成等も大変参考になりました。
Dockerでデータ分析環境を手軽に作る方法

 やっていることを簡単に言うと、Image を Build して、最後の行に書かれている command を実行しています。この形で書いておくことによって、毎回長い docker run のコマンドをたたく必要がなく、覚えやすいコマンドで実行が出来るようになります。

docker-compose.yml
version: "2.3"
services:
  jupyter:
    build: .
    volumes:
      - .:/tmp/working
    working_dir: /tmp/working
    ports:
      - 8888:8888
    command: jupyter lab --ip=0.0.0.0 --allow-root --no-browser

build: .:実行した場所にあるDockerfileを実行します。
volumes: .:/tmp/working:実行した場所をマウントします。
ports: 8888:8888:Localhost:8888 をDocker のポート8888 に転送します。さらに、Jupyter側がポート8888(デフォルト)で待っているので、Localhost:8888 にアクセスすることで、Jupyter に繋がるようになります。

 GPUを使いたい場合は、build と同じ階層に runtime: nvidia を追加します。ここの書き方は docker-compose.yml の冒頭に記載している version に左右されることに注意ください。

 次は、clean-layer.sh です。これは、Kaggle公式のGithub と同じものです。Docker では、RUN コマンド等を実行する度に Layer が作成され、RUN を書けば書くほど最終的に出来上がる Image が重くなります。そのため、多くの人は1つの RUN コマンドに多くのコマンド(apt-get/pip等)を書いていると思います。しかし、RUN の最後にゴミを削除するコマンド(clean-layer.sh)を実行すれば、最終的な Image が重くなりません(どこまでかは未検証ですが・・・)。RUN を複数に分けることは、可読性向上に繋がるため、この記事では clean-layer.sh を挟む実装を採用しています。

clean-layer.sh
#!/bin/bash
#
# This scripts should be called at the end of each RUN command
# in the Dockerfiles.
#
# Each RUN command creates a new layer that is stored separately.
# At the end of each command, we should ensure we clean up downloaded
# archives and source files used to produce binary to reduce the size
# of the layer.
set -e
set -x

# Delete files that pip caches when installing a package.
rm -rf /root/.cache/pip/*
# Delete old downloaded archive files 
apt-get autoremove -y
# Delete downloaded archive files
apt-get clean
# Ensures the current working directory won't be deleted
cd /usr/local/src/
# Delete source files used for building binaries
rm -rf /usr/local/src/*
# Delete conda downloaded tarballs
conda clean -y --tarballs

 最後に Dockerfile の解説を行います。こちらの書きっぷりも大変 Kaggle の Dockerfile が参考になりました。基本的には、Ubuntu20.04 + MiniConda + JupyterLab の環境であり、そこに Python のライブラリを入れているイメージです。

Dockerfile
FROM ubuntu:20.04

ADD  clean-layer.sh  /tmp/clean-layer.sh
COPY requirements_conda.txt ./
COPY requirements_pip.txt ./

ARG DEBIAN_FRONTEND=noninteractive

# Make sure python version you want to use
ENV PYTHON_MAJOR_VERSION=3
ENV PYTHON_MINOR_VERSION=7
ENV PATH="/root/miniconda3/bin:${PATH}"

# Update and install necessary modules.
RUN apt-get update && \
    apt-get install -y git vim wget zip unzip curl make cmake && \
    wget --quiet https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh && \
    mkdir /root/.conda && \
    bash Miniconda3-latest-Linux-x86_64.sh -b && \
    rm -f Miniconda3-latest-Linux-x86_64.sh && \
    chmod +x /tmp/clean-layer.sh && \
    /tmp/clean-layer.sh

# Install python
RUN conda config --add channels conda-forge && \
    conda config --add channels nvidia && \
    conda config --add channels pytorch && \
    conda config --add channels rapidsai && \
    conda install --yes python=$PYTHON_MAJOR_VERSION.$PYTHON_MINOR_VERSION && \
    apt-get install -y python3-pip && \
    /tmp/clean-layer.sh

# Install conda packages.
# Conda can solve dependency problem, and running speed is fast more than pip packages.
RUN conda install --yes --file requirements_conda.txt && \
    /tmp/clean-layer.sh

# Install pip packages. The packages, libsm6 libxrender1 are needed for opencv.
RUN apt-get install -y libsm6 libxrender1 --fix-missing && \
    pip3 install --no-cache-dir -r requirements_pip.txt && \
    /tmp/clean-layer.sh

# Install MeCab and NEologd dic (Japanese useful dictionary)
RUN apt-get install -y sudo mecab mecab-ipadic libmecab-dev && \
    git clone --depth 1 https://github.com/neologd/mecab-ipadic-neologd.git && \
    chmod 777 ./mecab-ipadic-neologd/bin/install-mecab-ipadic-neologd && \
    ./mecab-ipadic-neologd/bin/install-mecab-ipadic-neologd -y -n && \
    cp /etc/mecabrc /usr/local/etc/mecabrc && \
    /tmp/clean-layer.sh

# Install jupyterlab and jupyter-kite (https://github.com/kiteco/jupyterlab-kite)
RUN curl -sL https://deb.nodesource.com/setup_12.x |bash - && \
    apt-get install -y --no-install-recommends nodejs && \
    pip3 install --upgrade --no-cache-dir 'jupyterlab~=3.0' jupyterlab-git && \
    wget --quiet https://linux.kite.com/dls/linux/current && \
    pip3 install --upgrade --no-cache-dir  jupyter-kite && \
    jupyter labextension install "@kiteco/jupyterlab-kite" && \
    /tmp/clean-layer.sh

 ベースイメージは Ubuntu20.04 にしていますが、GPU を使う場合は、ベースイメージを以下等に変更してください。

From nvidia/cuda:11.0.3-cudnn8-devel-ubuntu18.04

ARG DEBIAN_FRONTEND=noninteractive:cmake をインストールした際に、タイムゾーン選択が出て、Build が止まってしまうので、interactive dialogue が出ないようにしています。https://askubuntu.com/questions/909277/avoiding-user-interaction-with-tzdata-when-installing-certbot-in-a-docker-contai
NEologd dic:正式名称は「mecab-ipadic-NEologd」。結構新しい単語もはいっている辞書で有用。https://github.com/neologd/mecab-ipadic-neologd
jupyter-kite:Jupyter で Autocomplete を使えるようにします。https://github.com/kiteco/jupyterlab-kite

Build 結果

コマンドは以下です。

docker-compose up --build

または、

docker-compose build --no-cache
docker-compose up

 --no-cache は、以下のエラーが Dockerfile 作成の試行錯誤中に何度か出たので、dockerでmysqlが立ち上がらなくなった。 を参考に追加しました。もし、ご自身で試行錯誤を実施した際にこのエラーが発生したら試してください。

failed to solve: rpc error: code = Unknown desc = failed to solve ...

 docker-compose up を実行すると Jupyter lab にアクセスする URL (http://127.0.0.1:8888/lab?token=...) が表示されるので、アクセスしてください。以下の画面が表示されます。
jupyter.png

Git 連携

 今回、jupyterlab-git もインストールしているため、GitHub / GitLab との連携が可能です。試しに 私のGithub から clone してみます。まずは、clone するフォルダを配置する場所に移動します。今回は input の下に移動します。そして、以下画像の赤枠をクリックします。
jupyter_git.png
 次に、Clone a Repository をクリックし、Clone したい Repository の URL (https://github.com/tt20171105/Machine-Learning 等)をコピペします。最後に CLONE をクリックすることで、input 直下に Machine-Learning フォルダが作成されます。これでご自身の Git を連携して修正して push したり、他の Repository を Clone してきて使ったりと便利になると思います。是非活用ください。
jupyter_git_clone.png

6
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
12