目录
前言:
Docker文档
Docker 安装以及安装源配置
镜像拉取
创建容器
安装第三方库
项目拷贝至容器
项目运行测试
导出容器为镜像资源
Dockerfile的使用
基于Dockerfile再次可使用镜像
运行处理后镜像
docker容器自启动服务
镜像打包
这次写一篇关于docker的使用教程,是结合简单的实际需求,把两个两个简单的tornado服务中的其中一个拿来完整演示,帮助大家更加方便理解docker的方便和强大之处。
docker简单来书是一个容器,能够把各种需要的环境或者软件仿放在里面,构建出一个我们所需要的的环境,并且每个容器是单独隔离的,不会影响,当我们在docker调试完毕,测试没有问题就,就可以打包成镜像资源,把这个镜像资源发给服务器或者其他人员,在服务器中导入就能直接运行。因为按照以前我部署过一个Flask Web服务,需要去服务配置和本地一样的环境,各种需要的东西都要手动配置,过程十分复杂,docker 的出现就是让部署更加简单,一次构建完成后, 可以免配置无限性次使用。
1.https://docker-doc.readthedocs.io/zh_CN/latest/index.html (官方文档)
2.http://www.dockerinfo.net/document(docker中文文档)
3.https://www.runoob.com/docker/docker-tutorial.html(菜鸟docker教程)
使用环境:Ubantu
为什么使用Ubantu喃,是因为公司算法小组自己用的服务器是Ubantu,同时我用的虚拟机是镜像也是Ubantu的,所以一切配置都是在Ubantu上面进行的,当然也可以windows或者其他linux系统上进行配置和安装。安装过程参考上面的Docker文档。里面有多种系统的安装教程。
在Linux上安装Docker比较方便,直接命令就可以了安装。
1.更新系统安装包:
sudo apt-get update
2.安装依赖包
$ sudo apt-get install \
apt-transport-https \
ca-certificates \
curl \
gnupg-agent \
software-properties-common
3.添加 Docker 的官方 GPG 密钥
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
4.设置稳定版仓库
$ sudo add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"
5.安装 Docker
$ sudo apt-get install docker-ce docker-ce-cli containerd.io
6.(重要)添加当前用户到 docker 用户组,这个必须设置,否则会使用过程,很多时候权限不足。
sudo groupadd docker
# 把当前用户加入到docker组中
sudo gpasswd -a ${USER} docker
# 重启docker服务
sudo service docker restart
7.验证是否安装成功 dokcer -v 如果像下面这样出现docker版本信息就代表安装成功
要搭建我们自己的环境(容器),需要在基础镜像上构建,所有容器都必须在一个基础镜像上构建,因为tornado本身就是http服务器,这点和Flask,Django不同,这两个需要gunicorn或者uwsigi配合部署,可能这就是tornado其中一个优点吧,省去了一个步骤,直接用python运行,就相当于部署完了。所以我这里需要一个python镜像,然后把镜像运行起来,成为一个容器,在里面安装tornado库,这就像我们在本地安装了一个python一样的。当然你需要其他镜像就拉去对应镜像的名字和版本就行,例如ubantu镜像,centenos镜像等。
拉取镜像:docker image pull+镜像名字
docker image pull python
因为我已经早就安装了,所以就不安装了,直接看所有镜像,可以看到拉取镜像没加版本的时候,会安装最新版本的。
运行镜像的同时就会创建基于当前镜像的容器,所以运行当前的python镜像。
docker run -t -i -p 5010:5010 --name tornado_server -v /home/label_data:/home/label_data 79cc46abd78d /bin/bash
参数解释:
-t -i允许输入和保持连接 --name 是表示对运行后的容器命名
-p 表示容器端口和主机端口的映射 -v表示是挂在目录,能够让容器中的文件夹映射到系统的文件夹,就能把数据储存到系统中
79cc46abd78d:表示的是运行的镜像ID /bin/bash表示的是能够使用命令交互操作
输入完成后,如果看到类似的界面,就表示创建容器成功~
因为我这个服务,只用到了tornado,其余也是python内置的库,所以只需要安装tornado即可,如果用到了其他库,用pip安装就行。同时-i 是试用国内镜像中国科技大学第三方安装源,这样速度更快。
pip install tornado -i https://pypi.mirrors.ustc.edu.cn/simple/
经过上面,tornado环境已经配置好了,现在要把项目代码放进容器,能够像我们使用pycharm本地运行一样。
1.首先退出当前配置好环境的容器,使用exit
2.查看当前项目文件所在目录,同时查看查看刚刚创建的容器ID docker ps -a
可以看到我刚刚创建的容器,能看到容器ID等信息
3.拷贝项目至容器
docker cp 项目文件路径 需要拷贝到容器ID:拷贝到容器路径地址
docker cp /home/lyt/桌面/部署/LabelTransferServer 9e074f96067b:/home/
解释:我把虚拟机上桌面上的部署文件夹里面的LabelTransfeServer文件夹放进容器9e074f96067b的home容器中/home/下。
4.项目结构
在LabelTransferServer项目中,Deploy中运行Server.py,就能把小项目运行起来,和pycharm中运行Server.py是等同的效果。
环境配置好了,项目代码放进去后,就能在容器中尝试运行起来这个http服务。
1.启动容器 docker start 容器ID
2.以终端方式进入容器 docker exec -it 容器ID /bin/bash
3.进入Deploy目录,用python执行 Server.py,就能把项目运行起来。可以看到我不断进入文件,最终进入Deploy中,运行起来,什么都没有。因为tornado本身的框架的特性,不会像Falsk,Django运行起来有日志信息。
4.Server.py服务源码
from abc import ABC
import tornado.httpserver
import tornado.ioloop
import tornado.log
import tornado.options
import tornado.web
from LabelFileTransferServer.LabelFileTransferServer import LabelFileTransferServer
from LabelFileTransferServer.Deploy.server_config import SAVE_PATH, DOWNLOAD_PATH
label_file_transfer_server = LabelFileTransferServer()
class LabelFileUpload(tornado.web.RequestHandler, ABC):
def post(self):
"""
从url上接收MD5和json文件流
"""
json_file_stream = self.request.files["json_file"][0]['body']
md5_value = self.get_query_argument("md5")
label_file_transfer_server.uploader(md5_value, json_file_stream, SAVE_PATH)
self.write("上传成功!")
class LabelFileDownload(tornado.web.RequestHandler, ABC):
def post(self):
"""
查询条件需要从url上接收
"""
query_conditions = self.get_query_argument('query')
file_url = label_file_transfer_server.downloader(query_conditions, DOWNLOAD_PATH)
self.write(file_url + '\n')
self.write("\n下载成功!")
def main():
application = tornado.web.Application([
(r"/uploader", LabelFileUpload),
(r"/downloader", LabelFileDownload),
])
http_server = tornado.httpserver.HTTPServer(application)
tornado.log.enable_pretty_logging()
http_server.listen(5010, address="0.0.0.0")
tornado.ioloop.IOLoop.instance().start()
if __name__ == '__main__':
main()
5.测试 可以看到上面的源码开放的也是5010端口和docker中端口开放的也是一样的,0.0.0.0允许任何人都可以访问我这个服务。
我这个有两个服务一个上传,一个下载,因为没有写HTML,就用postman测试这个服务。
就可以看到postman拿到了ubantu虚拟机的数据,同时ubantu接收到了post请求。
如果你只是想在自己的虚拟机上使用,其实就弄到这里的运行server就可以了,用个可以在后台持续运行的命令nohup就可以使用你的服务了,当然你要打包给别人用,或者再次部署到别的服务器,就需要打包成可以运行的镜像。
docker commit 容器ID 导出后镜像资源名:tag
docker commit 9e073f96067b tornado_server:origin
接下来查看一下镜像: 可以看到我们刚刚的配置能运行的服务,已经打包成镜像了。
docker images
如果你想把你的服务,部署在服务器上,不用再次部署,或者交给别人能直接使用,就需要用到Dockerfile。
1.新建一个文件夹 mkdir test
2.新建Dockerfile 用vi Dockerfile创建一个Dockerfile
FROM: 表示导入镜像,我把上面打包的容器镜像导入,再次构建镜像 EXPOSE:暴露5010端口
WORKDIR :用来切换工作目录 并且目录改变是持久不变的 Docker默认工作目录是/,这里要切换到Server.py的工作目录
ENTRYPOINT:启动容器中服务命令 ,因为我实际运行只需要,用python运行Server.py。所以这里用一个括号把当初在容器中运行服务的代码,放在这里括号里。
docker build -t name:tag (命名新的镜像名字:版本)
最后有个点,表示当前目录执行,不要忘了,之所以新建一个空文件夹,就是构建镜像防止不必要的东西导入进去。
docker build -t tornado_server:1.0.0 .
查看当前镜像:docker images
可以看到我们打包的1.0.0版本镜像构建成功,接下来我们去看看是否可以运行,如果可以运行,就表示这个镜像可以发给服务器,或者别人使用。
经过上面的dockerfile重新构建镜像, 接下来要去测试是否和我们自己在容器中效果是否一样,一样的话,就没问题了,可以打包压缩发给别人使用或者部署至服务器。
命令:docker run -idt -p 5010:5010 镜像ID
docker run -dit -p 5010:5010 4d38d180266f
参数解释: -d 是以守护进程方式放在后台持续运行,其余参数都是解释过的,不理解还可以去看文档。
运行后用docker ps 可以看到当前运行的容器。由于我这里运行的有两个项目,如果你运行起来能看到就表示成功,同样也以用postman请求。能够成功表示完全成功,我这里就不测试了。
可能我们服务器或者电脑会遇到断电等特殊情况,需要我们重新运行服务就很麻烦,所以需要设置自启动服务,就能自己启动。
需要在运行的时候加 --restart=always就能自启动了。
举个例子:
docker run -dit -p 5010:5010 -v /home/label_data:/home/label_data--restart=always --name upload_and_download_label_file_server + 镜像ID
上面的镜像就是能够直接使用的,我们需要打包成压缩包,别人用docker导入就可以使用或者可以直接部署服务器。
命令:docker save >名字.tar 镜像ID 或者 docker save -o 名字.tar 镜像ID
:docker save > tornado.tart 4d38d180266f
可以看到就是一个tar的压缩包了,如果想要部署到服务器,就把这个压缩包发送到服务器 ,然后用docker 导入后,就能看到镜像,直接用命令运行挂在后台就行了,最好加个自启动,应对断电等特殊情况,就可以自启动服务。