【问题标题】:Cant create conda env in dockerfile无法在 dockerfile 中创建 conda env
【发布时间】:2017-10-11 19:19:18
【问题描述】:

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

我的 dockerfile 中有这个:

RUN conda env create
RUN source activate myenvfromymlfile

当我运行容器时,虽然 env 没有激活。如果我do 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 的 dockerfile 中看到这一点:

CMD [ "source activate your-environment && exec python application.py" ]

有人可以解释为什么必须使用 && 使其成为单个命令吗?为什么在 RUN 指令中运行“源激活”不起作用?我想让我的 dockerfile 看起来像这样:

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

【问题讨论】:

  • 我不是 dockerfiles 方面的专家,但我认为您正在寻找的内容在这里:docs.docker.com/engine/userguide/eng-image/multistage-build。请参阅标题为Before multi-stage builds 的段落
  • 这与我的问题无关。 “source activate myenvfromymlfile”需要使用 && 作为单个命令与“python application.py”一起运行,我不明白为什么
  • 关于“&& 使其成为单个命令”,每一层都会增加额外的开销,并且环境变量不会在层之间传递。
  • 您可以参考here获取该问题的详细解释。

标签: python docker anaconda conda


【解决方案1】:

考虑下面的 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"]

所以现在当你运行容器时。您在步骤#2 中所做的任何事情都不存在,因为启动了一个外壳程序来运行步骤#2,当它完成时外壳程序被关闭。现在,当您运行映像时,会启动一个新的 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”的入口点和 someApp.py 的 CMD 一样)。我怎样才能让这个 conda 容器以这种方式运行?
  • 你需要创建一个 shell 脚本并将其用作 ENTRYPOINT,因此任何 CMD 实际上都会作为 shell 脚本的参数,然后在脚本中你可以做任何你想做的事情
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-22
相关资源
最近更新 更多