在Docker上构建保存在Yaml中的conda虚拟环境


在Docker上创建Python环境时,也使用pipPipenv,但是由于使用的库和软件包,使用conda环境可能会很方便。
关于如何在Docker上创建所需的conda环境的个人说明。

1.动机

Miniconda和Anaconda可以用于Python开发和数据分析。
(由于从属库与折扣一起安装,因此构建环境很容易,您不必自己安装它,或者由于二进制兼容性,建议从conda的特定渠道安装软件包。问题)
那时,我基本上是使用conda虚拟环境来更改我正在做的每项工作的软件包和版本,并使其在以后重现该环境变得更加容易。
但是,有时候有必要从Python以外的地方设置和构建环境,即使它是虚拟环境,也存在诸如污染PC环境并干扰其他环境的问题,因此最终Docker可以处理因为有很多(而且我很难将其移植到Docker)

使用Yaml文件的原因

有关详细信息,请参见下一章

  • 您可以轻松地将PC上现有的conda虚拟环境移植到Docker。
  • 相反,在Docker上开发的conda环境可以立即用您的Anaconda或Miniconda复制。

等。

2.保存和重建conda环境

2-1。从Yaml文件

生成Conda环境

(官方文件)

1
conda env create -f environment.yml

执行

时,将根据environment.yml中描述的信息创建conda环境。
例如,如果您在git上管理对应于environment.yml的代码,则在可移植性和可再现性方面很方便。

* environment.yml 的内容请参考以下说明
*我不记得conda env create之后选项的详细信息。 .. ..如果可以找到并喜欢它,请稍后添加。顺便说一下,conda create选项看起来像这样。

2-2。生成yaml文件

(官方文件)

输入目标conda虚拟环境并执行以下操作,例如

1
conda env export > environment.yml

然后,将在相应的conda环境中安装的所有软件包及其版本(包括构建信息)都写入environment.yml。 (感觉像pip freeze)

顺便说一句,即使您没有输入虚拟环境

1
conda env export  -n <仮想環境名> > environment.yml

您还可以显式指定要写出的虚拟环境名称,例如

另外,尽管以上两个的版本信息是完全固定的,但是在某些情况下,您只想指定最低条件而不这样做。
您可以通过参考(官方文件)来创建自己的yaml文件,以描述程序包和使用的通道。 (以下是一个适当的示例)

create_env_sample.yml

1
2
3
4
5
6
7
8
9
10
11
name: hoge
channels:
  - conda-forge
  - default
dependencies:
  - python==3.7.*
  - pandas<1.0
  - flask
  - pip
  - pip:
    - pynvim
  • 相关库等将自动安装(如果不发生冲突)。
  • 您还可以编写随pip安装的内容。 (在pip:下)

    • 首先执行conda安装,最后执行pip安装。
    • 在使用conda安装的软件包中明确安装pip可能是安全的

      • 出现警告,提示"可能使用了非conda虚拟环境中的点"。

在上例中的yaml文件中,

1
2
3
4
5
6
# condaでパッケージをインストール
conda create -n hoge python=3.7 pandas\<1.0 flask pip -c conda-forge
# 作った仮想環境に入る
conda activate hoge
# 最後にpipで必要なパッケージをインストール
python -m pip install pynvim

这几乎与构建

之类的环境相同。 (*尚未验证是否完全相同)

3.在Docker

上创建一个conda虚拟环境

(政策)

  • 将根据上一章准备的yaml文件放入Docker映像中,例如COPY

  • 使用Miniconda从yaml文件创建环境

    • 有关Miniconda本身的安装,请参阅官方等。
    • Continiuum的官方Dockerfile也很有帮助。
  • 上面的Miniconda仅用于从yaml文件创建虚拟环境,完成后,将为每个缓存删除原始的Miniconda(←,这是浪费空间)

    • 相反,使从yaml创建的虚拟环境base
    • (可能有更好的方法)

Dockerfile创建示例(摘录)

目录结构:

1
2
3
4
tree .
# .
# ├── Dockerfile
# └── environment.yml

感觉像

1
docker build --tag=hoge .

1
2
3
4
5
6
# Dockerfile内のARG部分を制御する場合
docker build \
    --tag=hoge \
    --build-arg VAL1=FOO \
    --build-arg VAL2=BAR \
     .

如果您喜欢

,并且构建通过

,则可以获得hoge的图像

Docker文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
ARG BASE_IMAGE=ubuntu:latest
FROM ${BASE_IMAGE}

# system update & package install
RUN apt-get clean && \
    apt-get -y update && \
    apt-get install -y --no-install-recommends \
    unzip bzip2 \
    openssl libssl-dev \
    curl wget \
    ca-certificates \
    locales \
    bash \
    sudo \
    git \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/*


# ローカルuser作成
ARG USER_NAME=user
ARG USER_UID=1000
ARG PASSWD=password
RUN useradd -m -s /bin/bash -u ${USER_UID} ${USER_NAME} && \
    gpasswd -a ${USER_NAME} sudo && \
    echo "${USER_NAME}:${PASSWD}" | chpasswd && \
    echo "${USER_NAME} ALL=(ALL) ALL" >> /etc/sudoers && \
    chmod g+w /etc/passwd


# conda用準備
ENV CONDA_DIR=/opt/conda \
    CONDA_TMP_DIR=/tmp/conda \
    HOME=/home/$USER_NAME \
    SHELL=/bin/bash
RUN mkdir -p $CONDA_DIR && \
    mkdir -p $CONDA_TMP_DIR && \
    chown $USER_NAME:$USER_UID $CONDA_DIR && \
    chown $USER_NAME:$USER_UID $CONDA_TMP_DIR
# yamlファイルの取り込み
ARG CONDA_YAML="./environment.yml"
COPY $CONDA_YAML /tmp/conda_packages.yml

USER ${USER_NAME}

WORKDIR $HOME
# miniconda
ARG MINICONDA_VERSION=py37_4.8.3-Linux-x86_64
ARG MINICONDA_MD5=751786b92c00b1aeae3f017b781018df
ENV PATH=${CONDA_DIR}/bin:$PATH

RUN cd /tmp && \
    wget --quiet https://repo.anaconda.com/miniconda/Miniconda3-${MINICONDA_VERSION}.sh && \
    echo "${MINICONDA_MD5} *Miniconda3-${MINICONDA_VERSION}.sh" | md5sum -c - && \
    /bin/bash Miniconda3-${MINICONDA_VERSION}.sh -f -b -p $CONDA_TMP_DIR && \
    rm Miniconda3-${MINICONDA_VERSION}.sh && \
    $CONDA_TMP_DIR/bin/conda env create -f /tmp/conda_packages.yml -p $CONDA_DIR && \
    rm -rf $HOME/.cache/* && \
    rm -rf $CONDA_TMP_DIR/*

# (以下省略)
  • 简介Miniconda安装在/tmp/conda/

    • 如上所述,它仅用于conda env create,因此稍后将完全擦除/tmp/conda/的底部。
    • 安装目标由-p选项指定。
  • 所需的conda环境安装在/opt/conda/下,并在此处传递PATH,这是创建用户的默认Python环境。

    • 使用-p--prefix选项指定安装目标,以使conda环境为/opt/conda/
  • 从下载和安装Miniconda到删除不必要的文件和缓存,您都需要一劳永逸地完成RUN的所有工作,以便图像大小不会增加。

(补充)

  • 我使用的Miniconda是撰写本文时(2020-07-24)的最新版本,因此我将通过参考此处等内容进行适当的更新。
  • 我正在创建一个用户,但这不是必需的,因此,如果省略它,它应该更干净
  • 如果yaml文件中有prefix:部分,则表示安装位置,但似乎conda env create-p--prefix选项中的规范具有优先权。
  • 如果在以yaml文件编写的安装包中写入conda,则安装在/opt/conda/中的虚拟环境将成为新的base环境。

    • 您可以在使用容器时出现要放入的其他软件包时,立即执行conda install ***,然后可以通过按conda env export -n base | tee environment.yml等来重新确认安装软件包或生成新的Yaml文件。
(更多补充)

有时无法将conda env export生成的yaml文件直接传递给conda env create,因此有一个示例和对策。

  • 如果将graphvizpip一起安装并使用conda env export生成yaml,则它将命名为python-graphviz

  • 但是,pip install python-graphviz将导致错误,因此,如果按原样使用此yaml文件,则会出现安装错误。
  • 因此,例如,我插入了以下部分,并稍微重写了yaml文件。
1
RUN sed -i -e 's/python-graphviz/graphviz/' /tmp/conda_packages.yml

sedgraphviz

替换yaml文件中的python-graphviz

参考

保存或构建conda环境:
https://qiita.com/nshinya/items/cb1cffabc3305c907bc5
https://qiita.com/yubessy/items/2dd43551aa8308dc7eca

在Docker上构建conda环境
https://hub.docker.com/r/continuumio/miniconda/dockerfile
https://github.com/jupyter/docker-stacks/tree/master(←请参阅存储库中的每个Dockerfile)