23

I have a dockerized django app that I want to put in production. But ever since I added an Imagefield Pillow is required and I struggle to install Pillow in the Docker container.

As far as I understand it, adding the dependencies jpeg-dev ibjpeg & zlib-dev should be enough for django (?). With the configuration below I receive the error:

Error on runserver:

product.Product.image: (fields.E210) Cannot use ImageField because Pillow is not installed.
    HINT: Get Pillow at https://pypi.org/project/Pillow/ or run command "pip install Pillow".
product.Product.thumbnail: (fields.E210) Cannot use ImageField because Pillow is not installed.
    HINT: Get Pillow at https://pypi.org/project/Pillow/ or run command "pip install Pillow".

If I add Pillow to requirements.txt (or putting pip install Pillow in the Dockerfile) I get an even longer error message while trying to build the container.

Without putting pip install Pillow in Dockerfile or requirements.txt - this is my configuration.

Dockerfile:

# pull official base image
FROM python:3.7-alpine

# set environment varibles
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1

# set work directory
WORKDIR /usr/src/kitschoen-dj

RUN pip install --upgrade pip

# install psycopg2
RUN apk update \
    && apk add --virtual build-deps gcc python3-dev musl-dev \
    && apk add postgresql \
    && apk add postgresql-dev \
    && pip install psycopg2 \
    && apk del build-deps
    && apk add jpeg-dev \
    && apk add libjpeg \
    && apk add zlib-dev

# install dependencies
RUN pip install --upgrade pip
COPY ./requirements.txt /usr/src/kitschoen-dj/requirements.txt
RUN pip install -r requirements.txt

# copy entrypoint.sh
COPY ./entrypoint.sh /usr/src/kitschoen-dj/entrypoint.sh

# copy project
COPY . /usr/src/kitschoen-dj/

# run entrypoint.sh
ENTRYPOINT ["/usr/src/kitschoen-dj/entrypoint.sh"]

Requirements.txt

astroid==2.1.0
certifi==2018.11.29
chardet==3.0.4
Django==2.1.7
django-cors-headers==2.4.0
django-filter==2.1.0
djangorestframework==3.9.1
djangorestframework-simplejwt==3.3
gunicorn==19.9.0
httpie==1.0.2
httpie-jwt-auth==0.3.0
idna==2.8
isort==4.3.4
lazy-object-proxy==1.3.1
Markdown==3.0.1
mccabe==0.6.1
PyJWT==1.7.1
requests==2.21.0
six==1.12.0
urllib3==1.24.1
wrapt==1.11.1

I have been stuck with this for a while. Can someone help?

Xen_mar
  • 8,330
  • 11
  • 51
  • 74

6 Answers6

68

For anyone who is interested in what worked for me (+ some background on why I ran into this):

Installing Pillow will require several dependencies. As far as I can tell, you need: gcc python3-dev jpeg-dev zlib-dev

To prevent these dependencies from ending up in the final image (keeping the image-size small) you can install some (not all!) of them in a virtual package.

After Pillow is installed successfully you can delete the dependencies that are only required for Pillow's installation.

Dependencies that are only needed during the build are called build dependencies.

So this is the code that worked for me:

RUN apk update \
    && apk add --virtual build-deps gcc python3-dev musl-dev \
    && apk add postgresql \
    && apk add postgresql-dev \
    && pip install psycopg2 \
    && apk add jpeg-dev zlib-dev libjpeg \
    && pip install Pillow \
    && apk del build-deps

(Some of the stuff is not required for Pillow, e. g. postgressql, postgresql-dev). As you can see, I installed my build dependencies in a virtual package called build-deps. AFTER installing the build dependencies, I am installing Pillow. At the end, I am removing the build dependencies.

I think, this is the solution that @LinPy proposed: I just wanted to explain this in a very verbose way to help others.

What is .build-deps for apk add --virtual command?

Xen_mar
  • 8,330
  • 11
  • 51
  • 74
22

add this to your Dockerfile:

RUN apk add --no-cache jpeg-dev zlib-dev
RUN apk add --no-cache --virtual .build-deps build-base linux-headers \
    && pip install Pillow

source: Github

LinPy
  • 16,987
  • 4
  • 43
  • 57
  • 1
    Thank you your input led me in the right direction! Not to say your solution doesn't work ... but it increases image size by about 120MB which is quite a lot. – Xen_mar Sep 04 '19 at 12:26
  • True, I think your solution is correct. What was missing for me (since I am still learning a lot of stuff, was that I have to delete the .build-deps in a later step for them to not end up in the image. But I like the usage of the meta-package build-base. I will keep that in mind. – Xen_mar Sep 04 '19 at 12:38
  • Pillow needs zlib-dev and jpeg-dev as build dependecies which can be removed. But it will also need libjpeg while running. So you could use something like this for a minimal image: `RUN apk add --update --no-cache --virtual .tmp gcc libc-dev linux-headers zlib-dev jpeg-dev && apk add libjpeg && pip install Pillow --no-cache-dir && apk del .tmp` – roOt Jun 08 '21 at 15:00
6

I just added these lines to my Dockerfile and it worked

RUN apk add --update --no-cache --virtual .tmp gcc libc-dev linux-headers
RUN apk add --no-cache jpeg-dev zlib-dev
RUN apk del .tmp

My Dockerfile (using python:3.8-alpine):

COPY ./requirements.txt /requirements.txt
RUN apk add --update --no-cache --virtual .tmp gcc libc-dev linux-headers
RUN apk add --no-cache jpeg-dev zlib-dev
RUN pip install -r /requirements.txt
RUN apk del .tmp
gastrodon
  • 75
  • 3
  • 9
Alan Moraes
  • 61
  • 1
  • 2
0

Add this to your Docker file

RUN apk add postgresql-dev gcc python3-dev musl-dev jpeg-dev zlib-dev

0

#Docker file FROM python:3.7-alpine

WORKDIR /app

set environment variables

ENV PYTHONDONTWRITEBYTECODE 1 ENV PYTHONUNBUFFERED 1

install psycopg2 dependencies

RUN apk update
&& apk add postgresql-dev gcc python3-dev musl-dev libc-dev make git libffi-dev openssl-dev libxml2-dev libxslt-dev zlib-dev jpeg-dev

install dependencies

COPY requirements.txt /app/requirements.txt RUN pip install --upgrade pip RUN pip install -r requirements.txt

copy project

COPY . .

Requirement file

Pillow==9.0.0

  • 1
    As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – excitedmicrobe Jan 29 '22 at 18:15
  • Would suggest you take a look at [the formatting how-to guide](https://stackoverflow.com/help/formatting), and make your code be beautiful :) – Jack Deeth Feb 02 '22 at 18:36
0

In my case it worked for me

FROM python:3.9.7-alpine

ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1


RUN mkdir /backend
ADD ./app /backend

WORKDIR /backend


RUN apk update && \
    apk add --virtual .tmp gcc python3-dev jpeg-dev zlib-dev musl-dev libjpeg py3-setuptools \
    tiff-dev openjpeg-dev freetype-dev lcms2-dev \
    libwebp-dev tcl-dev tk-dev harfbuzz-dev fribidi-dev libimagequant-dev \
    libxcb-dev libpng-dev alpine-sdk build-base openssl-dev dateutil tzdata py3-tz && \
    
    pip install --upgrade pip && \
    pip install -r requirements.txt && \
    echo 'requirements Installed' && \
    pip install uvicorn gunicorn  && \

    apk del .tmp



ENV DB_NAME  ******
ENV DB_USER ******
ENV DB_PASSWORD ******

ENV DJANGO_SUPERUSER_PASSWORD ******

CMD gunicorn myproject.asgi:application -k uvicorn.workers.UvicornWorker


Bambier
  • 586
  • 10
  • 16