Dockerイメージのベースイメージの選び方とその理由
Dockerでコンテナを作る時、超軽量OSであるalpine Linuxを使用することが多いと思います。
というものも通常はイメージが小さくなり、ビルドが速くなるからです。
しかし、PythonではAlpine Linuxをベースイメージに選ぶのはNGです!
Pythonを使用する場合はAlpine Linuxを使用するとビルドがめちゃくちゃ遅くなります!
PythonイメージでベースイメージにAlpine Linuxを使うと以下のようなデメリットがあります
・イメージを大きくなる
・時間がめちゃくちゃかかる
・たまに、理由がよくわからないランタイムバグが発生することも
Pythonパッケージをインストールする時、pipを使いますが、pipはビルド済みのバイナリをPyPIからダウンロードしてきてます。
通常はコンパイルしないのです。
によって全てのパッケージはバージョンごとにビルド(コンパイル)されています。
それをただsite-packagesにダウンロードしてきているわけです。
Alpine LinuxでnumpyやmatplotlibやpandasなどのPythonパッケージをインストールしようとすると、全てをコンパイルする必要があるのです。
というのも、通常のほとんどのLinux OSはコンパイルに標準CライブラリのGNUバージョン(glibc)を使用していますがAlpine Linuxでは軽量化のためにmusl libcを使用しています。
Alpine Linuxの開発者もこの問題は理解していて、いくつかのコンパイルに時間がかかるPythonパッケージ(matplotlibやpandas)に関してはalpineをベースイメージとしたpythonイメージに最初から入れてしまおうとしています。
しかし、根本的な解決策ではないので、全てのPythonパッケージがAlpineで高速インストールできることは今後もないでしょう。
ではどうすれば良いのか?
ベースイメージとしてDebianやCentOSを使えばいいのです。
Python公式Dockerイメージでは(例えば現時点で最新版は3.8.2)タグが、
3.8.2-buster
, 3.8.2-slim-buster
があります、タグにslimが付いているバージョンはDebian OSからあまり必要でない部分を削ぎ落としたバージョンです。
というわけでpython3.8.2を使いたいなら、python:3.8.2-slim-buster
イメージを使うと良いと思います。
Alpine Linuxは予期せぬランタイムバグを引き起こす可能性がある
Alpineが使用しているmusl Cライブラリは、理論的には他のLinuxディストリビューションで使用されているglibcとほとんど互換性があります。
実際にはその違いが問題を引き起こす可能性があります。
PythonのイメージにAlpine Linuxを使用しない方が良いです。
コメント