如何在dockerfile中激活conda虚拟环境

40 2020-03-17 07:41:27

引言

众所周知,Conda打包工具实现了各种环境,这些环境使不同的应用程序可以安装不同的库。因此,当为基于Conda的应用程序构建Docker映像时,需要激活Conda环境。

例如,现在有两个服务,一个视频处理服务依赖ffmpeg,一个网站服务依赖django-celery。使用conda install ffmpeg的时候conda会把默认的依赖升级到最新,比如python版本会升级到3.8。但是celery又仅仅支持到python 3.6。那么这时候就需要构建两个环境,分别安装ffmpeg和django。

那么如何编写dockerfile创建conda环境,并且在各个环境之间进行切换呢?

第一版dockerfile

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
FROM conda/miniconda3

...

# Update conda
RUN conda update -n base -c defaults conda


# Create app_env with python 3.6
RUN conda create -n app_env python=3.6
# Create mpeg_env with python 3.8
RUN conda create -n mpeg_env python=3.8

# Switch to mpeg_env then install ffmpeg
RUN conda activate mpeg_env
RUN conda install -y ffmpeg -c conda-forge

# Switch to app_env then install Django && Django-Celery
RUN conda deactivate
RUN conda activate app_env
RUN pip install -r /requirements.txt

...

尝试使用这个版本的dockerfile构建镜像的时候遇到了如下错误

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
CommandNotFoundError: Your shell has not been properly configured to use 'conda activate'.
To initialize your shell, run

    $ conda init <SHELL_NAME>

Currently supported shells are:
  - bash
  - fish
  - tcsh
  - xonsh
  - zsh
  - powershell

See 'conda init --help' for more information and options.

IMPORTANT: You may need to close and restart your shell after running 'conda init'.

看他的意思好像是需要先执行一个初始化命令,那么把conda init加进去试试

第二版dockerfile

这个版本主要是把上次执行的错误输出中的建议加到了dockerfile中

 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
FROM conda/miniconda3

...

# Update conda
RUN conda update -n base -c defaults conda


# Create app_env with python 3.6
RUN conda create -n app_env python=3.6
# Create mpeg_env with python 3.8
RUN conda create -n mpeg_env python=3.8

# Init conda
RUN conda init bash

# Switch to mpeg_env then install ffmpeg
RUN conda activate mpeg_env
RUN conda install -y ffmpeg -c conda-forge

# Switch to app_env then install Django && Django-Celery
RUN conda deactivate
RUN conda activate app_env
RUN pip install -r /requirements.txt

...

使用这个dockerfile进行构建还是报同样的错误,那么问题到底出在什么地方呢?有没有其他激活conda环境的方式。通过google关键字docker conda env查找到可以使用conda run -n myenv yourcommand来替换conda activate这样dockerfile中的RUN指令就会在虚拟环境中运行。接下来我们通过这个信息编写我们最终版本的dockerfile

最终版本的dockerfile

这个版本的dockerfile就是通过conda run -n myenv yourcommand指令让run命令在cconda的虚拟环境中执行,最终一切如常。

 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
FROM conda/miniconda3

...

# Update conda
RUN conda update -n base -c defaults conda


# Create app_env with python 3.6
RUN conda create -n app_env python=3.6
# Create mpeg_env with python 3.8
RUN conda create -n mpeg_env python=3.8

# Init conda
RUN conda init bash

# Switch to mpeg_env then install ffmpeg

SHELL ["conda""run""-n""ffmpeg_env""/bin/bash""-c"]
RUN conda install -y ffmpeg -c conda-forge

# Switch to app_env then install Django && Django-Celery
SHELL ["conda", "run", "-n", "app_env", "/bin/bash", "-c"]
RUN pip install -r /requirements.txt

...