Docker使用conda构建Python项目
🤗

Docker使用conda构建Python项目

Tags
Docker
Conda
Python
Published
March 7, 2018
Author
Eironn Walker

一.前置知识点:

1.什么是conda?和Ananconda什么关系?

Conda是适用于任何语言的软件包、依赖项和环境管理系统--包括Python,R,Ruby,Lua,Scala,Java,JavaScript,C / C ++,FORTRAN等。
Anaconda是一组大约一百个程序包,包括conda,numpy,scipy,ipython notebook等。
Conda是一个辅助进行包管理和环境管理的工具。目前是Ananconda默认的Python包和环境管理工具,所以安装了Ananconda完整版,就默认安装了Conda。Conda既具有pip的包管理能力,同时也具有vitualenv的环境管理功能 ,因此在功能上Conda可以看作是pip 和 vitualenv 的组合。
一般的,我们如果只想对python进行管理包以及环境等,只需要安装Miniconda即可:这是Anaconda的一个较小替代方案,它只是conda及其依赖项,而不是上面列出的依赖项。

2.遇到的一些问题

  • conda源导致包下载慢或者失败
    • 解决:切换成中科大的源,构建底层的image,Dockerfile如下:
      # 使用官方的miniconda FROM conda/miniconda3 RUN conda update conda -y \ # 更改源 && echo "channels:" > ~/.condarc \ && echo " - https://mirrors.ustc.edu.cn/anaconda/pkgs/main/" >> ~/.condarc \ && echo " - https://mirrors.ustc.edu.cn/anaconda/pkgs/free/" >> ~/.condarc \ && echo " - https://mirrors.ustc.edu.cn/anaconda/cloud/conda-forge/" >> ~/.condarc \ && echo "ssl_verify: true" >> ~/.condarc \ # 忽略 ttyname failed: Inappropriate ioctl for device 错误 && sed -i -e 's/mesg n .*true/tty -s \&\& mesg n/g' ~/.profile \ && cat ~/.condarc \ && conda env list
  • Dockerfile中RUN命令执行某些命令提示command not found
    • 解决:切换终端由sh为/bin/bash
      # 登陆bash终端 SHELL ["/bin/bash", "--login", "-c"] # conda 初始化bash终端 RUN conda init bash
  • 使用bash终端会报错:ttyname failed: Inappropriate ioctl for device
    • 解决:底层的镜像增加容错处理
      RUN sed -i -e 's/mesg n .*true/tty -s \&\& mesg n/g' ~/.profile
  • 如何通过conda创建虚拟环境以及安装依赖
    • 注意⚠️:requirements.txt 的导入导出只支持在本机环境中的导入导出,不支持跨设备以及docker中使用!
      # 创建虚拟环境,名字为k12,指定python版本,不依赖默认的包 conda create --name k12 python=3.8 pip --no-default-packages # 安装相关包 conda install pika conda install zeep conda install PyCrypto conda install pycryptodome conda install pyyaml # 导出requirements.txt conda list -e > requirements.txt # 安装requirements.txt依赖 conda install --yes --file requirements.txt # 创建新的虚拟环境k13并安装依赖 conda create -y -n k13 --file requirements.txt python=3.8 pip
  • conda导出的requirements.txt无法在docker中安装
    • 解决:不使用conda list -e 来导出requirements.txt
      使用环境的导出导入,注意增加—no-builds参数来构建可以在docker中运行的依赖。
      # 导出环境 conda env export --no-builds > k12.yml # 导入环境 conda env create -f k12.yml
  • docker中激活环境不生效
    • 解决:因为docker每一个RUN命令都会生成一个layer,导致真正在执行CMD或者ENTRYPOINT你激活的环境实际已经不存在了(可以理解为新建了一个终端)
      使用启动脚本的方式来执行启动命令
      #!/bin/bash server_start(){ source activate conda activate k12 python ./src/k12/rabbitmq.py } server_start
  • 其他命令记录
    • 删除环境 conda remove -n py36 --all

      激活环境&&运行程序

      CMD ["/app/start.sh"]

二.构建使用中科大的conda源

私有景象的Dockerfile编写:
# 使用官方的miniconda FROM conda/miniconda3 RUN conda update conda -y \ # 更改源 && echo "channels:" > ~/.condarc \ && echo " - https://mirrors.ustc.edu.cn/anaconda/pkgs/main/" >> ~/.condarc \ && echo " - https://mirrors.ustc.edu.cn/anaconda/pkgs/free/" >> ~/.condarc \ && echo " - https://mirrors.ustc.edu.cn/anaconda/cloud/conda-forge/" >> ~/.condarc \ && echo "ssl_verify: true" >> ~/.condarc \ # 忽略 ttyname failed: Inappropriate ioctl for device 错误 && sed -i -e 's/mesg n .*true/tty -s \&\& mesg n/g' ~/.profile \ && cat ~/.condarc \ && conda env list
shell命令,来发布镜像到dockerhub(需要提前在dockerhub来创建自己的镜像名字)
# 根据Dockerfile构建镜像 docker build -f Dockerfile -t invlong/miniconda3-ustc:1.0 . # 登陆后执行push命令 docker push invlong/miniconda3-ustc:1.0

三.Python项目Dockerfile

1.Dockerfile如下:

# 将官方 Python 运行时用作父镜像 FROM invlong/miniconda3-ustc:1.0 #代码添加到code文件夹 ADD . /app # 设置code文件夹是工作目录 WORKDIR /app SHELL ["/bin/bash", "--login", "-c"] # 配置环境 ENV PATH /opt/conda/envs/k12/bin:$PATH # 创建虚拟环境k12,并安装依赖 # 初始化bash # 创建虚拟环境k12 # 赋予sh脚本可执行权限 RUN conda init bash \ && conda env create -f k12.yml \ && chmod 777 start.sh # 激活环境&&运行程序 CMD ["/app/start.sh"]

2.start.sh如下:

#!/bin/bash server_start(){ source activate conda activate k12 python ./src/k12/rabbitmq.py } server_start

3.构建镜像

根据Dockerfile来构建image(别漏了最后的点)
docker build -f Dockerfile -t k12-third-python:1.0 .

4.运行镜像

#d 后台运行,it可交互模式运行 docker run -dit imageId