2

Trying to install matplotlib on an alpine docker image. I get a bunch of ugly messages. Am I missing some additional pre-req that needs to be manually installed?

Here is docker file:

    FROM openjdk:8-jre-alpine
    RUN apk update
    RUN apk add --no-cache tesseract-ocr
    RUN echo     import numpy, matplotlib, skimage, _tkinter > test.py
    RUN apk add --no-cache python3
    RUN pip3 install --upgrade pip setuptools
    RUN apk add --no-cache py3-numpy
    RUN pip install matplotlib

And the relevant docker output (similar output if I just do it live on Linux)

Collecting kiwisolver>=1.0.1
 Downloading kiwisolver-1.3.1.tar.gz (53 kB)
   ERROR: Command errored out with exit status 1:
    command: /usr/bin/python3.6 -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-yp9mr2j7/kiwisolver_29f6c98e09ef4d15af4bbadde3b1c2a2/setup.py'"'"'; __file__='"'"'/tmp/pip-install-yp9mr2j7/kiwisolver_29f6c98e09ef4d15af4bbadde3b1c2a2/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' egg_info --egg-base /tmp/pip-pip-egg-info-t2cdn0ra
        cwd: /tmp/pip-install-yp9mr2j7/kiwisolver_29f6c98e09ef4d15af4bbadde3b1c2a2/
   Complete output (44 lines):
   WARNING: The wheel package is not available.
     ERROR: Command errored out with exit status 1:
      command: /usr/bin/python3.6 -u -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-wheel-nil1gs35/cppy_c6bc34a322e5441da8a1a97ba7950d95/setup.py'"'"'; __file__='"'"'/tmp/pip-wheel-nil1gs35/cppy_c6bc34a322e5441da8a1a97ba7950d95/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' bdist_wheel -d /tmp/pip-wheel-wb4xn65c
          cwd: /tmp/pip-wheel-nil1gs35/cppy_c6bc34a322e5441da8a1a97ba7950d95/
     Complete output (6 lines):
     usage: setup.py [global_opts] cmd1 [cmd1_opts] [cmd2 [cmd2_opts] ...]
        or: setup.py --help [cmd1 cmd2 ...]
        or: setup.py --help-commands
        or: setup.py cmd --help
   
     error: invalid command 'bdist_wheel'
     ----------------------------------------
     ERROR: Failed building wheel for cppy
   ERROR: Failed to build one or more wheels
   Traceback (most recent call last):
     File "/usr/lib/python3.6/site-packages/setuptools/installer.py", line 126, in fetch_build_egg
       subprocess.check_call(cmd)
     File "/usr/lib/python3.6/subprocess.py", line 311, in check_call
       raise CalledProcessError(retcode, cmd)
   subprocess.CalledProcessError: Command '['/usr/bin/python3.6', '-m', 'pip', '--disable-pip-version-check', 'wheel', '--no-deps', '-w', '/tmp/tmpa3b9n_qa', '--quiet', 'cppy>=1.1.0']' returned non-zero exit status 1.
   
   The above exception was the direct cause of the following exception:
   
   Traceback (most recent call last):
     File "<string>", line 1, in <module>
     File "/tmp/pip-install-yp9mr2j7/kiwisolver_29f6c98e09ef4d15af4bbadde3b1c2a2/setup.py", line 92, in <module>
       cmdclass={'build_ext': BuildExt},
     File "/usr/lib/python3.6/site-packages/setuptools/__init__.py", line 152, in setup
       _install_setup_requires(attrs)
     File "/usr/lib/python3.6/site-packages/setuptools/__init__.py", line 147, in _install_setup_requires
       dist.fetch_build_eggs(dist.setup_requires)
     File "/usr/lib/python3.6/site-packages/setuptools/dist.py", line 676, in fetch_build_eggs
       replace_conflicting=True,
     File "/usr/lib/python3.6/site-packages/pkg_resources/__init__.py", line 766, in resolve
       replace_conflicting=replace_conflicting
     File "/usr/lib/python3.6/site-packages/pkg_resources/__init__.py", line 1049, in best_match
       return self.obtain(req, installer)
     File "/usr/lib/python3.6/site-packages/pkg_resources/__init__.py", line 1061, in obtain
       return installer(requirement)
     File "/usr/lib/python3.6/site-packages/setuptools/dist.py", line 732, in fetch_build_egg
       return fetch_build_egg(self, req)
     File "/usr/lib/python3.6/site-packages/setuptools/installer.py", line 128, in fetch_build_egg
       raise DistutilsError(str(e)) from e
   distutils.errors.DistutilsError: Command '['/usr/bin/python3.6', '-m', 'pip', '--disable-pip-version-check', 'wheel', '--no-deps', '-w', '/tmp/tmpa3b9n_qa', '--quiet', 'cppy>=1.1.0']' returned non-zero exit status 1.
   ----------------------------------------
ERROR: Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.
Error response from daemon: The command '/bin/sh -c pip3 install matplotlib' returned a non-zero code: 1
Peter Kronenberg
  • 878
  • 10
  • 32
  • 1
    did you mean `RUN pip3 install ...`? – C.Nivs Jan 04 '21 at 20:20
  • This is probably not related to your issue, but I'm a bit curious to know why you are using an openjdk based image to install a python software. – Zeitounator Jan 04 '21 at 20:27
  • 1
    We're primarily running Java code. The python code we need is just a utility – Peter Kronenberg Jan 04 '21 at 20:28
  • You might have a point about PIP3 vs PIP. Tried it with PIP3 and got different errors – Peter Kronenberg Jan 04 '21 at 20:36
  • *The headers or library files could not be found for zlib* => `apk add zlib` – β.εηοιτ.βε Jan 04 '21 at 20:49
  • 1
    You are missing a lot of build deps apparently. I could go way further with `apk add gcc g++ zlib-dev make python3-dev && pip3 install wheel && pip3 install matplotlib`. But the hunt is not over, what I could identiy is that it is still missing (at least....) headers and libraries for numpy and jpeg. I don't have more time to spend. I'll let you continue (or someone else which passes by). – Zeitounator Jan 04 '21 at 20:56
  • 1
    Well I lied :D I actually spent some more minutes and was able to complete the install: `apk add gcc g++ zlib-dev make python3-dev py-numpy-dev jpeg-dev && pip3 install wheel && pip3 install matplotlib` This is in replacement of your last dockerfile line. All your other installation have to remain. – Zeitounator Jan 04 '21 at 21:10
  • 1
    And with all those dependancies pointed by @Zeitounator, you might want to read this question: https://stackoverflow.com/questions/46221063/what-is-build-deps-for-apk-add-virtual-command/46222036 – β.εηοιτ.βε Jan 04 '21 at 21:20
  • Thank you! That did it. I thought the whole point of using a package manager such as apk is that it handles all the dependencies for you. – Peter Kronenberg Jan 04 '21 at 21:24
  • 1
    @PeterKronenberg it handles the dependancies of another apk package, not of a pip package. – β.εηοιτ.βε Jan 04 '21 at 21:25

4 Answers4

4

Since I spent some time on it and since matplotlib is a dependency used for development, I still decided to push that as an answer integrating good practice pointed out by @β.εηοιτ.βε

As reported in my comments, you are missing quite a few dependencies to install matploblib from pip which will build on the go.

Here is a Dockerfile that will install matplotlib in a single image layer, kept as thin as possible by removing the build dependencies in the last step

FROM openjdk:8-jre-alpine

RUN apk add --no-cache tesseract-ocr python3 py3-numpy && \
    pip3 install --upgrade pip setuptools wheel && \
    apk add --no-cache --virtual .build-deps gcc g++ zlib-dev make python3-dev py-numpy-dev jpeg-dev && \
    pip3 install matplotlib && \
    apk del .build-deps
Zeitounator
  • 38,476
  • 7
  • 53
  • 66
  • Your solution works perfectly. But I had 1 other thing to install and I'm having a similar problem. Cannot figure how to tell what dependencies it's complaining about. I need to add scikit-image. I have tried all sorts of combinations and permutations. RUN apk add --no-cache tesseract-ocr python3 py3-numpy imagemagick && \ pip3 install --upgrade pip setuptools wheel && \ apk add --no-cache --virtual .build-deps gcc g++ zlib-dev make python3-dev py-numpy-dev jpeg-dev && \ pip3 install matplotlib && \ pip3 install scikit-image && \ apk del .build-deps – Peter Kronenberg Jan 05 '21 at 14:53
  • I'm not going into that hunt again. You basically have to do what I did: launch the command, browse the awfully long error messages, find the first that poped out, identify the lib/package/header dev file that is missing for the build, search the internet to find which alpine package it is related to, install that package, restart the install, verify it fixed that error, start the process over with the next error, until all errors are fixed. – Zeitounator Jan 05 '21 at 15:13
  • I appreciate it. I'm just trying to learn how to even figure out what it's complaining about. It certainly is not straight-forward – Peter Kronenberg Jan 05 '21 at 15:23
  • 1
    @PeterKronenberg as soon as you do have the file, this is quite straight forward you browse: https://pkgs.alpinelinux.org/contents, you fill in the missing file and you select the Alpine version you are using, then you install the right package. E.g. https://pkgs.alpinelinux.org/contents?file=libz.so&path=&name=&branch=v3.9 – β.εηοιτ.βε Jan 05 '21 at 17:48
  • I think you meant to post this in https://stackoverflow.com/questions/65525888/how-to-install-tesseract-ocr-4-1-1-on-alpine – Peter Kronenberg Jan 05 '21 at 21:10
2

I finally made matplotlib work under Alpine. I trigger the these two commands after Docker have started, from within Python

import os
os.system('''apk add g++ jpeg-dev zlib-dev libjpeg make''')
os.system("pip3 install matplotlib")

This takes 2-3min to build for me. To speed up the deploy time, I have added a manuell trigger to build it (don't need the matplotlib all the time)

Punnerud
  • 7,195
  • 2
  • 54
  • 44
0

After a long time searching and trying, Zeitounator's answer is NOT working under python:3.9-alpine, throwing exceptions as below: required by py-numpy-dev

And inspired by James Endicott's answer, to solve this case, you need to add more requirements packages:

apk --no-cache add musl-dev linux-headers g++

Combining their two conclusions:

pip install --upgrade pip setuptools wheel
apk add --no-cache --virtual .build-deps musl-dev linux-headers g++ gcc zlib-dev make python3-dev jpeg-dev
pip install matplotlib
apk del .build-deps

BTW, if NOT NECESSARY, using pyhon3:ubuntu is a much smartter choise. It takes too long time to build

ChowRex
  • 50
  • 6
0

In addition to the provided answers, matplotlib may also fail because alpine will not have all the necessary font files by default. In that case, be sure to add freetype too.

adam.hendry
  • 4,458
  • 5
  • 24
  • 51