How do I reduce a python (docker) image size using a multi-stage build?

gCoh picture gCoh · Jan 31, 2018 · Viewed 18.2k times · Source

I am looking for a way to create multistage builds with python and Dockerfile:

For example, using the following images:

1st image: install all compile-time requirements, and install all needed python modules

2nd image: copy all compiled/built packages from the first image to the second, without the compilers themselves (gcc, postgers-dev, python-dev, etc..)

The final objective is to have a smaller image, running python and the python packages that I need.

In short: how can I 'wrap' all the compiled modules (site-packages / external libs) that were created in the first image, and copy them in a 'clean' manner, to the 2nd image.

Answer

gCoh picture gCoh · Feb 9, 2018

ok so my solution is using wheel, it lets us compile on first image, create wheel files for all dependencies and install them in the second image, without installing the compilers

FROM python:2.7-alpine as base

RUN mkdir /svc
COPY . /svc
WORKDIR /svc

RUN apk add --update \
    postgresql-dev \
    gcc \
    musl-dev \
    linux-headers

RUN pip install wheel && pip wheel . --wheel-dir=/svc/wheels

FROM python:2.7-alpine

COPY --from=base /svc /svc

WORKDIR /svc

RUN pip install --no-index --find-links=/svc/wheels -r requirements.txt

You can see my answer regarding this in the following blog post

https://www.blogfoobar.com/post/2018/02/10/python-and-docker-multistage-build