记录docker build遇到的坑
exec.sh
打包DockerFile的最后需要用exec.sh写入所有容器run之后所运行的命令
遇到的两个问题:
- 换行符的坑
tail: cannot open '/dev/null'$'\r' for reading: No such file or directory
tail: no files remaining
原因在于:
使用linux自带的vim编辑器exec.sh后会自动为exec.sh的最后一行加上CR LF换行符,导致linux没法正确识别tail -f /dev/null这个命令。在本地使用Notepad之后删掉了最后一行的换行符之后就可以正常运行了。
- 使用虚拟环境的坑
按照平时的做法,假如想使用名为py36_env的虚拟环境,则应该
conda activate py36_env
python xxx
但是在exec.sh里面这样写会报错(错误忘记记录下来了)。查阅了其他博客发现要这样写才行
{py36_env虚拟环境的路径} xxx
也就是要直接使用虚拟环境python的路径,而不是用conda activate的方式
requirements.txt问题
在网上查阅资料发现有两种生成requirements.txt的方法
- pipreqs
# 安装
pip install pipreqs
# 在当前目录生成
pipreqs . --encoding=utf8 --force
但是使用这种方式存在问题:
无法加载依赖包的依赖,例如我打包的镜像中需要用到bert4keras,而在这里bert4keras是基于tensorflow-gpu的,那么用这种方式扫描当前目录,其实没有办法找到tensorflow-gpu这个包,因此requirements.txt里面自然也没有tensorflow-gpu了。
- pip freeze
pip freeze > requirements.txt
这种情况会把当前环境下的所有包都加入requirements.txt中,相当于是项目所需要包的超集。虽然会有用不上的包,但是能保证项目所需要的包一定都在里面。
其他问题
- pip 换源
pip下载比较慢,因此可以先换源再install
# Dockerfile中的写法
RUN pip config set global.index-url https://mirrors.aliyun.com/pypi/simple/ && pip install -r /home/release/requirements.tx
- 关于anaconda
如果不指定版本,默认会安装最新版的anaconda,目前最新版的是python 3.8,然而3.7以上的python版本无法安装tensorflow 1.x,因此需要创建虚拟环境
# Dockerfile中的写法
RUN conda create --name py36_env python=3.6
RUN conda init bash
#**,以后pip的包安装到3.6环境里
SHELL ["conda", "run", "-n", "py36_env", "/bin/bash", "-c"]
- 关于gunicorn
在使用gunicorn命令启动flask controller的时候会莫名其妙出现下面的错误
[CRITICAL] WORKER TIMEOUT (pid: xxx)
查了下原因,这是因为gunicorn默认超过30s就会把线程kill掉,但是我这里第一个模型加载比较久,还没加载完就被kill了。
解决方法:在启动gunicorn时指定等待时间
/opt/conda/envs/py36_env/bin/gunicorn -w 4 -b 0.0.0.0:5051 -t 60000 xxxController:app
这里 -t就是指定等待时间