我有以下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 文件
。
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 笔记本服务器(使用 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 提示符运行命令
。这导致了与上面相同的错误。
我还尝试定义一个 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 环境
$ 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 Notebook 服务器的 Dockerfile。
我需要的额外复杂性包括向 Dockerfile 添加非 root 用户并创建新的 conda 环境,而不是更新默认的 base
conda 环境。
最佳答案
发生的情况是:
在
docker-compose.yml
中,ip=0.0.0.0
中存在拼写错误,应为--ip=0.0。 0.0
改为将主机的文件夹绑定(bind)到容器中会覆盖
.bashrc
。一个简单的更改就是安装到子目录中您需要以交互模式 (
-i
) 运行 bash,以便正确读取.bashrc
例如,这些点的更改反射(reflect)在您的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'
关于python - 使用 docker-compose 启动 Jupyter Notebook 时激活 Docker 容器内的 conda env,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53261888/