Docker使用conda构建Python项目踩坑日志


Docker使用conda构建Python项目

Created: July 26, 2021 9:14 AM

一.前置知识点:

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及其依赖项,而不是上面列出的依赖项。

Miniconda下载地址

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

二.构建使用中科大的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

声明:Eironn's Blog|版权所有,违者必究|如未注明,均为原创|本网站采用BY-NC-SA协议进行授权

转载:转载请注明原文链接 - Docker使用conda构建Python项目踩坑日志


Java开发,同时会一些旁门左道。