Search code examples
pythondockerdockerfiledebian-buster

Docker image taking long to build


Here are the contents of the Dockerfile, i changed from an alpine image to the slim-buster image. Im really struggling to see why its taking so long i think its got to do with all the aps im updating and installing in apt-get update. I might be reinstalling packages i don't need perhaps or doing something i don't need to, is there a way i can speed this up?

# pull official base image
FROM python:3.8-slim-buster

# set work directory
WORKDIR /opt/workspace

# set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1

# Need this crap for wkhtml old install because any version after this doesn't work with charts and javascript
RUN echo "deb http://security.debian.org/debian-security jessie/updates main" >> /etc/apt/sources.list

# Pillow and Psycopg Dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
        build-essential \
        wget \ 
        libpq-dev \
        libpng-dev \
        libjpeg-dev \
        python-dev \
        postgresql-client \
        python3-pip \
        python3-setuptools \
        python3-wheel \
        python3-cffi \
        libssl1.0.0 \
        libpng12-0 \
        xfonts-base \
        xfonts-75dpi \
        libcairo2 \
        libpango-1.0-0 \
        libpangocairo-1.0-0 \
        libgdk-pixbuf2.0-0 \
        libffi-dev \
        shared-mime-info\
        gcc \
        musl-dev \
        python3-dev \
        tk-dev \
        uuid-dev \ 
    && rm -rf /var/lib/apt/lists/*

# fetch wait for it script
RUN wget -q -O /usr/bin/wait-for-it https://raw.githubusercontent.com/vishnubob/wait-for-it/master/wait-for-it.sh && \
    chmod +x /usr/bin/wait-for-it

RUN pip install psycopg2

# bunch of wkhtmltopdf shit only works with charts on this image.
RUN wget http://archive.ubuntu.com/ubuntu/pool/main/libj/libjpeg-turbo/libjpeg-turbo8_2.0.3-0ubuntu1_amd64.deb
RUN dpkg -i libjpeg-turbo8_2.0.3-0ubuntu1_amd64.deb

RUN wget https://github.com/wkhtmltopdf/wkhtmltopdf/releases/download/0.12.2.1/wkhtmltox-0.12.2.1_linux-trusty-amd64.deb
RUN dpkg -i wkhtmltox-0.12.2.1_linux-trusty-amd64.deb

# Install Dependencies
COPY requirements.txt /opt/workspace/requirements.txt
RUN pip install --no-cache-dir -r requirements.txt

# copy entrypoint.sh
COPY ./entrypoint.sh /opt/workspace/entrypoint.sh

# copy project
COPY . /opt/workspace

# run entrypoint.sh
ENTRYPOINT ["/opt/workspace/entrypoint.sh"]

EDIT: After Receiving an answer I have updated my dockerfile to the following. Bare in mind the only packages i need to install using apt-get are the packages that wkhtmltopdf requires to run! it is running so much faster now and is working a lot better.

FROM python:3.8-slim-buster

# set work directory
WORKDIR /opt/workspace

# set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
ENV DEBIAN_FRONTEND=noninteractive

# Need this crap for wkhtml old install
RUN echo "deb http://security.debian.org/debian-security jessie/updates main" >> /etc/apt/sources.list

RUN apt-get update && apt-get install -y --no-install-recommends \
        wget \
        fontconfig \
        xfonts-base \
        xfonts-75dpi \
        libssl1.0.0 \
        libpq-dev \
        libpng-dev \
        libjpeg-dev \
        libffi-dev \
        libpng12-0 \
        libxext6 \
        libx11-6 \
        libxrender1 \ 
        gcc \
    && rm -rf /var/lib/apt/lists/*

# fetch wait for it script
RUN wget -q -O /usr/bin/wait-for-it https://raw.githubusercontent.com/vishnubob/wait-for-it/master/wait-for-it.sh && \
    chmod +x /usr/bin/wait-for-it

# bunch of wkhtmltopdf shit only works with charts on this image.
RUN wget http://archive.ubuntu.com/ubuntu/pool/main/libj/libjpeg-turbo/libjpeg-turbo8_2.0.3-0ubuntu1_amd64.deb
RUN dpkg -i libjpeg-turbo8_2.0.3-0ubuntu1_amd64.deb

RUN wget https://github.com/wkhtmltopdf/wkhtmltopdf/releases/download/0.12.2.1/wkhtmltox-0.12.2.1_linux-trusty-amd64.deb
RUN dpkg -i wkhtmltox-0.12.2.1_linux-trusty-amd64.deb

# Install Dependencies
COPY requirements.txt /opt/workspace/requirements.txt
RUN pip install --no-cache-dir -r requirements.txt

# copy entrypoint.sh
COPY ./entrypoint.sh /opt/workspace/entrypoint.sh

# copy project
COPY . /opt/workspace

# run entrypoint.sh
ENTRYPOINT ["/opt/workspace/entrypoint.sh"]

Solution

  • There's a bunch of issues here. First, there are packages you don't need:

    1. You're installing python twice. You're installing python, the Debian Python package, but the Docker python image has its own version of Python (in /usr/local), with dev headers already there. You don't need this, and it can lead to confusion because you end up with two versions of Python (https://pythonspeed.com/articles/importerror-docker/).

    2. musl-dev is unnecessary. Debian uses glibc, not musl. I suspect this is holdover from Alpine.

    3. You are installing a compiler, a whole bunch of C headers in general, all those *-dev packages. It's quite possible you don't need to at all! On Alpine, you need to compile everything because Alpine can't use normal binary wheels. (https://pythonspeed.com/articles/alpine-docker-python/) Since you're on Debian, quite possibly all your depedencies have binary wheels. You would still need a compiler for your own code, but if it's pure Python quite possibly not.

    So my suggestion: just drop the whole apt-get line. Pretty good chance it'll Just Work without it.