cjnash
cjnash

Reputation: 1248

Trouble installing opencv in docker container using pip

I want to build a python docker container that has scikit-learn, opencv, and numpy. Unfortunately, I couldn't find a pre-built container that contained all these, but I did find the one below that contains numpy and scikit-learn.

https://hub.docker.com/r/frolvlad/alpine-python-machinelearning/

I still needed to install opencv, so within my docker file I included a RUN pip install opencv-python. However, I keep on getting the error below:

Could not find a version that satisfies the requirement opencv-python (from version: ) No matching distribution found for opencv-python

Every single thing I have read online says that a pip install opencv-python will work, but it isn't working for me for some reason. Is it a problem with the python package maybe?

Any help is appreciated

Also, I will include my full Dockerfile below, I am aiming to use openFaas, which is a serverless framework, so my Dockerfile might look odd:

FROM frolvlad/alpine-python-machinelearning

RUN apk update
RUN apk upgrade

# Alternatively use ADD https:// (which will not be cached by Docker builder)
RUN apk --no-cache add curl \
    && echo "Pulling watchdog binary from Github." \
    && curl -sSL         
https://github.com/openfaas/faas/releases/download/0.8.0/fwatchdog > /usr/bin/fwatchdog \
    && chmod +x /usr/bin/fwatchdog \
    && apk del curl --no-cache

# Add non root user
RUN addgroup -S app && adduser -S -g app app
RUN chown app /home/app

RUN pip install -U pip

USER app

ENV PATH=$PATH:/home/app/.local/bin

WORKDIR /home/app/

RUN pip install opencv-python

RUN mkdir -p function
RUN touch ./function/__init__.py
WORKDIR /home/app/function/
RUN pip install --user app opencv-python

WORKDIR /home/app/
COPY function           function

ENV fprocess="python index.py"

HEALTHCHECK --interval=1s CMD [ -e /tmp/.lock ] || exit 1

CMD ["fwatchdog"]

Upvotes: 20

Views: 26678

Answers (6)

rnorris
rnorris

Reputation: 2092

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.9-slim, since it will come with Python already installed (substitute 3.9 for a newer version if this no longer works). 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.

Additionally, you will need to install a couple extra packages in order to actually use opencv. Be sure to add RUN apt-get update && apt-get install -y libglib2.0-0 libgl1-mesa-glx && rm -rf /var/lib/apt/lists/* to your Dockerfile so the shared libraries that OpenCV depends on are present in the container image.

Upvotes: 27

chakib
chakib

Reputation: 1

Solved with:

pip3 install --upgrade setuptools pip

pip3 install opencv-python

source > https://github.com/3b1b/manim/issues/1213#issuecomment-703272203

Upvotes: 0

tobias-fyi
tobias-fyi

Reputation: 49

I found this article, Using Alpine can make Python Docker builds 50x slower, to be very helpful when dealing with this issue. Here is an excerpt from it:

... standard Linux wheels don’t work on Alpine Linux.

Why? Most Linux distributions use the GNU version (glibc) of the standard C library that is required by pretty much every C program, including Python. But Alpine Linux uses musl, those binary wheels are compiled against glibc, and therefore Alpine disabled Linux wheel support.

Most Python packages these days include binary wheels on PyPI, significantly speeding install time. But if you’re using Alpine Linux you need to compile all the C code in every Python package that you use.

Which also means you need to figure out every single system library dependency yourself.

Hopefully this adds to the comment/recommendation from rnorris to use a different base image (if you're not married to Alpine).

The article was very helpful to me in debugging this issue. I hope it is for you as well!

Upvotes: 4

wynemo
wynemo

Reputation: 2323

you can use this https://hub.docker.com/r/jjanzic/docker-python3-opencv

it's Docker image with python 3.7 and opencv 4.1.0

docker run -it jjanzic/docker-python3-opencv python
>>> import cv2

then you can install opencv-python==4.1.2.30 by pip.

Upvotes: 1

Utopia
Utopia

Reputation: 661

Using python:3.7-alpine, I was just able to install both numpy and opencv-utils. The only change I needed to make was to add g++ as additional package to my apk command in Dockerfile

RUN apk --no-cache add g++ ${ADDITIONAL_PACKAGE}

Hope this helps !!

Upvotes: 3

Jan Jongboom
Jan Jongboom

Reputation: 27342

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.

Upvotes: 7

Related Questions