I’m Python developer and Docker user. I like Python. It’s simple and developing process is very fast, but usually it’s not the best choice if you want a small distributable software.
It’t very common that a Python project is packaged as Docker Image with some hundreds of MB. Even for a small projects! But don’t worry. Here you have a trick to create smaller Docker Python images.
Oks, we want to package a project with this typical scaffolding:
$ ls -lh demo_app/
-rw-r--r-- 1 Dani staff 1B May 25 10:31 Dockerfile
-rw-r--r-- 1 Dani staff 2B May 25 09:28 MANIFEST.in
drwxr-xr-x 2 Dani staff 64B May 25 09:27 app
-rw-r--r-- 1 Dani staff 9B May 25 09:27 requirements.txt
-rw-r--r-- 1 Dani staff 0B May 25 09:27 setup.py
The process will be as the following:
- Write a multi-step Docker file.
- Start with a Python base image.
- Create a Python wheel building step with python optimization flags.
- Create the final layer and install the built wheels avoiding using Pypi index server.
Then we create this Dockefile:
FROM python:3.8-alpine as base
RUN apk update && \
apk upgrade
FROM base as builder
RUN apk add --no-cache build-base && \
python -m pip install --no-cache-dir -U pip wheel
COPY ./ /app/
RUN python -OO -m pip wheel --no-cache-dir --wheel-dir=/root/wheels -r /app/requirements.txt && \
python -OO -m pip wheel --no-cache-dir --wheel-dir=/root/wheels /app/
FROM base
COPY --from=builder /root/wheels /root/wheels
RUN python -m pip install --no-cache --no-index /root/wheels/*
RUN rm -rf /root/wheels
ENTRYPOINT ["my-project"]
We only must pay attention to two things:
Int the first one we were installed the project dependencies and our own project:
RUN python -OO -m pip wheel --no-cache-dir --wheel-dir=/root/wheels -r /app/requirements.txt && \
python -OO -m pip wheel --no-cache-dir --wheel-dir=/root/wheels /app/
The second one we were installed only wheels we were created in the previous steps avoiding pip access to Pypi server for download anything:
RUN python -m pip install --no-cache --no-index /root/wheels/*
So the resulting Docker image will only contains binaries generated code by wheels without optimization Python flags