在构建过程中,在Docker文件中激活并切换Anaconda环境

23 人关注

我尝试了好几个小时,都不知道如何在构建过程中在Docker文件中激活和切换Anaconda环境。

这里是最初的代码。

FROM nvidia/cuda:10.1-cudnn7-devel-ubuntu16.04
# Set user
ENV SETUSER myuser
RUN useradd -m $SETUSER
USER $SETUSER
WORKDIR /home/$SETUSER
# Install Anaconda
RUN wget https://repo.anaconda.com/archive/Anaconda3-2019.03-Linux-x86_64.sh
RUN bash Anaconda3-2019.03-Linux-x86_64.sh -b
RUN rm Anaconda3-2019.03-Linux-x86_64.sh
# Set path to conda
ENV CONDA_ENV_NAME mynewenv
RUN /home/$SETUSER/anaconda3/condabin/conda create -q --name $CONDA_ENV_NAME python=3.6 && \
    /home/$SETUSER/anaconda3/condabin/conda clean --yes --all
RUN /home/$SETUSER/anaconda3/condabin/conda activate base #Just for testing anaconda environment

起初,Docker中的Anaconda会抱怨shell没有设置好,所以在conda创建命令后我加入了。

RUN /home/$SETUSER/anaconda3/condabin/conda init bash
RUN /bin/bash -c "source /home/$SETUSER/.bashrc"
RUN /home/$SETUSER/anaconda3/condabin/conda activate base

在构建docker镜像后运行这3条命令可以工作(即在调用docker run container-name后交互运行),但由于某些原因,在以下情况下不能工作building容器。我发现$PATH变量在构建过程中没有被更新,所以在构建时和构建后比较了我的$PATH。

ENV PATH /home/$SETUSER/anaconda3/envs/$CONDA_ENV_NAME/bin:$PATH
ENV PATH /home/$SETUSER/anaconda3/condabin:$PATH
ENV PATH /home/$SETUSER/anaconda3/bin:$PATH
RUN conda init bash
RUN /bin/bash -c "source /home/$SETUSER/.bashrc"
RUN conda activate base

现在,构建时的Docker $PATH和构建后运行容器时交互式修改的$PATH是一样的,但我仍然得到shell没有正确设置的错误。

CommandNotFoundError。你的shell没有被正确配置为使用'conda activate'。 要初始化你的外壳,请运行 $ conda init 目前支持的shell是 - bash - fish - tcsh - xonsh - zsh - 权力的象征 参见'conda init --help'获取更多信息和选项。 重要的是:你可能需要在运行'conda init'后关闭并重新启动你的shell。

Why is this not working???

我看到可能有使用miniconda docker模板的变通办法,但我不能用。我如何在Docker构建过程中创建和切换Anaconda环境?谢谢!

5 个评论
通常在Docker中,你不需要像Conda这样的工具,可以管理多个并发的隔离软件安装。Docker本身提供了这种隔离。 对于Python包,只需在你的Docker文件中运行 pip install ,将东西安装到 "系统 "Python中(与你正在构建的镜像隔离)。
xnet
这一切都很好,但我需要运行一个特定版本的python。所以我需要创建一个新的Anaconda环境来实现这一点。
你有没有试过把这个 RUN conda activate base 改为 RUN bash -c "conda activate base"
Zhe
@DavidMaze 有些软件包只通过Anaconda发布,在PyPI上没有提供。
python
anaconda
dockerfile
miniconda
xnet
xnet
发布于 2019-06-09
4 个回答
Roland Weber
Roland Weber
发布于 2022-09-22
已采纳
0 人赞同

你的Docker文件里有太多的RUN命令。这不只是因为每个RUN都会在镜像中创建一个新的层。还因为每个RUN命令都会启动一个新的shell,而 conda activate 只适用于当前的shell。

你应该把逻辑上的行动组合并成一条RUN命令。使用 && 来合并命令,使用 \ 来断行,以便于阅读。

RUN conda activate <myenv> \
 && conda install <whatever> \

请记住:在RUN命令结束后,shell就会消失。因此,如果你想在之后对conda环境做一些其他事情,你必须再次运行conda activate,或者使用-n <myenv>把一些东西放到环境中,而不先激活它。

当你从图像中启动一个容器时,你也将不得不在容器内调用conda activate

Asclepius
Asclepius
发布于 2022-09-22
0 人赞同

假设你想安装conda环境并在其中运行一些东西,这种方法使用了 ENV PATH 来间接地在conda环境中启动python。人们可能会怀疑这种方法是否真的激活了环境,但只要随后的命令能起作用,而且确实能起作用,这可能就不重要了。

FROM continuumio/miniconda3:latest
WORKDIR myappdir
COPY environment.yml .
RUN set -x && \
#   apt-get update && apt-get -y install gcc && \
    conda install -n base -c defaults conda=4.* && \
    conda env create -n condaenv  # Installs environment.yml && \
    conda clean -a
COPY myapppkg myapppkg
ENV PATH /opt/conda/envs/condaenv/bin:$PATH
ENTRYPOINT ["python", "-m", "myapppkg"]

我建议不要使用conda run,因为它是实验性的,有很多严重的错误,如this one影响它。虽然这个特定的错误现在已经被修复,但正如conda run -h所显示的那样,它继续具有 "实验 "性质,这意味着它可能再次破坏上游,限制了人们对它的信任。

For reference:

  • List of Miniconda Docker tags
  • List of conda updates by channel: defaults, conda-forge
  • NumesSanguis
    NumesSanguis
    发布于 2022-09-22
    0 人赞同

    我还没有用nvidia图像进行测试,但是 多阶段的Docker构建 应该可以帮助你,它可能会看起来像这样。

    # get Miniconda docker image to get a installed conda env; WARNING: That image is Debian based
    FROM continuumio/miniconda3:latest AS miniconda
    # your Docker commands
    FROM nvidia/cuda:10.1-cudnn7-devel-ubuntu16.04
    # Set user
    ENV SETUSER myuser
    RUN useradd -m $SETUSER
    USER $SETUSER
    WORKDIR /home/$SETUSER
    # Miniconda: get necessary files from build
    COPY --from=miniconda /opt/conda /opt/conda
    # Set correct permissions
    RUN chown -R $SETUSER: /opt/conda
    #   New terminals will have conda active
    # If nvidia's Docker image has no .bashrc
    # COPY --from=miniconda /home/$SETUSER/.bashrc
    # else
    RUN echo ". /opt/conda/etc/profile.d/conda.sh" >> ~/.bashrc && \
        echo "conda activate base" >> ~/.bashrc
    # switch shell sh (default in Linux) to bash
    SHELL ["/bin/bash", "-c"]
    # give bash access to Anaconda, then normal anaconda commands, e.g. (-q: quiet, -y: answer yes)
    RUN source /home/$SETUSER/.bashrc \
     && conda create -q --name testy \
     && conda activate testy \
     && conda install -y your_package
    

    从这个GitHub问题中得到启发。https://github.com/ContinuumIO/docker-images/issues/89

    Rm4n
    Rm4n
    发布于 2022-09-22
    0 人赞同

    在尝试了所有的解决方案之后,最后对我有用的是在创建conda环境之后,在调用 conda activate 之前,将conda脚本源化。下面是我的Docker文件的摘录,我创建了三个不同的conda环境,我想在每个环境中安装 pip

    RUN bash miniconda.sh -b -p /opt/conda
    RUN source /opt/conda/etc/profile.d/conda.sh && conda init bash
    RUN source /opt/conda/etc/profile.d/conda.sh && \
        conda create --name py37 python=3.7 -y && source /opt/conda/etc/profile.d/conda.sh && \
        conda activate py37 && conda install -c anaconda pip -y && \
        conda create --name py38 python=3.8 -y && source /opt/conda/etc/profile.d/conda.sh && \