2

I want to dockerize flask application which has lots of dependencies. My goal is to reduce the size of the final docker image.

I tried multi-stage build but it is not reducing the size of final docker image.

Below is my Dockerfile

FROM python:3.6-slim-buster as base

RUN apt-get update && apt-get install --no-install-recommends --no-upgrade -y \
    libglib2.0-0 libxext6 libsm6 libxrender1 libfontconfig1 && rm -rf /var/lib/apt/lists/*


WORKDIR /wheels

COPY requirements.txt /wheels

RUN pip install -U pip \
   && pip wheel -r requirements.txt



FROM python:3.6-slim-buster

COPY --from=base /wheels /wheels


RUN pip install -U pip \
       && pip install -r /wheels/requirements.txt \
                      -f /wheels \
       && rm -rf /wheels \
       && rm -rf /root/.cache/pip/* 

...

Last pip install... command is taking up 905MB.

How should I separate all the requirements from the final image and reduce the overall size of the final docker image?

Parth Shihora
  • 75
  • 2
  • 8

1 Answers1

5

Deleting /wheels in the final RUN does not make your image smaller—those files are still in the previous layer that the final image builds on. Once you copy something in it's going to be in your image.

What I would suggest instead is installing the code into a virtualenv in the build image (though you can also do --user install) and copy the virtualenv over into the runtime image.

FROM python:3.7-slim AS compile-image
RUN apt-get update
RUN apt-get install -y --no-install-recommends build-essential gcc

RUN python -m venv /opt/venv
# Make sure we use the virtualenv:
ENV PATH="/opt/venv/bin:$PATH"

COPY requirements.txt .
RUN pip install -r requirements.txt

COPY setup.py .
COPY myapp/ .
RUN pip install .

FROM python:3.7-slim AS build-image
COPY --from=compile-image /opt/venv /opt/venv

# Make sure we use the virtualenv:
ENV PATH="/opt/venv/bin:$PATH"
CMD ['myapp']

See here for original version with more explanations: https://pythonspeed.com/articles/multi-stage-docker-python/

Itamar Turner-Trauring
  • 3,430
  • 1
  • 13
  • 17
  • 1
    my application requires some libraries which can be installed using `apt-get` and it is not getting installed in virtual env. Is there a way to accomplish this? – Parth Shihora Jul 27 '19 at 02:06
  • You can also do `apt-get install` in the second image, with a different list of packages than the first image if you want. The virtulenv is a way to make copying the files easier, that's all. – Itamar Turner-Trauring Jul 27 '19 at 10:38