Unable to install PyMuPDF on alpine docker image

Viewed 3140

I am trying to install pymupdf package on apline image but getting below error

fitz/fitz_wrap.c:2739:10: fatal error: ft2build.h: No such file or directory
     2739 | #include <ft2build.h>
          |          ^~~~~~~~~~~~
    compilation terminated.
    error: command 'gcc' failed with exit status 1
 RUN pip install PyMuPDF
 ---> Running in 34d246d6f01b
Collecting PyMuPDF
  Downloading PyMuPDF-1.18.5.tar.gz (251 kB)
Using legacy 'setup.py install' for PyMuPDF, since package 'wheel' is not installed.
Installing collected packages: PyMuPDF
    Running setup.py install for PyMuPDF: started
    Running setup.py install for PyMuPDF: finished with status 'error'
    ERROR: Command errored out with exit status 1:
     command: /usr/bin/python3.8 -u -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-uxc_zm2j/pymupdf/setup.py'"'"'; __file__='"'"'/tmp/pip-install-uxc_zm2j/pymupdf/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' install --record /tmp/pip-record-nipvlcn8/install-record.txt --single-version-externally-managed --compile --install-headers /usr/include/python3.8/PyMuPDF
         cwd: /tmp/pip-install-uxc_zm2j/pymupdf/
    Complete output (20 lines):
    running install
    running build
    running build_py
    creating build
    creating build/lib.linux-x86_64-3.8
    creating build/lib.linux-x86_64-3.8/fitz
    copying fitz/__init__.py -> build/lib.linux-x86_64-3.8/fitz
    copying fitz/fitz.py -> build/lib.linux-x86_64-3.8/fitz
    copying fitz/utils.py -> build/lib.linux-x86_64-3.8/fitz
    copying fitz/__main__.py -> build/lib.linux-x86_64-3.8/fitz
    running build_ext
    building 'fitz._fitz' extension
    creating build/temp.linux-x86_64-3.8
    creating build/temp.linux-x86_64-3.8/fitz
    gcc -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -Os -fomit-frame-pointer -g -Os -fomit-frame-pointer -g -Os -fomit-frame-pointer -g -DTHREAD_STACK_SIZE=0x100000 -fPIC -I/usr/include/mupdf -I/usr/local/include/mupdf -Imupdf/thirdparty/freetype/include -I/usr/include/python3.8 -c fitz/fitz_wrap.c -o build/temp.linux-x86_64-3.8/fitz/fitz_wrap.o
    fitz/fitz_wrap.c:2739:10: fatal error: ft2build.h: No such file or directory
     2739 | #include <ft2build.h>
          |          ^~~~~~~~~~~~
    compilation terminated.
    error: command 'gcc' failed with exit status 1
    ----------------------------------------
ERROR: Command errored out with exit status 1: /usr/bin/python3.8 -u -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-uxc_zm2j/pymupdf/setup.py'"'"'; __file__='"'"'/tmp/pip-install-uxc_zm2j/pymupdf/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' install --record /tmp/pip-record-nipvlcn8/install-record.txt --single-version-externally-managed --compile --install-headers /usr/include/python3.8/PyMuPDF Check the logs for full command output.
WARNING: You are using pip version 20.2.4; however, version 20.3.3 is available.
You should consider upgrading via the '/usr/bin/python3.8 -m pip install --upgrade pip' command.
The command '/bin/sh -c pip install PyMuPDF' returned a non-zero code: 1
5 Answers

freetype-dev in Alpine will be installed in /usr/include/freetype2. You can link headers and directories to /usr/include apk add mupdf-dev installed mupdf with a method structure inconsistent with that of pymupdf,So you need to compile the mupdf library from source code.

FROM python:3.8-alpine
RUN apk add gcc g++ cmake make mupdf-dev freetype-dev
ARG MUPDF=1.18.0
RUN ln -s /usr/include/freetype2/ft2build.h /usr/include/ft2build.h \
    && ln -s /usr/include/freetype2/freetype/ /usr/include/freetype \
    && wget -c -q https://www.mupdf.com/downloads/archive/mupdf-${MUPDF}-source.tar.gz \
    && tar xf mupdf-${MUPDF}-source.tar.gz \
    && cd mupdf-${MUPDF}-source \
    && make HAVE_X11=no HAVE_GLUT=no shared=yes prefix=/usr/local install \
    && cd .. \
    && rm -rf *.tar.gz mupdf-${MUPDF}-source
RUN pip install PyMuPDF==1.18.9

Try this , it works

Also, Alpine's official Mupdf library has been updated to make installation easier.(Updated at 2021-04-28) enter image description here

FROM python:3.8-alpine
# Add temporary virtual environment dependencies
RUN apk --no-cache add --virtual .builddeps gcc g++

# These dependency packages cannot be removed because they continue to be used in PyMupdf
RUN apk --no-cache add  mupdf-dev freetype-dev jbig2dec-dev jpeg-dev openjpeg-dev 

# install PyMupdf
RUN pip install pymupdf

# Remove virtual environment dependencies
RUN apk del .builddeps

For those kind of errors there are simple steps to take:

  1. Read the error and identify the missing file, you have done it already, you seems to be missing ft2build.h
  2. Go the the Alpine package website and browse the Contents tab
  3. In the field File type in the name of the file you are missing; in Branch, select your Alpine version and in Repository select main
  4. This will point you at a sepcific package, just install it via apk in your Dockerfile and you should be good to go

In your case, this is the result of such a search on Alpine version 3.12: Alpine contents search

So you issue can be fixed adding in the existing apk command the package freetype-dev

RUN apk add --no-cache \
      freetype-dev

Try to update pip first with pip install -U pip.

Here is a deep dive into the problem https://github.com/pymupdf/PyMuPDF/issues/894 there an old pip that get source from tar.gz file rather than .whl and the build has been failed because of wrong INCLUDE dir for freetype2 which is workarounded since PyMuPDF 1.18.2 but... Pypi has outdated source tar.gz.

The problem is that there is no wheel on PyPI for the envrionment established by the docker file. In such cases, pip tries to create PyMuPDF from sources. Because PyMuPDF is a binding for MuPDF, this in turn is bound to fail, when there is no MuPDF installation ... like here. The solution therefore is to

  • either install MuPDF before installing PyMuPDF
  • or use one of the OS / Python combinations for which there is a wheel.

this work for me, and only work with python:3.8.10 or greater and with Pymupdf:1.18.14:

1). Only if you don't have python installed:
apk add --update py-pip

2). Install dependencies:

apk add --no-cache \
python3-dev \
mupdf-dev \
gcc \
libc-dev \
musl-dev \
jbig2dec \
openjpeg-dev \
jpeg-dev \
harfbuzz-dev

3). Create Shortcut:
ln -s /usr/lib/libjbig2dec.so.0 /usr/lib/libjbig2dec.so

4). install PymuPdf:
pip install pymupdf

only if you want do at same time:

apk add --update py-pip \
&& apk add --no-cache \
python3-dev \
mupdf-dev \
gcc \
libc-dev \
musl-dev \
jbig2dec \
openjpeg-dev \
jpeg-dev \
harfbuzz-dev \
&& ln -s /usr/lib/libjbig2dec.so.0 /usr/lib/libjbig2dec.so \
&& pip install pymupdf
Related