Search code examples
pythondockerdockerfilecondaminiconda

No module named conda in Docker


I am trying to create a docker image with miniconda3 intalled. Instead of using directly the base image offered in docker hub, I want to start from scratch by creating my own Dockerfile and putting there the commands of the Dockerfile of the continuumio/miniconda3 image, which are:

FROM debian:latest

#  $ docker build . -t continuumio/miniconda3:latest -t continuumio/miniconda3:4.5.11
#  $ docker run --rm -it continuumio/miniconda3:latest /bin/bash
#  $ docker push continuumio/miniconda3:latest
#  $ docker push continuumio/miniconda3:4.5.11

ENV LANG=C.UTF-8 LC_ALL=C.UTF-8
ENV PATH /opt/conda/bin:$PATH

RUN apt-get update --fix-missing && \
    apt-get install -y wget bzip2 ca-certificates curl git && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/*

RUN wget --quiet https://repo.anaconda.com/miniconda/Miniconda3-4.5.11-Linux-x86_64.sh -O ~/miniconda.sh && \
    /bin/bash ~/miniconda.sh -b -p /opt/conda && \
    rm ~/miniconda.sh && \
    /opt/conda/bin/conda clean -tipsy && \
    ln -s /opt/conda/etc/profile.d/conda.sh /etc/profile.d/conda.sh && \
    echo ". /opt/conda/etc/profile.d/conda.sh" >> ~/.bashrc && \
    echo "conda activate base" >> ~/.bashrc

ENV TINI_VERSION v0.16.1
ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /usr/bin/tini
RUN chmod +x /usr/bin/tini

ENTRYPOINT [ "/usr/bin/tini", "--" ]
CMD [ "/bin/bash" ]

Building and running the container works just fine. For reference, here is the output of conda info in the container:

(base) root@def48bd1ed5d:/# conda info

     active environment : base
    active env location : /opt/conda
            shell level : 1
       user config file : /root/.condarc
 populated config files : 
          conda version : 4.5.11
    conda-build version : not installed
         python version : 3.7.0.final.0
       base environment : /opt/conda  (writable)
           channel URLs : https://repo.anaconda.com/pkgs/main/linux-64
                          https://repo.anaconda.com/pkgs/main/noarch
                          https://repo.anaconda.com/pkgs/free/linux-64
                          https://repo.anaconda.com/pkgs/free/noarch
                          https://repo.anaconda.com/pkgs/r/linux-64
                          https://repo.anaconda.com/pkgs/r/noarch
                          https://repo.anaconda.com/pkgs/pro/linux-64
                          https://repo.anaconda.com/pkgs/pro/noarch
          package cache : /opt/conda/pkgs
                          /root/.conda/pkgs
       envs directories : /opt/conda/envs
                          /root/.conda/envs
               platform : linux-64
             user-agent : conda/4.5.11 requests/2.19.1 CPython/3.7.0 Linux/4.4.0-187-generic debian/10 glibc/2.28
                UID:GID : 0:0
             netrc file : None
           offline mode : False

The problem appears whenever I try to use conda to install a module, for example conda install jupyter -y. The process starts and at some point during the installation I get this error:

Preparing transaction: done
Verifying transaction: done
Executing transaction: done
Traceback (most recent call last):
  File "/opt/conda/bin/conda", line 7, in <module>
    from conda.cli import main
ModuleNotFoundError: No module named 'conda'
(base) root@def48bd1ed5d:/# 

After this, it seems the installation is corrupeted. If I try to use the conda command to call for exmaple conda info again, I get the same error:

(base) root@def48bd1ed5d:/# conda info
Traceback (most recent call last):
  File "/opt/conda/bin/conda", line 7, in <module>
    from conda.cli import main
ModuleNotFoundError: No module named 'conda'
(base) root@def48bd1ed5d:/# 

Solution

  • miniconda3 version specified in installation line inside the Dockerfile is the not the latest one

    That Dockerfile that you used to build local image will install miniconda3-4.5.11 not the latest version. You can find it here:

    ...
    RUN wget --quiet https://repo.anaconda.com/miniconda/Miniconda3-4.5.11-Linux-x86_64.sh -O ~/miniconda.sh && \
        /bin/bash ~/miniconda.sh -b -p /opt/conda &&
    ...
    

    And also in this way with docker:

    $ docker build --tag miniconda3:test .
    $ docker docker run -i -t miniconda3:test /bin/bash
    $ docker history --no-trunc miniconda3:test | grep Miniconda3
    
    /bin/sh -c wget --quiet https://repo.anaconda.com/miniconda/Miniconda3-4.5.11-Linux-x86_64.sh -O ~/miniconda.sh && ...
    

    Ok, now let's look at official continuumio/miniconda3:

    $ docker run -i -t continuumio/miniconda3 /bin/bash
    

    and then:

    $ docker history --no-trunc continuumio/miniconda3 | grep Miniconda3
    
    /bin/sh -c wget --quiet https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh -O ~/miniconda.sh && ...
    

    As you can see continuumio/miniconda3 image from DockerHub installs latest miniconda3 4.8.2 and not the 4.5.11 version. Thus, your local image built from that Dockerfile will produce container with miniconda3:4.5.11.

    Change in python version breaks conda

    Now, let's figure out why conda fails. First build and run:

    $ docker build --tag miniconda3:test .
    $ docker docker run -i -t miniconda3:test /bin/bash
    

    Get some info:

    (base) root@61cafd17d954:/# conda info
    
         active environment : base
        active env location : /opt/conda
                shell level : 1
           user config file : /root/.condarc
     populated config files : 
              conda version : 4.5.11
        conda-build version : not installed
             python version : 3.7.0.final.0
           base environment : /opt/conda  (writable)
               channel URLs : https://repo.anaconda.com/pkgs/main/linux-64
                              https://repo.anaconda.com/pkgs/main/noarch
                              https://repo.anaconda.com/pkgs/free/linux-64
                              https://repo.anaconda.com/pkgs/free/noarch
                              https://repo.anaconda.com/pkgs/r/linux-64
                              https://repo.anaconda.com/pkgs/r/noarch
                              https://repo.anaconda.com/pkgs/pro/linux-64
                              https://repo.anaconda.com/pkgs/pro/noarch
              package cache : /opt/conda/pkgs
                              /root/.conda/pkgs
           envs directories : /opt/conda/envs
                              /root/.conda/envs
                   platform : linux-64
                 user-agent : conda/4.5.11 requests/2.19.1 CPython/3.7.0 Linux/5.4.0-48-generic debian/10 glibc/2.28
                    UID:GID : 0:0
                 netrc file : None
               offline mode : False
    

    Well, we have conda:4.5.11 with python:3.7.0.

    Now, we are going to install jupyter, for example:

    (base) root@61cafd17d954:/# conda install jupyter
    

    You may notice, that this installation will update python:

    The following packages will be UPDATED:
    
    ...
        python:             3.7.0-hc3d631a_0        --> 3.8.5-h7579374_1       
    ...
    

    If you proceed, this will update python and will break conda:

    ...
    Preparing transaction: done
    Verifying transaction: done
    Executing transaction: done
    Traceback (most recent call last):
      File "/opt/conda/bin/conda", line 7, in <module>
        from conda.cli import main
    ModuleNotFoundError: No module named 'conda'
    

    This is quite known issue and you can find more info on this issue in How does using conda to install a package change my python version and remove conda? answer, and in official conda repo: No module named conda.cli.main #2463.

    Update conda or use Dockerfile for the miniconda3:latest

    There are 3 possible solutions to this issue:

    1. Edit your Dockerfile by replacing this line:
    RUN wget --quiet https://repo.anaconda.com/miniconda/Miniconda3-4.5.11-Linux-x86_64.sh -O ~/miniconda.sh && \
    

    with

    RUN wget --quiet https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh -O ~/miniconda.sh && \
    
    1. Use the latest official Dockerfile from ContinuumIO, you can find it here.

    2. Update conda inside container before usage:

    (base) root@61cafd17d954:/# conda update conda