Trouble installing opencv in docker container using pip

I've just run into this issue as well. It turns out that this is not working because opencv-python does not have any prebuilt wheels for Alpine (the distribution you're using as your base docker image).

The conversation in this issue on the opencv-python package explains why this happens in greater detail. The TL;DR is: if you really need to use Alpine, you can try forcing the installation of the manylinux wheel for opencv-python, but this can break. Your best option if you need to keep Alpine is to build the module from source. Since you are running this on OpenFAAS, I suspect you will want to keep your size low, so building from source may be a good option for you.

If you're not attached to Alpine, I would suggest moving to a different base docker image. If you're not sure which image to use as your base, I would recommend python:3.7-slim, since it will come with Python already installed (substitute 3.7 for whichever version you are using, but really. . . 3.7 is nice). With this container, you can simply run pip install opencv-python numpy scipy to have all three of your desired packages installed. The rest of your Dockerfile should work mostly unmodified; you will just need to install/uninstall curl using apt instead of apk.


I had the same issue, but even more complicated by requiring an ARMv7 image (as this was supposed to run on a Raspberry Pi). I've put together a Dockerfile and a pre-built OpenCV installation here: alpine-opencv-docker.

Alternatively you can compile yourself in the Dockerfile, but this takes a huge amount of time (probably close to a full day), via:

ENV OPENCV_VER 3.3.0
ENV OPENCV https://github.com/opencv/opencv/archive/${OPENCV_VER}.tar.gz

# build dependencies
RUN apk add -U --no-cache --virtual=build-dependencies \
    build-base \
    clang \
    clang-dev ninja \
    cmake \
    freetype-dev \
    g++ \
    jpeg-dev \
    lcms2-dev \
    libffi-dev \
    libgcc \
    libxml2-dev \
    libxslt-dev \
    linux-headers \
    make \
    musl \
    musl-dev \
    openjpeg-dev \
    openssl-dev \
    python3-dev \
    zlib-dev \
    && apk add --no-cache \
    curl \
    freetype \
    gcc \
    jpeg \
    libjpeg \
    openjpeg \
    python3 \
    tesseract-ocr \
    zlib

# build opencv from source
RUN mkdir /opt && cd /opt && \
    curl -L $OPENCV | tar zx && \
    cd opencv-$OPENCV_VER && \
    mkdir build && cd build && \
    cmake -G Ninja \
          -D CMAKE_BUILD_TYPE=RELEASE \
          -D CMAKE_INSTALL_PREFIX=/usr/local \
          -D WITH_FFMPEG=NO \
          -D WITH_IPP=NO \
          -D PYTHON_EXECUTABLE=/usr/bin/python3 \
          -D WITH_OPENEXR=NO .. && \
    ninja && ninja install && \
    cp -p $(find /usr/local/lib/python3.6/site-packages -name cv2.*.so) \
/usr/lib/python3.6/site-packages/cv2.so

I pulled together my package by compiling the above in a huge EC2 VM, then pulling the following paths off the container:

  • /usr/lib/python3.6/site-packages/cv2.so
  • /usr/local/include/opencv
  • /usr/local/include/opencv2
  • /usr/local/lib

Then I can add them back via normal ADD commands in my Dockerfile, so now everyone who wants to spin up the container is done in seconds instead of days.