1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Django】Django + mysqlclientのDockerイメージサイズを1/7に軽量化する

Posted at

この記事について

シンプルなPythonのDockerイメージを軽量化する方法について調べると,ベースイメージをslimにする,マルチステージビルドをするといった方法をよく見かけます.しかし,DjangoでMySQLを使用する場合の推奨ドライバであるmysqlclientをインストールするためには,少し工夫が必要みたいです.

そこで,イメージを限りなく軽量化しつつ,mysqlclientがインストールできるDockerfileを作成してみました.

準備

今回は日本語訳されたDocker公式ドキュメントのクイックスタートにあるDockerfileを編集して軽量化していきます.

Dockerfile
FROM python:3
ENV PYTHONUNBUFFERED 1
RUN mkdir /code
WORKDIR /code
ADD requirements.txt /code/
RUN pip install -r requirements.txt
ADD . /code/

ちなみにrequirements.txtには必要最低限のものだけ記述してます.

requirements.txt
Django
mysqlclient

まずはこのDockerfileを使ってイメージをビルドしてみます.(この後の比較のためにタグつけてます)

$ docker build . -t django-mysqlclient:base
$ docker image ls

REPOSITORY           TAG       IMAGE ID       CREATED         SIZE
django-mysqlclient   base                                     1.07GB

1.07 GBというサイズになりました.こいつをどこまで軽量化できるか試していきます.

軽量化する

slimイメージを使う

まずはベースイメージをslimに変更してみます.
slimイメージを使用することで,よく用いられるライブラリ以外を除外した,サイズが削減されたPythonイメージをpullできるようです.しかし,mysqlclientのインストール時に必要なパッケージも除外されるようで,apt-getでインストールしています.

Dockerfile
+ FROM python:3-slim
- FROM python:3
ENV PYTHONUNBUFFERED 1
+ RUN apt-get update && \
+  apt-get install -y default-libmysqlclient-dev build-essential pkg-config
RUN mkdir /code
WORKDIR /code
ADD requirements.txt /code/
RUN pip install -r requirements.txt
ADD . /code/

このDockerfileを使ってイメージをビルドしてみます.

$ docker build . -t django-mysqlclient:slim
$ docker image ls

REPOSITORY           TAG       IMAGE ID       CREATED         SIZE
django-mysqlclient   base                                     1.07GB
django-mysqlclient   slim                                     546MB

1.07 GB から 546 MB になりました.だいたい半分のサイズですね.

マルチステージビルドする

次にマルチステージビルドを行います.
マルチステージビルドとは,ビルドに必要なパッケージを含むイメージと,実行に必要なパッケージだけを含むイメージを別々にビルドすることで,最終的なイメージを軽量化する手法です.

Dockerfile
FROM python:3-slim as base

FROM base as builder
ENV PYTHONUNBUFFERED 1
RUN apt-get update && \
  apt-get install -y default-libmysqlclient-dev build-essential pkg-config
RUN mkdir /install
ADD requirements.txt .
RUN pip install --prefix=/install -r requirements.txt

FROM base as runner
ENV PYTHONUNBUFFERED 1
COPY --from=builder /install /usr/local
COPY --from=builder /usr/lib/x86_64-linux-gnu/libmysql* /usr/lib/x86_64-linux-gnu
COPY --from=builder /usr/lib/x86_64-linux-gnu/libmaria* /usr/lib/x86_64-linux-gnu
COPY --from=builder /usr/bin/mysql_config /usr/bin
RUN mkdir /code
WORKDIR /code
ADD . /code/

簡単に解説をすると,builderステージではこれまでの同様にapt-getやpipで必要なパッケージをインストールしておき,runnerステージでDjangoとmysqlclientの動作に必要なファイルのみをコピーしてきています.

さて,このDockerfileを使ってイメージをビルドしてみます.

platformによってmysqlclient関連のパッケージがインストールされる場所が変わるようで,M1/M2 Macの方は--platform=linux/amd64オプションを追加すると動作するかと思われます.

$ docker build . -t django-mysqlclient:slim-multi
$ docker image ls

REPOSITORY           TAG          IMAGE ID       CREATED         SIZE
django-mysqlclient   base                                        1.07GB
django-mysqlclient   slim                                        546MB
django-mysqlclient   slim-multi                                  156MB

546 MB から 156 MB になりました.最初と比べると約1/7のサイズになりましたね.

おわりに

今回はクイックスタートのDockerfileを比較対象にするために,最低限の変更にとどめていますが,もっと最適化ができる部分(ADD命令をCOPY命令にするとか)があるかと思います.間違い・改善点等があれば指摘していただけますと幸いです.

参考

1
0
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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?