在 docker 中激活 conda 环境

Yah*_*ger 29 python docker anaconda conda

我需要在 docker 中激活环境并在此环境中运行命令。我创建了环境,但随后我尝试激活此环境并以这种方式运行命令:

CMD [ "source activate mro_env && ipython kernel install --user --name=mro_env" ]
Run Code Online (Sandbox Code Playgroud)

但是当我运行 docker 时出现错误:

[FATAL tini (8)] exec source activate mro_env && ipython kernel install 
--user --name=mro_env failed: No such file or directory
Run Code Online (Sandbox Code Playgroud)

这是整个 Dockerfile:

FROM continuumio/miniconda3

ADD /src/mro_env.yml /src/mro_env.yml
RUN conda env create -f /src/mro_env.yml

# Pull the environment name out of the mro_env.yml
RUN echo "source activate $(head -1 /src/mro_env.yml | cut -d' ' -f2)" > ~/.bashrc
ENV PATH /opt/conda/envs/$(head -1 /src/mro_env.yml | cut -d' ' -f2)/bin:$PATH

CMD [ "source activate mro_env && ipython kernel install --user --name=mro_env" ]
Run Code Online (Sandbox Code Playgroud)

chA*_*xey 19

对我来说,这里介绍的解决方案工作顺利:

FROM continuumio/miniconda3
RUN conda create -n {env} python=3.6
RUN echo "source activate {env}" > ~/.bashrc
ENV PATH /opt/conda/envs/{env}/bin:$PATH
Run Code Online (Sandbox Code Playgroud)

UPD:“env”只是一个示例,如果需要,请调整“env”名称。


Sad*_*ven 18

按照本教程进行操作,它奏效了。示例 Dockerfile:

FROM continuumio/miniconda
WORKDIR /usr/src/app
COPY ./ ./
RUN conda env create -f environment.yml

# Make RUN commands use the new environment:
SHELL ["conda", "run", "-n", "myenv", "/bin/bash", "-c"]

EXPOSE 5003
# The code to run when container is started:
ENTRYPOINT ["conda", "run", "-n", "myenv", "python3", "src/server.py"]
Run Code Online (Sandbox Code Playgroud)

更新:

如果您使用 4.9 版本的 conda,则可以使用“conda run --no-capture-output”来不缓冲 IO。更新的 Dockerfile:

FROM continuumio/miniconda
WORKDIR /usr/src/app
COPY ./ ./
RUN conda env create -f environment.yml

# Make RUN commands use the new environment:
SHELL ["conda", "run", "--no-capture-output", "-n", "myenv", "/bin/bash", "-c"]

EXPOSE 5003
# The code to run when container is started:
ENTRYPOINT ["conda", "run", "--no-capture-output", "-n", "myenv", "python3", "src/server.py"]
Run Code Online (Sandbox Code Playgroud)

  • 您在这里提到的教程(以及整个网站)值得花每一分钟来阅读。谢谢。 (4认同)
  • SHELL 命令不起作用,并使我的代码的其余部分认为它在引号中 (3认同)
  • 最后我知道,“conda run”会缓冲所有标准输出/错误,直到该过程完成,因此这不是通过标准 I/O 进行交互的应用程序的选项。我想它仍然可以运行服务器,但不要指望在运行时监视任何 stderr 消息。此外,该“教程”也有问题,就像第一个示例一样,它只是失败了,因为作者没有在一次运行中正确链接他们的命令(即使用“&&”),并且当[基本映像]时不必要地运行“conda init” ](https://hub.docker.com/r/continuumio/miniconda3/dockerfile) 已经完成了该设置。 (2认同)
  • @merv如果你使用4.9版本的conda,你可以使用“conda run --no-capture-output”来不缓冲IO (2认同)

Cia*_*lsh 11

对我来说,问题是安装后在 docker 内运行命令conda activate env导致 conda 要求我使用该conda init bash命令。但是,此命令要求您重新启动 shell,我们不想在 docker 内执行此操作。因此,解决方案是认识到要求conda您重新启动 shell 的原因是因为它已修改并想要重新加载~/.bashrc. 我们可以手动执行此操作,并且无需使用以下命令重新启动 shell:

. ~/.bashrc
Run Code Online (Sandbox Code Playgroud)

对于那些需要它的人来说,这是完整的 dockerfile:

FROM ubuntu:18.04
# update apt and get miniconda
RUN apt-get update \
    && apt-get install -y wget \
    && wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh


# install miniconda
ENV PATH="/root/miniconda3/bin:$PATH"
RUN mkdir /root/.conda && bash Miniconda3-latest-Linux-x86_64.sh -b

# create conda environment
RUN conda init bash \
    && . ~/.bashrc \
    && conda create --name test-env python=3.7 \
    && conda activate test-env \
    && pip install ipython

Run Code Online (Sandbox Code Playgroud)

编辑-处理评论

评论者是正确的,因为上面的示例不适用于在 docker 中切换 conda 环境。最近,我发现要使其正常工作,您应该RUNconda init bash && .~/.bashrc && conda activate env.

这是另一个例子:


FROM quay.io/pypa/manylinux2014_x86_64

RUN yum install -y wget
RUN wget https://repo.anaconda.com/miniconda/Miniconda3-py39_4.9.2-Linux-x86_64.sh
RUN bash Miniconda3-py39_4.9.2-Linux-x86_64.sh -b -p /Miniconda3

RUN /Miniconda3/bin/conda create -y --name py37 python=3.7 pytest
RUN /Miniconda3/bin/conda create -y --name py38 python=3.8 pytest
RUN /Miniconda3/bin/conda create -y --name py39 python=3.9 pytest

RUN /Miniconda3/bin/conda init && bash ~/.bashrc && . ~/.bashrc

ENV conda /Miniconda3/bin/conda
ENV bashrc /root/.bashrc

# install numpy in each env
RUN $conda init && . $bashrc && conda activate py37 && pip install numpy 
RUN $conda init && . $bashrc && conda activate py38 && pip install numpy
RUN $conda init && . $bashrc && conda activate py39 && pip install numpy

Run Code Online (Sandbox Code Playgroud)


Ser*_*e K 7

您可以设置 CONDA_DEFAULT_ENV

像这样:

FROM continuumio/miniconda3

ARG conda_env=mro_env

ADD /src/environment.yml /src/environment.yml
RUN conda env create -f /src/environment.yml

ENV PATH /opt/conda/envs/$conda_env/bin:$PATH
ENV CONDA_DEFAULT_ENV $conda_env

CMD [ "python", "test.py" ]

Run Code Online (Sandbox Code Playgroud)

更新:

更好地使用激活。为我工作:

FROM continuumio/miniconda3

ADD /src/environment.yml /src/environment.yml

RUN conda env create -f /src/environment.yml
ENV PATH /opt/conda/envs/mro_env/bin:$PATH
RUN /bin/bash -c "source activate mro_env"

CMD [ "python", "test.py" ]
Run Code Online (Sandbox Code Playgroud)

  • 指定 `/bin/bash -c "source activate mro_env"` 似乎完全没有意义,因为后面的 `ENTRYPOINT` 和/或 `CMD` 的活动 shell 不是 `bash`;显然是“sh”。设置“CONDA_DEFAULT_ENV”似乎也同样毫无意义。在这两种情况下,真正的工作都是由“ENV PATH”完成的。 (4认同)
  • 我的问题是在这种环境下启动 jupyter。您知道如何在 jupyter 上安装环境并随环境启动它吗? (2认同)

小智 5

As the user merv points out in one of the comments above (sorry don't have enough rep to vote up the comment) conda run buffers all stdout/stderr, thus making it not workable for applications interacting or even just displaying logs over I/O.

I noticed there was no accepted answer, so I just post what has worked very well for me:

You can use an entrypoint script to activate the conda enviroment and let it take over further input from the Dockerfile such that the python script can be executed within the activated conda environment

Example Dockerfile:

FROM continuumio/miniconda3

# make docker use bash instead of sh
SHELL ["/bin/bash", "--login", "-c"]

# copy all necessary files
COPY environment.yml .
COPY ownchain/mypyscript.py .
COPY entrypoint.sh /usr/local/bin/

# make entrypoint script executable
RUN chmod u+x /usr/local/bin/entrypoint.sh
# create environment
RUN conda env create -f environment.yml

ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
CMD ["python", "mypyscript.py"]
Run Code Online (Sandbox Code Playgroud)

Where the entrypoint.sh looks like this:

#!/bin/bash --login
set -e

# activate conda environment and let the following process take over
conda activate myenv
exec "$@"
Run Code Online (Sandbox Code Playgroud)

All credit to David R. Pugh from this post that has more details, in particular with regards to Jupyter.


Hol*_*ole 5

以下是如何在 conda 环境中运行脚本而不缓冲所有标准输入/输出。

--no-capture-output选项自 conda 4.9 版起可用。

FROM continuumio/miniconda3

COPY ./environment.yml ./environment.yml

RUN conda env create && conda clean --all -f --yes

ENTRYPOINT ["conda", "run", "--no-capture-output", "-n", "the_environment_name", "python", "myscript.py"]
Run Code Online (Sandbox Code Playgroud)