TL; DR
dockerでOpenCVが使えるpythonのコンテナが欲しかった。
適当にpythonのイメージを拾ってきて作ると1.07gbになってしまったが
ちょっと頑張ると440MBまで小さくなった。
概要
railsで作っているサービスに画像処理の機能を追加することになったが、
画像処理ならpythonの方が使い勝手が良さそうだと思った(偏見)ので、pythonコンテナを用意することにした。
何も考えずに用意すると、イメージサイズが1gbを超えてしまった。
railsや他のコンテナのイメージサイズと合わせると、酷いことになってしまったので、
頑張ってサイズを小さくした。
初めに用意したコンテナ
はじめに用意したDockerfileはかなりシンプル。
FROM python:3.7.0
WORKDIR /app
COPY requirements.txt /app/
RUN pip install --no-cache-dir -r requirements.txt
特に何事もなく動作確認ができたので、そのまま完了報告をしようかと思ったが
何か重たいなと感じ、
$ docker images
と叩いてみると
1.07GB
と表示されてしまった。
「え?デカ過ぎないか?」
python:3.7.0のイメージサイズが923MBとなっていたのでベースのイメージからして
重過ぎることはすぐに分かったが
$ docker history $image_name
とすると、サイズが大きくなってしまう原因を絞り込めると最近知ったので調べて見た。
するといくつか怪しそうなものが。。。
IMAGE CREATED CREATED BY SIZE COMMENT
82ef4046d424 3 minutes ago /bin/sh -c pip install --no-cache-dir -r req… 149MB
47b14d8c6138 About an hour ago /bin/sh -c #(nop) COPY file:459af46ed1f18f20… 262B
c77fb443d300 About an hour ago /bin/sh -c #(nop) WORKDIR /app 0B
a9d071760c82 2 weeks ago /bin/sh -c #(nop) CMD ["python3"] 0B
<missing> 2 weeks ago /bin/sh -c set -ex; wget -O get-pip.py 'ht… 5.93MB
<missing> 2 weeks ago /bin/sh -c #(nop) ENV PYTHON_PIP_VERSION=18… 0B
<missing> 2 weeks ago /bin/sh -c cd /usr/local/bin && ln -s idle3… 32B
<missing> 2 weeks ago /bin/sh -c set -ex && wget -O python.tar.x… 69.9MB
<missing> 2 weeks ago /bin/sh -c #(nop) ENV PYTHON_VERSION=3.7.0 0B
<missing> 2 weeks ago /bin/sh -c #(nop) ENV GPG_KEY=0D96DF4D4110E… 0B
<missing> 2 weeks ago /bin/sh -c apt-get update && apt-get install… 17MB
<missing> 2 weeks ago /bin/sh -c #(nop) ENV LANG=C.UTF-8 0B
<missing> 2 weeks ago /bin/sh -c #(nop) ENV PATH=/usr/local/bin:/… 0B
<missing> 2 weeks ago /bin/sh -c set -ex; apt-get update; apt-ge… 556MB
<missing> 2 weeks ago /bin/sh -c apt-get update && apt-get install… 142MB
<missing> 2 weeks ago /bin/sh -c set -ex; if ! command -v gpg > /… 7.8MB
<missing> 2 weeks ago /bin/sh -c apt-get update && apt-get install… 23.2MB
<missing> 2 weeks ago /bin/sh -c #(nop) CMD ["bash"] 0B
<missing> 2 weeks ago /bin/sh -c #(nop) ADD file:58d5c21fcabcf1eec… 101MB
因みに、以下にオプションをつけると各行のコマンドを省略せずに確認できた。
$ docker history $image_name --no-trunc=true
<missing> 2 weeks ago /bin/sh -c set -ex; apt-get update;
apt-get install -y --no-install-recommends
autoconf automake bzip2 dpkg-dev file g++ gcc imagemagick libbz2-dev libc6-dev libcurl4-openssl-dev libdb-dev libevent-dev libffi-dev libgdbm-dev libgeoip-dev libglib2.0-dev libjpeg-dev libkrb5-dev liblzma-dev libmagickcore-dev libmagickwand-dev libncurses5-dev libncursesw5-dev libpng-dev libpq-dev libreadline-dev libsqlite3-dev libssl-dev libtool libwebp-dev libxml2-dev libxslt-dev libyaml-dev make patch xz-utils zlib1g-dev
$(if apt-cache show 'default-libmysqlclient-dev' 2>/dev/null | grep -q '^Version:'; then
echo 'default-libmysqlclient-dev';
else
echo 'libmysqlclient-dev';
fi ) ;
rm -rf /var/lib/apt/lists/*
556MB
<missing> 2 weeks ago /bin/sh -c apt-get update &&
apt-get install -y --no-install-recommends bzr git mercurial openssh-client subversion procps && rm -rf /var/lib/apt/lists/*
142MB
<missing> 2 weeks ago /bin/sh -c #(nop) ADD file:
58d5c21fcabcf1eec94e8676a3b1e51c5fdc2db5c7b866a761f907fa30ede4d8 in /
101MB
alpine(非推奨かつ未完了)
python:3.7.0のイメージには不要なものが混ざっているようだったので、
もう少し小さいものから作ることにした。
調べているとalpineではpip installでopencv-pythonをインストールは出来なくて
自分でbuildしないといけないという話があったので、やろうとして見た。
まだ完成していないが、大体はこんな感じで良さそうだった。
FROM python:3.7.0-alpine
WORKDIR /app
COPY requirements.txt /app/
RUN apk upgrade --no-cache && \
apk add --update --no-cache \
redis \
build-base \
cmake \
gtk+3.0 \
pkgconfig \
linux-headers
RUN mkdir /opencv && \
cd /opencv && \
wget https://github.com/Itseez/opencv/archive/3.4.3.zip && \
unzip 3.4.3.zip && \
cd opencv-3.4.3 && \
mkdir build && \
cd build && \
cmake -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=/usr/local -D WITH_IPP=ON .. && \
make -j7 && \
make install && \
rm -rf /opencv
RUN pip install -r requirements.txt
ただ、buildにかなりの時間がかかってしまうことと、まだいくつかエラーが残ってしまっているので、
やる気がなくなり、alpineはやめることにした。
slim
最終的に採用したのはpython:3.7.0-slim。
OpenCVを使うためにはいくつかlibが足りなかったので、手動で入れる必要があったものの
alpineの時ほど頭をかかえる必要もなく、用意ができた。
そしてサイズも440MBと最初の半分以下になってくれた!
もっと小さくする方法もあるようだが、まぁこれは一旦は良いかと思った。
これをベースにして、足りないものが出てきたら適宜追加していくことにする。
FROM python:3.7.0-slim
WORKDIR /app
COPY requirements.txt /app/
ENV LIB="libswscale-dev \
libtbb2 \
libtbb-dev \
libjpeg-dev \
libpng-dev \
libtiff-dev \
libglib2.0-0 \
libsm6 \
libxext6 \
libavformat-dev \
libpq-dev"
RUN apt-get update \
&& apt-get -y upgrade \
&& apt-get install --no-install-recommends -qy $LIB \
&& apt-get clean \
&& apt-get autoclean \
&& apt-get autoremove \
&& pip install --no-cache-dir -r requirements.txt \
&& rm -rf /tmp/* /var/tmp/* \
&& rm -rf /var/lib/apt/lists/* \
rm -rf /var/lib/apt/lists/*
まとめ
dockerのイメージサイズはもっと手軽に小さくしていきたい。
あと、このままだとOpenCVで日本語が文字化けするので、適当にフォントを拾ってこないといけなさそう。
railsのイメージサイズは重たいまま