Search code examples
pythondockerarmdockerfiletensorflow-lite

Docker container with Python modules gets too big


I want my Docker container to use tensorflow lite (tflite) in a python script. My Dockerfile looks like this:

FROM arm32v7/python:3.7-slim-buster
COPY model.tflite /
COPY docker_tflite.py /
COPY numpy-1.20.2-cp37-cp37m-linux_armv7l.whl /
RUN apt-get update \
    && apt-get -y install libatlas-base-dev
RUN pip install numpy-1.20.2-cp37-cp37m-linux_armv7l.whl \
    && pip install --no-build-isolation --extra-index-url https://google-coral.github.io/py-repo/ tflite_runtime

CMD ["python", "docker_tflite.py"]

The Docker Container is too big for my microcontroller at 197 MB, is there any way to make it smaller?


UPDATE:

Following Itamar's answer, I have adjusted my Dockerfile:

FROM arm32v7/python:3.7-slim-buster as dev
COPY model.tflite /
COPY docker_tflite.py /
COPY numpy-1.20.2-cp37-cp37m-linux_armv7l.whl /
RUN apt-get update \
    && apt-get -y install libatlas-base-dev
RUN pip install --user numpy-1.20.2-cp37-cp37m-linux_armv7l.whl \
    && pip install --user --no-build-isolation --extra-index-url https://google-coral.github.io/py-repo/ tflite_runtime


FROM arm32v7/python:3.7-slim-buster as runtime
COPY model.tflite /
COPY docker_tflite.py /
COPY --from=dev /root/.local /root/.local
RUN apt-get update \
    && apt-get -y install libatlas-base-dev

CMD ["python", "docker_tflite.py"]

Meanwhile the Docker container is at 179 MB, which is already a progress, thank you very much. Is there any more optimization potential in my Dockerfile, e.g. in the apt-get statements?


Solution

  • There quite a few options for making the installation smaller:

    • You could make a build with e.g. PyInstaller and only install the artifact on an image without python. You get the "binary" and only the artifacts needed to run the application. If you build it on a builder image with python and then copy the artifact to your resulting image it could have a lot of impact on size especially of that image is e.g. an alpine bare or busybox image.
    • You can also add the --no-install-recommends to your apt-get command to not follow all deps.
    • Multi-stage image with one builder image and a target image. The builder image can be as big as it needs to be to build and the target image as small as possible and only copy the needed end build.
    • The 3.7-slim-stretch is already a few Mb smaller than the slim-buster...
    • add this to your RUN command && apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* to clean up after yourself
    • etc.

    I don't know if the impact will be big enough to reduce to 120Mb. :-)

    FROM arm32v7/python:3.7-slim-buster as dev
    COPY model.tflite /
    COPY docker_tflite.py /
    COPY numpy-1.20.2-cp37-cp37m-linux_armv7l.whl /
    RUN apt-get update \
        && apt-get -y install libatlas-base-dev
    RUN pip install --user numpy-1.20.2-cp37-cp37m-linux_armv7l.whl \
        && pip install --user --no-build-isolation --extra-index-url https://google-coral.github.io/py-repo/ tflite_runtime
    
    
    FROM arm32v7/python:3.7-slim-stretch as runtime
    COPY model.tflite /
    COPY docker_tflite.py /
    COPY --from=dev /root/.local /root/.local
    RUN apt-get update \
        && apt-get -y install libatlas-base-dev \
        && apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
    
    CMD ["python", "docker_tflite.py"]
    

    ^^^ changed to stretch and added the apt-get clean stuff