Search code examples
pythondockerdockerfiledocker-multi-stage-build

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


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.


Solution

  • 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