condas`source activate virtualenv`在Dockerfile中不起作用

时间:2016-06-21 13:25:43

标签: docker anaconda conda

方案

我试图根据公共continuumio/anaconda3容器设置一个简单的泊坞窗图片(我对码头工具来说很新,所以请纠正我可能的错误观念

Dockerfile

FROM continuumio/anaconda3:latest

# update conda and setup environment
RUN conda update conda -y \
    && conda env list \
    && conda create -n testenv pip -y \
    && source activate testenv \
    && conda env list

docker build -t test .的构建和图像以错误结束:

/bin/sh: 1: source: not found

激活新虚拟环境时。

建议1:

关注this answer我试过了:

FROM continuumio/anaconda3:latest

# update conda and setup environment
RUN conda update conda -y \
    && conda env list \
    && conda create -y -n testenv pip \
    && /bin/bash -c "source activate testenv" \
    && conda env list

这似乎首先起作用,因为它输出:prepending /opt/conda/envs/testenv/bin to PATH,但conda env list以及屁echo $PATH清楚地表明它没有:

[...]
# conda environments:
#
testenv                  /opt/conda/envs/testenv
root                  *  /opt/conda

---> 80a77e55a11f
Removing intermediate container 33982c006f94
Step 3 : RUN echo $PATH
---> Running in a30bb3706731
/opt/conda/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

docker文件作为MWE开箱即用。 我很欣赏任何想法。谢谢!

3 个答案:

答案 0 :(得分:6)

使用docker ENV指令可以将虚拟环境路径持久添加到PATH虽然这不能解决conda env list下列出的选定环境。

参见MWE:

FROM continuumio/anaconda3:latest

# update conda and setup environment
RUN conda update conda -y \
    && conda create -y -n testenv pip

ENV PATH /opt/conda/envs/testenv/bin:$PATH

RUN echo $PATH
RUN conda env list

答案 1 :(得分:1)

方法1:将SHELL与自定义入口点脚本一起使用

编辑:我已经开发了一种经过改进的方法,它比"conda", "run"语法更好。

Sample dockerfile available at this gist。它通过在exec节的参数进行RUN之前利用自定义的入口点脚本来设置环境。

这为什么起作用?

外壳程序(非常简单)是一个进程,可以充当任意程序的入口点。 exec "$@"允许我们启动一个新流程,继承父流程的所有环境。在这种情况下,这意味着我们激活conda(基本上会破坏大量环境变量),然后运行/bin/bash -c CONTENTS_OF_DOCKER_RUN


方法2:带参数的外壳

这是我以前的方法,受Itamar Turner-Trauring的礼貌;非常感谢他们!

# Create the environment:
COPY environment.yml .
RUN conda env create -f environment.yml

# Set the default docker build shell to run as the conda wrapped process
SHELL ["conda", "run", "-n", "vigilant_detect", "/bin/bash", "-c"]

# Set your entrypoint to use the conda environment as well
ENTRYPOINT ["conda", "run", "-n", "myenv", "python", "run.py"]

修改ENV可能不是最好的方法,因为conda喜欢控制环境变量本身。此外,您的自定义conda env可能会激活其他脚本来进一步调节环境。

为什么行得通?

在启动新的bash shell之前,这利用conda run来“将条目添加到环境的PATH并运行该环境可能包含的所有激活脚本”。

使用conda可能会令人沮丧,因为这两个工具都有效地希望垄断环境,并且从理论上讲,您永远不需要容器内的conda。但是截止日期和技术债务是一件事情,有时您只是必须完成,有时conda是配置依赖项的最简单方法(在您看来,GDAL)。

答案 2 :(得分:0)

抄袭ccauet的答案(我无法开始工作),以及Charles Duffey关于其中的更多内容而不只是PATH的评论,以下是解决问题的方法。

激活环境时,conda会设置以下变量,以及一些在停用环境时可以引用的备份默认值。这些变量已从Dockerfile中省略,因为根conda环境不需要再次使用。作为参考,这些是CONDA_PATH_BACKUPCONDA_PS1_BACKUP_CONDA_SET_PROJ_LIB。它还设置PS1以便在终端提示行的左侧显示(testenv),这也被省略。以下陈述将满足您的需求。

ENV PATH /opt/conda/envs/testenv/bin:$PATH
ENV CONDA_DEFAULT_ENV testenv
ENV CONDA_PREFIX /opt/conda/envs/testenv

为了缩小创建的图层数量,您可以将这些命令组合到一个ENV命令中,同时设置所有变量。

根据包装,可能还需要设置其他一些变量。例如,

ENV GDAL_DATA /opt/conda/envs/testenv/share/gdal
ENV CPL_ZIP_ENCODING UTF-8
ENV PROJ_LIB /opt/conda/envs/testenv/share/proj

获取此信息的简便方法是在根环境中调用printenv > root_env.txt,激活testenv,然后调用printenv > test_env.txt,然后检查 diff root_env.txt test_env.txt