docker 打包部署 python项目_Docker python项目实战部署入门

For whom

点开这篇文章的童鞋大多数是刚听过docker这个词或者是早就听过这个词但是却没有仔细了解过,但是发现网上的教程又太过理论,初学者难以快速入门或者不知道从何学起,那么恭喜你,这篇文章就是为你而写。

Outline

Docker是什么?先来一段百度百科上的定义:

Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的Linux或Windows 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。

上面的一段话总结起来主要有三点:1.docker的作用是可以将项目及其所需环境一起打包起来,完整移植到另外一个机器上。2.docker是一项虚拟化技术,虚拟化的目的是为了在同一个主机上运行多个系统或应用,提高资源利用率。3.docker的产生的多个环境是完全独立的,不能相互影响。

认识两个概念

Docker里有两个非常重要的概念, images,container,这两个概念都跟打包好的项目环境有关。简单来说,images是镜像,相当于面向对象里面的类,container是容器,相当于面向对象里面的实例,那么我们知道类是可以产生实例的,但在dcoker里不同的是 容器也可以生成镜像.

总体步骤:主机A build镜像---push到docker hub---主机B pull镜像

实战

话不多说,下面就举个实际例子,来帮助大家快速入门docker python项目部署。

假如我的朋友小Xi(又无中生友了..)是一个深度学习炼丹师,最近在忙活一个人脸检测项目,经过多次优化,终于得到了一个精度和速度都非常棒的模型,现在他的Leader要让他给甲方当面展示下模型,甲方提出了一个要求:模型必须在甲方提供的主机上运行,以防乙方得到的模型数据是在硬件配置非常高的环境下得到的。小Xi理解甲方的顾虑,但是这万一甲方的电脑环境配置有问题,到时候现场演示代码报错怎么弄啊,这时候小Xi的同事小Liu站出来说,你可以试试docker啊,小Xi一拍脑袋,对啊,docker的作用不正是将项目和依赖环境一起打包吗,说干就干,甩了(暴露了《鬼吹灯》铁粉的身份)!

本地的项目文件如下图所示,我们要给甲方运行的主文件是evaluate_image.py, 那么我们接下来的任务是把这个项目用docker打包起来,并上传到docker_hub,在另一台主机上把这个项目pull下来。

准备工作

当你敲了几个docker指令你就会发现,docker怎么这么烦啊,每次都要root权限,那么怎么解决这个问题呢?

groups #查看现在用户所在组的组成员,这时候应该是没有docker的

sudo groupadd docker # 添加docker用户组

sudo gpasswd -a xi docker #"xi"是自己的用户名,将你的用户名加到docker用户组里

newgrp docker #更新用户组

groups #这时再查看用户所在组的组成员,发现这时候有docker了,但是很可能你再开一个shell groups还是没有docker,我弄了好久,电脑重启以后就有了.

这时应该就解决了权限问题。

build镜像

首先按照这样的方式建立目录,其中docker_file里面是所有的项目代码,Dockerfile是我们自己建立的文件用于生成镜像

.

├── docker_file

└── Dockerfile

现在你的目录应该是这个样子

下面来填写Dockerfile的内容:

FROM python:2.7 #你的项目的工作环境

ADD ./docker_file /file #./docker_file是本地的项目的相对路径, /file是你要建立的镜像里面的项目的相对路径

WORKDIR /file #镜像的工作路径

##下面三行用于添加阿里源,官方源pip安装速度太慢

RUN pip install -U pip

RUN pip config set global.index-url http://mirrors.aliyun.com/pypi/simple

RUN pip config set install.trusted-host mirrors.aliyun.com:

RUN pip install -r requirements.txt #用pip为镜像安装项目的依赖库

CMD ["python", "/file/evaluate_image.py"] #指定项目主文件

需要着重关注的是requirements.txt的生成方法,这个文件里面包含了项目所有的依赖库,当然你可以一行一行的打进去,幸运的是,Python里面提供了一个包可以自动生成项目的依赖库pipreqs,首先你需要安装这个库:

pip install pipreqs

然后cd到项目目录:

pipreqs ./

这时,你会发现docker_file文件夹下面出现了一个requirements.txt,打开里面的内容如下:

tensorflow==1.4.1

easydict==1.9

numpy==1.13.3

切回到docker项目根目录,使用下面的指令,新建镜像

用下面的指令查看目前存在的所有镜像,我们看到了刚才建立的xi_test镜像,你会发现,怎么每个镜像文件都这么大啊,会不会把我的硬盘空间吃完,别担心,docker采用的技术可以和已有镜像共享相同的部分,因此实际并没有占据那么多空间。

docker images

push镜像到docker hub

既然本地已经有新建的镜像了,那么我们就把它上传到docker hub,先去docker hub注册一个账号,比如我的账号是xyl123,然后建立一个仓库,如first,那么这个仓库就可以用xyl123/first来指代.

docker login #登录docker

docker tag xi_test xyl123/first #必须给本地镜像打上这样的tag标签,才可以传到docker hub上

docker push xyl123/first

这时打开自己的docker hub主页会发现已经存在了刚上传的image

pull镜像到本地

经过上面的步骤小Xi已经把自己的镜像传到docker hub上面了,只需要甲方安装docker环境,并且在演示的时候用甲方的主机把docker hub上的镜像pull下来就好了。

docker pull xyl123/first #通过运行docker images 你会发现本地多出了一个镜像,接下来你就可以利用images的相关指令对pull下来的images进行操作了.

运行镜像

运行镜像的结果是产生一个container,这个container就是我们的项目及其环境。

docker run -it xyl123/first /bin/bash #运行镜像,产生一个容器,并以shell的交互形式运行容器.

可以看到我们产生了一个容器,并且进入了该容器,而且进入的文件夹正是我们在Dockerfile里面设置的工作目录/file,一旦进入了容器,你就可以像操作本地文件的方式操作容器里的文件。

root@50666281fef3:/file# 中的50666281fef3是该容器的id,如果你想查一下本地还有哪些容器,可以新建一个终端使用(不要在容器内使用):

docker ps #查看正在运行的container,

docker ps -a # -a可以查看所有的container

那如果你想删除、开启,停止,进入,退出一个容器呢?

docker rm container_id #运行某个container

docker stop container_id #停止某个container

docker start container_id #运行某个container

docker stop container_id #停止某个container

docker exec -it container_id /bin/bash #进入某个container

exit #退出container,退出后容器并不停止,这是和 docker attach container_id 方式进入容器的根本的不同

容器生成镜像

如果在跟甲方演示的时候,甲方提了一些建议,小 Xi修改了生成的容器的内容,为了将修改之后的环境上传到docker hub,供后续改进,这时候需要用改好的容器生成一个镜像。

docker commit 50666281fef3 modified_test_xi

这时候再运行docker images,就可以发现新生成的images了。

容器和本地文件互传

假如说,甲方要保存刚才容器内运行的结果到本地,用docker -ps 指令找到刚才容器对应的name

docker cp epic_elbakyan:/file/image/result/宋茜_2.jpeg ./

这时本地就出现了容器内跑出的结果,这不是宋茜的人脸(大)人头(长腿)吗?真的很方便。

如果想反过来的,只需要颠倒本地和容器地址的位置。

docker cp epic_elbakyan: ./ 宋茜_2.jpeg /file/image/result/

注意上面两个指令不是在容器内部运行的,是在本地运行的。

日常鸡汤

工欲善其事必先利其器,对一个算法工程师而言,每天仅仅沉醉于阅读paper不可自拔,是远远不够的,要睁开眼睛看看世界,合理利用日新月异的技术帮助自己提高效率,同样的,对于一个负责落地的开发工程师来说,也应该了解必要的理论知识,提升代码的准确性。因此想要成为一个领域内极其优秀的人才,理论和工程能力如人之双腿,缺一不可。

你可能感兴趣的:(docker,打包部署,python项目)