【问题标题】:Activating a conda env inside a Docker container when using docker-compose to start Jupyter notebook使用 docker-compose 启动 Jupyter notebook 时在 Docker 容器中激活 conda env
【发布时间】:2018-11-12 12:07:55
【问题描述】:

我有以下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

在激活 conda 环境的 Docker 容器中生成 bash 提示符。

(environment_name)$

现在我想使用docker-compose 在容器内启动一个 Jupyter 笔记本服务器(使用指定 Jupyter 作为依赖项的 conda 环境文件构建)。

当我使用下面的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: truestdin_open: true 添加到docker-compose.yml 中,认为这应该在运行command 之前调用交互式bash 提示符。这导致了与上述相同的错误。

我还尝试定义一个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

在激活 conda 环境之前,我尝试明确采购 /opt/conda/etc/profile.d/conda.sh

#!/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

我现在没有想法。这应该是可能的。 Here 是一个带有 docker-compose.yml 文件的项目示例,这是一个指定 conda 环境并启动 Jupyter 笔记本服务器的 Dockerfile。

我需要的额外复杂性包括将非 root 用户添加到 Dockerfile 并创建新的 conda 环境,而不是更新默认的 base conda 环境。

【问题讨论】:

  • 你能把environment.yml的内容贴出来吗?
  • 添加了一个存根 environment.yml 文件。
  • 在我看来错误来自 ip=0.0.0.0 参数,而应该是 --ip=0.0.0.0
  • @fernandezcuesta 感谢您发现错字!但这不会影响我收到的任何错误消息。关键问题似乎在于激活 conda 环境。

标签: python docker docker-compose conda


【解决方案1】:

发生的结果是:

  1. docker-compose.yml 中,您在ip=0.0.0.0 中有错字,应改为--ip=0.0.0.0

  2. 将主机的文件夹绑定到容器中会覆盖.bashrc。一个简单的更改是安装到子目录中

  3. 您需要以交互模式 (-i) 运行 bash,以便正确读取 .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'

【讨论】:

  • 您是如何发现将主机的文件夹绑定到容器中会覆盖.bashrc
  • docker documentation中有描述
猜你喜欢
  • 1970-01-01
  • 2019-02-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-07
  • 1970-01-01
  • 2019-08-03
  • 2017-08-10
  • 2023-03-05
相关资源
最近更新 更多