1.前言
在前面的技术文章中介绍了Dockerfile的基本应用,下面详细的介绍下通过Dockerfile来部署Python的应用程序的过程。本案例主要使用Python语言,使用的WEB框架是Flask,然后来实现一个网站的部署过程,也就是说写好程序代码好后,开发dockerfile的代码,执行以及生成镜像,其他人基于该镜像,docker run就可以在电脑跑起来对应的应用程序。
2.Flask案例代码
涉及到的Python的源代码具体如下:
from flask import Flask,make_response,jsonify,abort,request from flask_restful import Api,Resource from flask_httpauth import HTTPBasicAuth from flask import Flask from flask_jwt import JWT, jwt_required, current_identity from werkzeug.security import safe_str_cmp app=Flask(__name__) app.debug = True app.config['SECRET_KEY'] = 'super-secret' api=Api(app=app) auth=HTTPBasicAuth() @auth.get_password def get_password(name): if name=='admin': return 'admin' @auth.error_handler def authoorized(): return make_response(jsonify({'msg':"请认证"}),403) books=[ {'id':1,'author':'wuya','name':'Python接口自动化测试实战','done':True}, {'id':2,'author':'无涯','name':'Selenium3自动化测试实战','done':False} ] class User(object): def __init__(self, id, username, password): self.id = id self.username = username self.password = password def __str__(self): return "User(id='%s')" % self.id users = [ User(1, 'wuya', 'asd888'), User(2, 'stage', 'asd888'), User(3,'line','asd888') ] username_table = {u.username: u for u in users} userid_table = {u.id: u for u in users} def authenticate(username, password): user = username_table.get(username, None) if user and safe_str_cmp(user.password.encode('utf-8'), password.encode('utf-8')): return user def identity(payload): user_id = payload['identity'] return userid_table.get(user_id, None) jwt = JWT(app, authenticate, identity) class Books(Resource): # decorators = [auth.login_required] decorators=[jwt_required()] def get(self): return jsonify({'status':0,'msg':'ok','datas':books}) def post(self): if not request.json: return jsonify({'status':1001,'msg':'请求参数不是JSON的数据,请检查,谢谢!'}) else: book = { 'id': books[-1]['id'] + 1, 'author': request.json.get('author'), 'name': request.json.get('name'), 'done': True } books.append(book) return {'status':1002,'msg': '添加书籍成功','datas':book} # return jsonify({'status':1002,'msg': '添加书籍成功','datas':book}, 201) class Book(Resource): # decorators = [auth.login_required] decorators = [jwt_required()] def get(self,book_id): book = list(filter(lambda t: t['id'] == book_id, books)) if len(book) == 0: return jsonify({'status': 1003, 'msg': '很抱歉,您查询的书的信息不存在'}) else: return jsonify({'status': 0, 'msg': 'ok', 'datas': book}) def put(self,book_id): book = list(filter(lambda t: t['id'] == book_id, books)) if len(book) == 0: return jsonify({'status': 1003, 'msg': '很抱歉,您查询的书的信息不存在'}) elif not request.json: return jsonify({'status': 1001, 'msg': '请求参数不是JSON的数据,请检查,谢谢!'}) elif 'author' not in request.json: return jsonify({'status': 1004, 'msg': '请求参数author不能为空'}) elif 'name' not in request.json: return jsonify({'status': 1005, 'msg': '请求参数name不能为空'}) elif 'done' not in request.json: return jsonify({'status': 1006, 'msg': '请求参数done不能为空'}) elif type(request.json['done'])!=bool: return jsonify({'status': 1007, 'msg': '请求参数done为bool类型'}) else: book[0]['author'] = request.json.get('author', book[0]['author']) book[0]['name'] = request.json.get('name', book[0]['name']) book[0]['done'] = request.json.get('done', book[0]['done']) return jsonify({'status': 1008, 'msg': '更新书的信息成功', 'datas': book}) def delete(self,book_id): book = list(filter(lambda t: t['id'] == book_id, books)) if len(book) == 0: return jsonify({'status': 1003, 'msg': '很抱歉,您查询的书的信息不存在'}) else: books.remove(book[0]) return jsonify({'status': 1009, 'msg': '删除书籍成功'}) api.add_resource(Books,'/v1/api/books') api.add_resource(Book,'/v1/api/book/<int:book_id>') if __name__ == '__main__': app.run(debug=True,host='0.0.0.0')
3.Dockerfile文件
下来实现部署Python应用程序的Dockerfile文件,文件的内容具体如下:
FROM centos:7.8.2003 MAINTAINER 无涯 #下载yum RUN curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo; RUN curl -o /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo; #安装Python环境 RUN yum install python3-devel python3-pip -y #安装flask库 RUN pip3 install -i https://pypi.douban.com/simple flask RUN pip3 install flask_restful RUN pip3 install flask_httpauth RUN pip3 install flask_jwt #复制文件到容器目录 COPY app.py /opt #切换目录 WORKDIR /opt #启动服务 EXPOSE 5000 CMD ["python3","app.py"]
4.构建镜像
下来构建Dockerfile,具体构建命令以及执行过程如下:
docker build -t flask_web . #执行构建后,部分输出信息 ---> 654d11509ebb Step 7/10 : COPY app.py /opt ---> cf4f278d900b Step 8/10 : WORKDIR /opt ---> Running in 8dd988a4bf0d Removing intermediate container 8dd988a4bf0d ---> 6866628f23f7 Step 9/10 : EXPOSE 5000 ---> Running in 131bded2d074 Removing intermediate container 131bded2d074 ---> b7876c74dae4 Step 10/10 : CMD ["python3","app.py"] ---> Running in 498f6c4ab849 Removing intermediate container 498f6c4ab849 ---> 89f07acc5d97 Successfully built 89f07acc5d97 Successfully tagged flask_web:latest
5.运行容器
构建成功后,下来运行容器,具体详细过程如下:
[root@wuyaShare learnDocker]# docker run -it --rm -p 5000:5000 flask_web * Serving Flask app 'app' (lazy loading) * Environment: production WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. * Debug mode: on * Running on http://172.18.0.2:5000/ (Press CTRL+C to quit) * Restarting with stat * Debugger is active! * Debugger PIN: 132-410-186
6.验证容器
测试代码具体如下,模块名称为test_app.py,源码为:
import requests def test_login(): r=requests.post( url='http://172.18.0.2:5000/auth', json={"username":"wuya","password":"asd888"}) assert r.status_code==200
验证结果信息如下:
python3 -m pytest -v test_app.py ============================== test session starts =============================== platform linux -- Python 3.7.1, pytest-6.2.5, py-1.10.0, pluggy-0.13.1 -- /usr/python37/bin/python3 collected 1 item test_app.py::test_login PASSED
服务端收到的请求信息具体如下:
172.18.0.1 - - [21/Oct/2021 10:55:50] "POST /auth HTTP/1.1" 200 -
感谢每一个认真阅读我文章的人,看着粉丝一路的上涨和关注,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:
① 2000多本Python电子书(主流和经典的书籍应该都有了)
② Python标准库资料(最全中文版)
③ 项目源码(四五十个有趣且经典的练手项目及源码)
④ Python基础入门、爬虫、web开发、大数据分析方面的视频(适合小白学习)
⑤ Python学习路线图(告别不入流的学习)
在我的QQ技术交流群里(技术交流和资源共享,广告进来腿给你打断)
可以自助拿走,群号913569736(备注“csdn000”)群里的免费资料都是笔者十多年测试生涯的精华。还有同行大神一起交流技术哦。