#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
thenENV 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
thenENV 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>