Активировать и переключать среду Anaconda в Dockerfile во время сборки

Я пытался часами и не могу понять, как активировать и переключать среды anaconda в Dockerfile во время процесса сборки

Вот исходный код:

FROM nvidia/cuda:10.1-cudnn7-devel-ubuntu16.04

# Set user
ENV SETUSER myuser

RUN useradd -m $SETUSER
USER $SETUSER
WORKDIR /home/$SETUSER

# Install Anaconda
RUN wget https://repo.anaconda.com/archive/Anaconda3-2019.03-Linux-x86_64.sh
RUN bash Anaconda3-2019.03-Linux-x86_64.sh -b
RUN rm Anaconda3-2019.03-Linux-x86_64.sh

# Set path to conda
ENV CONDA_ENV_NAME mynewenv
RUN /home/$SETUSER/anaconda3/condabin/conda create -q --name $CONDA_ENV_NAME python=3.6 && \
    /home/$SETUSER/anaconda3/condabin/conda clean --yes --all
RUN /home/$SETUSER/anaconda3/condabin/conda activate base #Just for testing anaconda environment

Сначала anaconda в Docker будет жаловаться, что оболочка не настроена должным образом, поэтому после команды conda create я добавил:

RUN /home/$SETUSER/anaconda3/condabin/conda init bash
RUN /bin/bash -c "source /home/$SETUSER/.bashrc"
RUN /home/$SETUSER/anaconda3/condabin/conda activate base

Выполнение трех команд после создания образа докера работает (т. Е. Выполняется в интерактивном режиме после вызова docker run имя-контейнера), но по какой-то причине не работает при сборке контейнера. Я выяснил, что переменная $ PATH не обновлялась во время сборки, поэтому сравнил мой $ PATH при сборке и после сборки.

ENV PATH /home/$SETUSER/anaconda3/envs/$CONDA_ENV_NAME/bin:$PATH
ENV PATH /home/$SETUSER/anaconda3/condabin:$PATH
ENV PATH /home/$SETUSER/anaconda3/bin:$PATH
RUN conda init bash
RUN /bin/bash -c "source /home/$SETUSER/.bashrc"
RUN conda activate base

Теперь Docker $ PATH при сборке и $ PATH при интерактивном изменении при запуске контейнера после сборки одинаковы, но я все еще получаю ошибку неправильной настройки оболочки.

CommandNotFoundError: ваша оболочка неправильно настроена для использования conda activate. Чтобы инициализировать оболочку, запустите $ conda init В настоящее время поддерживаются следующие оболочки: - bash - fish - tcsh - xonsh - zsh - powershell Дополнительные сведения и параметры см. В 'conda init --help'. ВАЖНО: вам может потребоваться закрыть и перезапустить оболочку после запуска conda init.

Почему это не работает ???

Я видел, что может быть обходной путь с использованием шаблона докера miniconda, но я не могу его использовать. Как мне создать и переключить среду anaconda в процессе сборки Docker? Спасибо!


person xnet    schedule 08.06.2019    source источник
comment
Обычно в Docker вам не нужен такой инструмент, как Conda, который может управлять несколькими параллельными изолированными установками программного обеспечения: Docker сам обеспечивает эту изоляцию. Для пакетов Python просто запустите pip install в своем Dockerfile, чтобы установить что-то в системный Python (изолированный от образа, который вы создаете).   -  person David Maze    schedule 09.06.2019
comment
Все в порядке, но мне нужно запустить определенные версии python. Поэтому мне нужно создать для этого новую среду анаконды.   -  person xnet    schedule 20.06.2019
comment
Здесь та же проблема с решением   -  person CiaranWelsh    schedule 01.07.2020
comment
Вы пробовали изменить это RUN conda activate base на RUN bash -c "conda activate base"?   -  person Andrew Li    schedule 18.08.2020


Ответы (3)


В вашем Dockerfile слишком много команд RUN. Дело не только в том, что каждый RUN создает новый слой в изображении. Кроме того, каждая команда RUN запускает новую оболочку, а conda activate применяется только к текущей оболочке.

Вам следует объединить логические группы действий в одну команду RUN. Используйте && для объединения команд и \ для разрыва строк для удобства чтения:

RUN conda activate <myenv> \
 && conda install <whatever> \
 && ...

Имейте в виду: в конце этой команды RUN оболочка исчезнет. Поэтому, если вы хотите сделать что-то еще с этой средой conda после этого, вам нужно снова запустить conda activate или использовать -n <myenv>, чтобы поместить что-то в среду, не активируя ее предварительно.

Когда вы запускаете контейнер из образа, вам также нужно будет вызвать conda activate внутри контейнера.

person Roland Weber    schedule 09.06.2019

Предполагая, что вы хотите установить среду conda и запустить что-то в ней, этот подход использует ENV PATH для косвенного запуска python в этой среде conda. Можно задаться вопросом, действительно ли этот подход активирует среду, но если последующие команды работают, а они действительно работают, это может не иметь значения.

FROM continuumio/miniconda3:latest
WORKDIR myappdir
COPY environment.yml .
RUN set -x && \
#   apt-get update && apt-get -y install gcc && \
    conda install -n base -c defaults conda=4.* && \
    conda env create -n condaenv  # Installs environment.yml && \
    conda clean -a
COPY myapppkg myapppkg
ENV PATH /opt/conda/envs/condaenv/bin:$PATH
ENTRYPOINT ["python", "-m", "myapppkg"]

Я не рекомендую использовать conda run в экспериментальном режиме из-за истории серьезных ошибок, таких как этот влияя на это. Хотя эта конкретная ошибка сейчас исправлена, ее продолжающийся экспериментальный характер, как показано conda run -h, означает, что она может снова выйти из восходящего потока, ограничивая доверие, которое можно ей возложить.

Для справки:

person Acumenus    schedule 21.08.2019

Я не тестировал его с изображением nvidia, но многоступенчатые сборки Docker должны помочь вам, что, вероятно, будет выглядеть примерно так:

# get Miniconda docker image to get a installed conda env; WARNING: That image is Debian based
FROM continuumio/miniconda3:latest AS miniconda


# your Docker commands
FROM nvidia/cuda:10.1-cudnn7-devel-ubuntu16.04

# Set user
ENV SETUSER myuser

RUN useradd -m $SETUSER
USER $SETUSER
WORKDIR /home/$SETUSER


# Miniconda: get necessary files from build
COPY --from=miniconda /opt/conda /opt/conda
# Set correct permissions
RUN chown -R $SETUSER: /opt/conda
#   New terminals will have conda active
# If nvidia's Docker image has no .bashrc
# COPY --from=miniconda /home/$SETUSER/.bashrc
# else
RUN echo ". /opt/conda/etc/profile.d/conda.sh" >> ~/.bashrc && \
    echo "conda activate base" >> ~/.bashrc

# switch shell sh (default in Linux) to bash
SHELL ["/bin/bash", "-c"]

# give bash access to Anaconda, then normal anaconda commands, e.g. (-q: quiet, -y: answer yes)
RUN source /home/$SETUSER/.bashrc \
 && conda create -q --name testy \
 && conda activate testy \
 && conda install -y your_package

Вдохновение из этого выпуска GitHub: https://github.com/ContinuumIO/docker-images/issues/89

person NumesSanguis    schedule 15.11.2019