51

In my docker file, I want to install med2image python package (https://github.com/FNNDSC/med2image). I use the following code:

FROM ubuntu:16.04
RUN apt-get update && apt-get install -y --no-install-recommends \
    python3.5 \
    python3-pip \
    && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
RUN pip install nibabel pydicom matplotlib pillow
RUN pip install med2image

But I get the following error when I want to build the image:

Downloading https://files.pythonhosted.org/packages/6f/e5/948b023c7feb72adf7dfb26d90a13c838737bbf52be704f5ddd0878e3264/med2image-1.1.2.tar.gz
Complete output from command python setup.py egg_info:
Sorry, only Python 3.5+ is supported.

----------------------------------------
Command "python setup.py egg_info" failed with error code 1 in  /tmp/pip-install-FnNb_S/med2image/
The command '/bin/sh -c pip install med2image' returned a non-zero code: 1

What should I do?!

user
  • 1,220
  • 1
  • 12
  • 31
Mehdi
  • 1,146
  • 1
  • 14
  • 27
  • 1
    Try adding the following to set python3 as default https://askubuntu.com/questions/320996/how-to-make-python-program-command-execute-python-3 (in particular the `update-alternatives` way) – Oleg Sklyar May 14 '18 at 15:33
  • 2
    I would suggest to use [that base image](https://store.docker.com/images/python) instead (`FROM python:3` aka `FROM python:3.6.5`) – ErikMD May 14 '18 at 21:06

4 Answers4

80

Recommended base image

As suggested in my comment, you could write a Dockerfile that looks like:

FROM python:3

RUN pip install --no-cache-dir --upgrade pip && \
    pip install --no-cache-dir nibabel pydicom matplotlib pillow med2image
    # Note: we had to merge the two "pip install" package lists here, otherwise
    # the last "pip install" command in the OP may break dependency resolution…

CMD ["cat", "/etc/os-release"]

And the command example above could confirm at runtime (docker build --pull -t test . && docker run --rm -it test) that this image is based on the GNU/Linux distribution "Debian stable".

Generic Dockerfile template

Finally to give a comprehensive answer, note that a good practice regarding Python dependencies consists in specifying them in a declarative way in a dedicated text file (in alphabetical order, to ease review and update) so that for your example, you may want to write the following file:

requirements.txt

matplotlib
med2image
nibabel
pillow
pydicom

and use the following generic Dockerfile

FROM python:3

WORKDIR /usr/src/app

COPY requirements.txt ./

RUN pip install --no-cache-dir --upgrade pip \
  && pip install --no-cache-dir -r requirements.txt

COPY . .

CMD ["python", "./your-daemon-or-script.py"]

To be more precise, this is the approach suggested in the documentation of the Docker official image python, §. How to use this image

ErikMD
  • 13,377
  • 3
  • 35
  • 71
  • When `RUN python -m pip install --upgrade pip` is used, then does it re-use the same layer or does it create new layer (so effectively use upgrade)? – variable May 14 '20 at 11:15
  • (maybe `python -m pip install --upgrade pip` is unneeded, but) I confirm that the 2 commands concatenated with a `&&` (`RUN pip install --upgrade pip && pip install --no-cache-dir -r requirements.txt`) do create a single layer. See also the SO question [Purpose of specifying several UNIX commands in a single RUN instruction in Dockerfile](https://stackoverflow.com/q/59535609/9164010) – ErikMD May 14 '20 at 11:33
  • prefere a single `pip install` command or you might break dependency resolution – Gaetan Sep 06 '22 at 09:17
  • @Gaetan I guess you talk about the`RUN` command, but can you be more specific? which exact command would you recommend? – ErikMD Sep 06 '22 at 11:27
  • BTW AFAICT, `pip` and dependency resolution is not very robust: (independently of this Docker context) I often stumbled on a `pip install` command that went through successfully, unlike a subsequent `pip check`… – ErikMD Sep 06 '22 at 11:28
  • Appart from the `pip install --no-cache-dir --upgrade pip` that needs to be in its own, you need to do pip install --no-cache-dir --upgrade nibabel pydicom matplotlib pillow med2image` for instance in a single command or the resolution on the second call of pip install might break something installed in the first (happened) – Gaetan Sep 07 '22 at 12:25
  • @Gaetan OK I see what you meant, thanks! Actually the code `pip install --no-cache-dir nibabel pydicom matplotlib pillow && pip install --no-cache-dir med2image` was not a recommendation of mine, it was directly taken from the OP's question… and I agree it's way better to merge the two package lists (as I suggest in the last generic template). I'll edit my answer anyway to make this clearer, thanks. – ErikMD Sep 07 '22 at 14:22
41

Some of the other answers/comments are suggesting to change your base image but if you want to keep your ubuntu 16.04 you can also simply specify your version of pip/python to use pip3 or pip3.5 like shown below.

FROM ubuntu:16.04

RUN apt-get update && apt-get install -y --no-install-recommends \
    python3.5 \
    python3-pip \
    && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/*

RUN pip3 install nibabel pydicom matplotlib pillow
RUN pip3 install med2image
Tummala Dhanvi
  • 3,007
  • 2
  • 19
  • 35
mgc
  • 5,223
  • 1
  • 24
  • 37
5

Try pip3

RUN pip3 install nibabel pydicom matplotlib pillow
RUN pip3 install med2image
d g
  • 1,594
  • 13
  • 13
3

If you have Jupyter Notebook in your docker container, you can install any python package by running a new Terminal in Jupyter by clicking the button shown here:

button for terminal

and running: pip install <package-name>

The package stays in the docker container even after you exit the container.

Sayyor Y
  • 1,130
  • 2
  • 14
  • 27