Building Django Docker Image with Alpine

This article is intention to explain why you should build your docker image with Alpine Linux.


So, what is Alpine Linux?

Alpine Linux is a Linux distribution, and it’s primary designed for “power user who appreciate security, simplicity and resource efficiency”. https://en.wikipedia.org/wiki/Alpine_Linux

In short, Alpine Linux is just like other Linux distribution such as Ubuntu, Debain, Fedora etc… it is used to build image for docker. But the main reason why Alpine is heavily used for container because of its size. Alpine base size is around 4 to 5 MB and after the installation on disk is around 130MB. When your docker image getting smaller it get even faster for deployment.

Compare Image Built with Ubuntu and Alpine

Docker file using Python Alpine Image

FROM python:3.6-alpine
ENV PYTHONUNBUFFERED 1
# Creating working directory
RUN mkdir /code
WORKDIR /code
# Copying requirements
COPY ./myproject/ .
RUN apk add --no-cache --virtual .build-deps \
ca-certificates gcc postgresql-dev linux-headers musl-dev \
libffi-dev jpeg-dev zlib-dev \
&& pip install -r requirements.txt

Docker file using Python Ubuntu Image

FROM python:3.6
ENV PYTHONUNBUFFERED 1
# Creating working directory
RUN mkdir /code
WORKDIR /code
# Copying requirements
COPY ./myproject/ .
RUN apt-get update && apt-get install -y gettext libgettextpo-dev \
&& pip install -r requirements.txt

Result After Built

Built with same project and install the same dependencies.

As you can see, the image built with Alpine is 72% reduced in size. And thank to this post (https://blog.codeship.com/alpine-based-docker-images-make-difference-real-world-apps/), we can optimized further more.

Docker file with Python Alpine and even more optimization

FROM python:3.6-alpine
ENV PYTHONUNBUFFERED 1
# Creating working directory
RUN mkdir /code
WORKDIR /code
# Copying requirements
COPY ./myproject/ .
RUN apk add --no-cache --virtual .build-deps \
ca-certificates gcc postgresql-dev linux-headers musl-dev \
libffi-dev jpeg-dev zlib-dev \
&& pip install -r requirements.txt \
&& find /usr/local \
\( -type d -a -name test -o -name tests \) \
-o \( -type f -a -name '*.pyc' -o -name '*.pyo' \) \
-exec rm -rf '{}' + \
&& runDeps="$( \
scanelf --needed --nobanner --recursive /usr/local \
| awk '{ gsub(/,/, "\nso:", $2); print "so:" $2 }' \
| sort -u \
| xargs -r apk info --installed \
| sort -u \
)" \
&& apk add --virtual .rundeps $runDeps \
&& apk del .build-deps
Result with more optimization

Again we have reduced from 286MB to 145MB, and that is CRAZY!!

Conclusion

Building docker image with Alpine make our image size very small, compare to other Linux distribution base image. Pulling docker image is already fast with the size of a gigabyte, but it’s even faster with around 100 MB. And I use docker everyday for development and for around 6 projects it already took 10GB of storage space in my computer. Hopefully using Alpine base image gonna help me free up some spaces.

You can find the project testing result here: https://github.com/NorakGithub/django-docker-alpine