Активируйте среду conda в docker

#windows #docker #dockerfile #conda #environment

#python #docker #анаконда #conda

Вопрос:

Мне нужно активировать среду в docker и запустить команду в этой среде. Я создаю среду, но затем пытаюсь активировать эту среду и выполнить команду таким образом:

 CMD [ "source activate mro_env amp;amp; ipython kernel install --user --name=mro_env" ]
 

но когда я запустил docker, я получаю сообщение об ошибке:

 [FATAL tini (8)] exec source activate mro_env amp;amp; ipython kernel install 
--user --name=mro_env failed: No such file or directory
 

Это весь файл 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 amp;amp; ipython kernel install --user --name=mro_env" ]
 

Комментарии:

1. Пожалуйста, покажите нам свой Dockerfile; похоже, вы на самом деле не создавали mro_env среду. Пожалуйста, также ознакомьтесь с официальной документацией для получения инструкции CMD.

2. @JordanSinger Я добавил файл Dockerfile

3. Вы уверены, что создание вашей среды прошло успешно?

4. @FabienP Да. среда успешно установлена. проблема заключается в интеграции с jupyter notebook. моя цель — установить среду на jupyter и запустить jupyter с этой средой. У вас есть какие-либо идеи, как я мог это сделать?

5. Обычно я делаю это так, чтобы установить Jupyter в среду, а затем запустить его оттуда. В противном случае вы могли бы посмотреть nb_conda_kernels , как получить доступ к этой среде с вашего сервера Jupyter.

Ответ №1:

Следуйте этому руководству, и это сработало. Пример файла 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"]
 

Обновить:

Вы можете использовать «conda run —no-capture-output», чтобы не буферизировать ввод-вывод, если вы используете версию conda 4.9. Обновленный файл 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"]
 

Комментарии:

1. Учебное пособие, которое вы упомянули здесь (и весь веб-сайт), стоит каждой минуты, потраченной на его чтение. Спасибо.

2. Команда оболочки не работает и заставляет остальную часть моего кода думать, что она в кавычках

3. Последнее, что я знал, conda run буферизует все стандартные выходные данные / ошибки до завершения процесса, так что это не вариант для приложения, взаимодействующего через стандартный ввод-вывод. Я полагаю, что он все еще может запускать сервер, но не ожидайте, что он будет отслеживать какие-либо сообщения stderr во время его работы. Кроме того, в этом «учебном пособии» есть проблемы, например, в первом примере сбой происходит только потому, что автор неправильно связывает свои команды за один ЗАПУСК (т. Е. Использует amp;amp; ) и излишне запускается conda init , когда базовый образ уже выполнил эту настройку.

4. Как насчет того, что Docker настолько эфемерен, что команды должны быть связаны таким образом

5. @merv Вы можете использовать «conda run —no-capture-output», чтобы не буферизировать ввод-вывод, если вы используете версию conda 4.9

Ответ №2:

Вы можете установить 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" ]

 

Обновить:

Лучше использовать activate. Работа для меня:

 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" ]
 

Комментарии:

1. Он добавляет conda env bin , который может работать, не уверен, какова CONDA_DEFAULt_ENV здесь роль. И это может привести к путанице conda activate , поскольку вы не определяете другие переменные как CONDA_SHLVL etc…

2. Моя проблема заключается в запуске jupyter с этой средой. У вас есть какие-нибудь идеи, как установить среду на jupyter и запустить ее вместе со средой?

3. Указание /bin/bash -c "source activate mro_env" кажется совершенно бессмысленным, поскольку активная оболочка для ENTRYPOINT и / или CMD , которые следуют, не bash является; это очевидно sh . Настройка CONDA_DEFAULT_ENV , по-видимому, также бессмысленна. В обоих случаях реальная работа выполняется самим ENV PATH .

4. при использовании docker всегда ли нам нужно создавать новую среду conda каждый раз, когда мы создаем контейнер? Или только один раз при создании образа docker?

5. Я видел, как ppl делал что-то подобное в файле docker: RUN conda create -n pycoq python=3.9 -y then ENV PATH="/home/bot/miniconda3/envs/pycoq/bin:${PATH}" . Есть ли в этом что-то неправильное?

Ответ №3:

Для меня решение, представленное здесь, сработало без проблем:

 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
 

Ответ №4:

Как указывает пользователь merv в одном из комментариев выше (извините, у меня недостаточно репутации, чтобы проголосовать за комментарий), conda run буферизует все стандартные значения / stderr, что делает его неработоспособным для взаимодействия приложений или даже просто отображения журналов через I / O.

Я заметил, что общепринятого ответа не было, поэтому я просто публикую то, что очень хорошо сработало для меня:

Вы можете использовать скрипт точки входа для активации среды conda и позволить ему принимать дополнительные входные данные из файла Dockerfile, чтобы скрипт python мог быть выполнен в активированной среде conda

Пример файла 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"]
 

Где entrypoint.sh выглядит примерно так:

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

# activate conda environment and let the following process take over
conda activate myenv
exec "$@"
 

Вся заслуга Дэвида Р. Пью из этого поста, в котором содержится более подробная информация, в частности, в отношении Jupyter.

Комментарии:

1. при использовании docker нам всегда нужно создавать новую среду conda каждый раз, когда мы создаем контейнер? Или только один раз при создании образа docker?

2. Я видел, как ppl делал что-то подобное в файле docker: RUN conda create -n pycoq python=3.9 -y then ENV PATH="/home/bot/miniconda3/envs/pycoq/bin:${PATH}" . Есть ли в этом что-то неправильное?

Ответ №5:

Вот как запустить скрипт в среде conda без буферизации всего стандартного ввода / вывода.

--no-capture-output Опция доступна с версии conda 4.9.

 FROM continuumio/miniconda3

COPY ./environment.yml ./environment.yml

RUN conda env create amp;amp; conda clean --all -f --yes

ENTRYPOINT ["conda", "run", "--no-capture-output", "-n", "the_environment_name", "python", "myscript.py"]
 

Ответ №6:

Проблема для меня заключалась в том, что выполнение команды conda activate env внутри docker после установки заставило conda попросить меня использовать эту conda init bash команду. Однако эта команда просит вас перезапустить оболочку, чего мы не хотим делать внутри docker. Таким образом, решение состоит в том, чтобы понять , что причина conda , по которой вас просят перезапустить оболочку , заключается в том, что она была изменена и хочет перезагрузить содержимое ~/.bashrc . Мы можем сделать это вручную и отказаться от необходимости перезапуска оболочки с помощью:

 . ~/.bashrc
 

Вот полный файл dockerfile для тех, кто этого хочет:

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


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

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

 

Редактировать — разобраться с комментарием

Комментатор прав в том, что приведенный выше пример не работает для переключения сред conda в docker. Совсем недавно я понял, что для того, чтобы это работало, вы должны начинать каждую RUN команду с conda init bash amp;amp; .~/.bashrc amp;amp; 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 amp;amp; bash ~/.bashrc amp;amp; . ~/.bashrc

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

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

 

Комментарии:

1. поместите последнюю составную команду в разные строки запуска, и она полностью сломается. это не рабочее решение, если вам нужно переключаться между различными средами в контейнере.

2. @Джереми Лейпциг прав. Чтобы переключаться между средами conda в последующих RUN командах, вам нужно будет начинать каждую RUN команду с conda init amp;amp; . ~/.bashrc amp;amp; conda activate py38 (например).

Ответ №7:

Я понимаю, что не существует единого решения, подходящего для всех, но это то, что я использую в своих приложениях Flask:

 FROM continuumio/miniconda3

COPY environment.yml .
RUN conda env create -f environment.yml

COPY app /app
WORKDIR /app

CMD ["conda", "run", "-n", "my_env", "python", "app.py"]
 

Логика очень проста. Сначала копируется файл среды, за которым следует создание среды. Затем копируются файлы приложений (именно здесь находятся все мои файлы приложений Flask). Наконец, с помощью CMD приложение запускается, указывая на среду.

Это структура каталогов проекта, которую я использовал с файлом Dockerfile:

 -- project
    -- app
        -- app.py
    -- environment.yaml
    -- Dockerfile
 

Обратите внимание, что это не активирует среду как таковую, но указывает на нее во время выполнения в команде CMD

Ответ №8:

Я наткнулся на этот вопрос, пытаясь активировать среду, а затем установить в нее некоторые пакеты. Решение оболочки не сработало для меня (возможно, потому, что я пытался сделать это в более старой версии conda — 4.5.4, если быть точным).

Решение состоит в том, чтобы активировать среду и выполнить все необходимые команды внутри новой оболочки. Кроме того, помните, что при каждом запуске запускается новая оболочка, которая ничего не помнит из предыдущего ЗАПУСКА.

 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 
    amp;amp; conda config --add channels conda-forge 
    amp;amp; conda install Jupiter 
    amp;amp; conda env list"

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

Обратите внимание, что каждая команда находится в пределах «» одного и того же /bin/bash -c.

Ответ №9:

Аналогично другим ответам, но с оболочкой, которая выглядит более чистой

 RUN wget 
https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh 
amp;amp; mkdir /root/.conda 
amp;amp; bash Miniconda3-latest-Linux-x86_64.sh -b 
amp;amp; rm -f Miniconda3-latest-Linux-x86_64.sh 
amp;amp; echo "source activate base" > ~/.bashrc

SHELL ["/bin/bash", "-c"]
ARG CONDA_ENV=env_name 
# Create env
RUN conda --version 
  amp;amp; conda create -n ${CONDA_ENV} python=3.7 
  amp;amp; source activate ${CONDA_ENV}
 

Ответ №10:

Довольно безнадежно заставить это работать надежно. Иногда решение некоторое время работает в системе, а затем внезапно перестает работать. В настоящее время для этого также мало поддержки от continuum/minicoda3 создателей. Я думаю, потому что они намерены использовать контейнер по-другому. Я попробовал следующее, и оно выполняется, однако при попытке запустить контейнер с docker-compose ним вместо этого ищет среду в странном месте /opt/conda/envs/ /root/miniconda3/envs/ .

 FROM ubuntu:22.04
ENV PATH="/root/miniconda3/bin:${PATH}"
ARG PATH="/root/miniconda3/bin:${PATH}"
RUN apt-get update

RUN apt-get install -y wget build-essential time amp;amp; rm -rf /var/lib/apt/lists/*

RUN wget 
    https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh 
    amp;amp; mkdir /root/.conda 
    amp;amp; bash Miniconda3-latest-Linux-x86_64.sh -b 
    amp;amp; rm -f Miniconda3-latest-Linux-x86_64.sh 

RUN conda --version

RUN conda init bash

RUN conda create -n myenv -c conda-forge -c bioconda python==3.10 pip

SHELL ["conda", "run", "-n", "myenv", "/bin/bash", "-c"]

COPY requirements.txt requirements.txt

RUN pip install -r requirements.txt
 

Ответ №11:

Я использую это для активации среды при запуске контейнера. Для установки пакетов в эту среду я просто использую «-n myenv».

 ENV PATH /opt/miniconda/bin:${PATH}

RUN wget --quiet https://repo.anaconda.com/miniconda/Miniconda3-4.5.11-Linux-x86_64.sh -O ~/miniconda.sh --no-check-certificate amp;amp; /bin/bash ~/miniconda.sh -b -p /opt/miniconda
RUN rm ~/miniconda.sh
RUN conda clean -ya

RUN conda update -n base -c defaults conda
RUN conda create --name detic python=3.8 -y

RUN echo ". /opt/miniconda/etc/profile.d/conda.sh" >> ~/.bashrc
RUN echo "conda activate detic" >> ~/.bashrc

RUN conda install -n detic ipython
 

Мне не нравится менять точки входа

Ответ №12:

Если вам не нужно менять среду вдали от базы, вы также можете сделать это:

 COPY conda.yaml /
RUN { echo "name: base"; tail  2 /conda.yaml; } > /base.yaml
RUN conda env update --file /base.yaml --prune
 

Среда в conda.yaml может иметь любое имя, поскольку мы заменяем его на base.

Ответ №13:

Поскольку conda run является экспериментальной функцией, правильный способ — добавить эту строку в ваш Dockerfile

 SHELL [ "/bin/bash", "--login", "-c" ]
 

после этого вы можете продолжить

 RUN conda init bash
 

а затем продолжайте активировать вашу среду с помощью

 RUN conda activate <env_name>