无法在Dockerfile中创建conda环境

5

我在应用程序文件夹中有一个environment.yml

我在我的Dockerfile里面有这样的内容:

RUN conda env create
RUN source activate myenvfromymlfile

当我运行容器时,环境没有被激活。如果我执行 conda env list 命令,我看到 /opt/conda 被激活:

root@9c7181cf86aa:/app# conda env list
# conda environments:
#
myenvfromymlfile         /opt/conda/envs/myenvfromymlfile
root                  *  /opt/conda

如果我连接到容器,就可以手动运行source activate myenvfromymlfile ,它可以正常工作,但为什么在RUN指令中不起作用呢?
在需要conda的dockerfiles示例中,我经常看到这种情况。
CMD [ "source activate your-environment && exec python application.py" ]

请问为什么需要使用 && 将它们组合成一个单一的命令?为什么在 RUN 指令中运行 "source activate" 无法工作?我希望我的 Dockerfile 看起来像这样:

RUN conda env create
RUN source activate myenvfromymlfile
ENTRYPOINT ["python"]
CMD ["application.py"]

我不是Dockerfile的专家,但我认为你要找的在这里:https://docs.docker.com/engine/userguide/eng-image/multistage-build/。请查看标题为“多阶段构建之前”的段落。 - J'e
这与我的问题无关。"source activate myenvfromymlfile"需要与"python application.py"一起使用&&作为单个命令运行,才能正常工作,我不明白为什么。 - red888
关于“&& 使其成为单个命令”,每个层都会增加额外的开销,并且环境变量不会在层之间传递。 - J'e
您可以在此处参考详细的问题解释:https://stackoverflow.com/q/67059518/6503329 - Shreyesh Desai
1个回答

5
考虑以下Dockerfile:
RUN conda env create
RUN source activate myenvfromymlfile
ENTRYPOINT ["python"]
CMD ["application.py"]

语句 #1 conda env create:创建环境并将更改文件保存在磁盘上。

语句 #2 source activate myenvfromymlfile:在bash会话中加载一些内容,这里不会对磁盘进行更改。

语句 #3 和 #4 指定了运行容器时会发生什么事情。

ENTRYPOINT ["python"]
CMD ["application.py"]

现在当您运行容器时,第二步中所做的任何事情都不会存在,因为启动了一个 shell 来运行第二步,当它完成后 shell 就关闭了。现在当您运行镜像时,将启动一个新的 shell,并且是全新的 shell,不知道过去在您的 Dockerfile 中运行了 source activate myenvfromymlfile
现在您想在创建的环境中运行此 application.py。Docker 的默认 shell 是 sh -c。因此,当您设置以下命令 CMD 时:
CMD [ "source activate your-environment && exec python application.py" ]

容器启动时执行的最后一个命令是
sh -c "source activate your-environment && exec python application.py"

该命令会激活当前shell环境,然后运行你的程序。


这很有道理,我以为所有运行命令都是同一个会话,但事实并非如此!这有点糟糕,因为我真的想要一个通用的镜像,可以执行任何你传递给它的 Python 应用程序(就像使用 "python" 的 ENTRYPOINT 和一些应用程序的 CMD 一样)。我该如何让这个 conda 容器表现出这种方式? - red888
1
你需要编写一个shell脚本,并将其用作ENTRYPOINT,这样任何CMD实际上都作为参数传递给shell脚本,然后在脚本中可以执行任何操作。 - Tarun Lalwani

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接