【Python】データ分析環境をコンテナで作るならベースイメージにalpineはやめた方が良いかもしれない

Numpy/Pandas、scikit-learnを使うPython実行環境を整えようとしているあなたへ。

悪いことは言わないので、alpineイメージを使うのは**やめた方が良いです**。


# 結論から

**slim**イメージを使いましょう。
3.7系の最新であるバージョン`3.7.5`のベースイメージサイズの違いは以下の通り。

```shell
$ docker images
python              3.7.5-alpine3.10    b11d2a09763f        8 days ago          98.8MB
python              3.7.5-slim          46cf279fff55        11 days ago         179MB
python              3.7.5               023b89039ba4        11 days ago         918MB
```

# あれこれパッケージ追加するのにAlpineは不向き

Pythonでコンテナ環境を立ち上げるみなさんは多分 `Numpy`や`scikit-learn`を使いたい場面が多いのではないでしょうか。
`Pandas`もバックエンドで`Numpy`が依存関係にあります。

これらのパッケージは高速・高機能なだけあって重量級のパッケージであり、裏側ではC言語が使われています。

以下で実例を述べていきます。

# AlpineにNumpyをインストールするまで

Numpyのインストールには必要パッケージがあります。これは、Numpyは内部でC言語が使われており高速性・高機能性が実現されているためです。

以下のようなDockerfileを用意してコンテナをビルドします。
ビルドするまでの時間も計ってみます。

```Dockerfile:Dockerfile
FROM python:3.7.5-alpine3.10

RUN apk --no-cache add gcc python3-dev musl-dev && \
    pip install --upgrade pip && \
    pip install --no-cache numpy
```


```shell
$ time docker build . -t my_python
Sending build context to Docker daemon  2.048kB
Step 1/2 : FROM python:3.7.5-alpine3.10
 ---> b11d2a09763f
Step 2/2 : RUN apk --no-cache add gcc python3-dev musl-dev &&     pip install --upgrade pip && pip install --no-cache numpy

Collecting numpy
  Downloading https://files.pythonhosted.org/packages/b6/d6/be8f975f5322336f62371c9abeb936d592c98c047ad63035f1b38ae08efe/numpy-1.17.3.zip (6.4MB)
Building wheels for collected packages: numpy
  Building wheel for numpy (setup.py): started
  Building wheel for numpy (setup.py): still running...
  Building wheel for numpy (setup.py): still running...
  Building wheel for numpy (setup.py): still running...
```

めっちゃ時間かかるんですけど...

お。終わりました。

```shell
~~
Successfully tagged my_python:latest

real    5m31.468s
user    0m0.043s
sys     0m0.062s
```

＿人人人人人人人人人人人＿
＞　5m31.468s　　　　　＜
￣Y^Y^Y^Y^Y^Y^Y^Y^Y^Y￣

5分半かかりました。
※実行環境はCore-i5-626U 上の vCPU 2コア仮想マシン

ちなみに `sklearn`のインストールはもっとかかり、諦めました。
原因は`Collecting numpy`の後ろにあります。

```
Collecting numpy
  Downloading https://files.pythonhosted.org/packages/b6/d6/be8f975f5322336f62371c9abeb936d592c98c047ad63035f1b38ae08efe/numpy-1.17.3.zip (6.4MB)
```

ZIPファイル、つまり**ソースコードをそのまま**ダウンロードしてローカル上でビルドしているのです。
そうではなく あらかじめコンパイルされたパッケージである`wheel`が見つかれば良いのですが、Alpineイメージには無いのでしょう。

# で、結局軽量イメージなわけ？

上記のDockerfileでNumpyは無事インストールできました。
ここで、イメージサイズの軽量性を吟味するためにnumpyはインストールしない(コンテナホストの必要パッケージが整っている)状態でのサイズを比較してみます。
つまり、以下のDockerfileです。

```Dockerfile:Dockerfile
FROM python:3.7.5-alpine3.10

RUN apk --no-cache add gcc python3-dev musl-dev
```

```shell
$ docker build . -t my_python2
Sending build context to Docker daemon  2.048kB
(略)
Successfully tagged my_python2:latest
$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
my_python2          latest              c348cdbf1ce8        5 seconds ago       294MB
```

＿人人人人人人人＿
＞　SIZE　　　　＜
＞　**294MB**　　　＜
￣Y^Y^Y^Y^Y^Y￣

ベースイメージ`python:3.7.5-slim`のイメージは**179MB**でした。
これ、**使う意味ある**？

# 一方slimイメージを使うと…？

**前提パッケージは何も必要ありません**。
Dockerflleすら用意せずに結果を確認してみます。

```shell
$ docker run -it python:3.7.5-slim bash
root@fba70cf17452:/# pip install numpy
Collecting numpy
  Downloading https://files.pythonhosted.org/packages/00/4a/e34fce8f18c0e052c2b49f1b3713469d855f7662d58ae2b82a88341e865b/numpy-1.17.3-cp37-cp37m-manylinux1_x86_64.whl (20.0MB)
     |████████████████████████████████| 20.0MB 4.2MB/s
Installing collected packages: numpy
Successfully installed numpy-1.17.3
```

10秒もかからずにインストール完了しました。
ここでのミソは、ダウンロードしているのがZIPファイルではなくビルド済みである`whl`ファイルである点です。
scikit-learn(`sklearn`)も同様に10秒足らずでインストールできました。

# まとめ

ベースイメージに色々追加パッケージをインストールするならslimベースイメージ一択です。

もし、本当にシンプルで軽量なランタイムが必要でしたら もちろんAlpineが適しているでしょう。