Активация conda env внутри контейнера Docker при использовании docker-compose для запуска ноутбука Jupyter - PullRequest
0 голосов
/ 12 ноября 2018

У меня есть следующее Dockerfile.

FROM continuumio/miniconda3:4.5.11

# create a new user (defaults to 'al-khawarizmi')
USER root
ARG username=al-khawarizmi
RUN useradd --create-home --home-dir /home/${username} ${username}
ENV HOME /home/${username}

# switch to newly created user to avoid running container as root
USER ${username}
WORKDIR $HOME

# build and activate the specified conda environment from a file (defaults to 'environment.yml')
ARG environment=environment.yml
COPY ${environment} .
RUN conda env create --file ${environment} && \
    echo ". /opt/conda/etc/profile.d/conda.sh" >> ~/.bashrc && \ 
    echo "conda activate $(head -1 ${environment} | cut -d' ' -f2)" >> ~/.bashrc

Dockerfile позволяет пользователю указать файл среды conda в качестве аргумента сборки. Вот бы типичный environment.yml file.

name: nessie-py

channels:
  - conda-forge
  - defaults

dependencies:
  - python=3.6
  - "notebook=5.7.*"
  - "matplotlib=3.0.*"
  - "numpy=1.15.*"
  - "pandas=0.23.*"

Пользователь может запустить образ стандартным способом, и среда conda будет автоматически активирована. Запуск

$ docker run -it image_name:image_tag

возвращает приглашение bash в контейнере Docker с активированной средой conda.

(environment_name)$

Теперь я хотел бы использовать docker-compose для запуска сервера ноутбука Jupyter внутри контейнера (созданного с помощью файла среды conda, в котором Jupyter указан как зависимость).

Когда я использую следующее docker-compose.yml

version: "3.7"

services:
  notebook-server:
    build:
      context: ./
    ports:
      - "8888:8888"
    volumes:
      - ./:/home/al-khawarizmi
    command: jupyter notebook --no-browser ip=0.0.0.0  

Я получаю следующую ошибку.

$ docker-compose up
Creating network "nessie-py_default" with the default driver
Creating nessie-py_notebook-server_1 ... done
Attaching to nessie-py_notebook-server_1
notebook-server_1  | [FATAL tini (7)] exec jupyter failed: No such file or directory
nessie-py_notebook-server_1 exited with code 127

Я подозревал, что эта ошибка означает, что среда conda не активирована. Затем я попытался добавить tty: true и stdin_open: true к docker-compose.yml, думая, что это должно вызвать интерактивное приглашение bash перед запуском command. Это привело к той же ошибке, что и выше.

Я также попытался определить сценарий start-notebook.sh, который явно активирует среду conda до запуска ноутбука.

#!/bin/bash
set -e

# activate the environment and start the notebook
conda activate nessie-py
jupyter notebook --no-browser ip=0.0.0.0

приводит к другой ошибке

$ docker-compose up
Creating network "nessie-py_default" with the default driver
Creating nessie-py_notebook-server_1 ... done
Attaching to nessie-py_notebook-server_1
notebook-server_1  | 
notebook-server_1  | CommandNotFoundError: Your shell has not been properly configured to use 'conda activate'.
notebook-server_1  | If your shell is Bash or a Bourne variant, enable conda for the current user with
notebook-server_1  | 
notebook-server_1  |     $ echo ". /opt/conda/etc/profile.d/conda.sh" >> ~/.bashrc
notebook-server_1  | 
notebook-server_1  | or, for all users, enable conda with
notebook-server_1  | 
notebook-server_1  |     $ sudo ln -s /opt/conda/etc/profile.d/conda.sh /etc/profile.d/conda.sh
notebook-server_1  | 
notebook-server_1  | The options above will permanently enable the 'conda' command, but they do NOT
notebook-server_1  | put conda's base (root) environment on PATH.  To do so, run
notebook-server_1  | 
notebook-server_1  |     $ conda activate
notebook-server_1  | 
notebook-server_1  | in your terminal, or to put the base environment on PATH permanently, run
notebook-server_1  | 
notebook-server_1  |     $ echo "conda activate" >> ~/.bashrc
notebook-server_1  | 
notebook-server_1  | Previous to conda 4.4, the recommended way to activate conda was to modify PATH in
notebook-server_1  | your ~/.bashrc file.  You should manually remove the line that looks like
notebook-server_1  | 
notebook-server_1  |     export PATH="/opt/conda/bin:$PATH"
notebook-server_1  | 
notebook-server_1  | ^^^ The above line should NO LONGER be in your ~/.bashrc file! ^^^
notebook-server_1  | 
notebook-server_1  | 
nessie-py_notebook-server_1 exited with code 1

Эта ошибка говорит о том, что bash не использует ~/.bashrc до запуска сценария.

Я пытался явно получить /opt/conda/etc/profile.d/conda.sh перед активацией среды conda.

#!/bin/bash
set -e

# activate the environment and start the notebook
. /opt/conda/etc/profile.d/conda.sh
conda activate nessie-py
jupyter notebook --no-browser ip=0.0.0.0

, что приводит к другой ошибке!

$ docker-compose up
Creating network "nessie-py_default" with the default driver
Creating nessie-py_notebook-server_1 ... done
Attaching to nessie-py_notebook-server_1
notebook-server_1  | Could not find conda environment: nessie-py
notebook-server_1  | You can list all discoverable environments with `conda info --envs`.
notebook-server_1  | 
nessie-py_notebook-server_1 exited with code 1

Я могу проверить, какие conda envs можно обнаружить в контейнере, запустив

$ docker run -it nessie-py conda info --envs

, в котором говорится, что среда действительно существует.

$ docker run -it nessie-py_notebook-server conda info --envs
# conda environments:
#
nessie-py                /home/al-khawarizmi/.conda/envs/nessie-py
base                  *  /opt/conda

У меня нет идей на данный момент. Это должно быть возможно. Здесь - пример проекта с файлом docker-compose.yml, Dockerfile, который задает среду conda и запускает сервер ноутбука Jupyter.

Дополнительные сложности, которые мне нужны, включают добавление пользователя без полномочий root в Dockerfile и создание новой среды conda вместо обновления стандартной среды base conda.

1 Ответ

0 голосов
/ 14 ноября 2018

То, что происходит, является следствием:

  1. В docker-compose.yml есть опечатка в ip=0.0.0.0, которая должна быть --ip=0.0.0.0 вместо

  2. Привязка папки хоста к контейнеру переопределяет .bashrc.Простым изменением будет монтирование в подкаталог

  3. Вам необходимо запустить bash в интерактивном режиме (-i), чтобы .bashrc правильно читалось

Например, изменения в этих точках отражены в вашем docker-compose.yml:

version: "3.7"

    services:
      notebook-server:
        build:
          context: ./
        ports:
          - "8888:8888"
        volumes:
          - ./:/home/al-khawarizmi/hosthome
        command: bash -ic 'jupyter notebook --no-browser --ip=0.0.0.0'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...