本文主要是介绍Flask制作python web服务并用Cython打包再放进docker运行,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
项目需求
- 提供web api服务
- Cython打包
- 放进docker
- 部署在服务器上
1. 本地开发api
# -*- coding: utf-8 -*-
"""
一个简单的demo
Created on Mon Jan 10 11:39:08 2022
@author: Lenovo
"""
from flask import Flask, make_responseapp = Flask(__name__)
@app.route('/', methods=['GET'])
def hello_world():txt = 'Hellow World, this is my first docker api server'print(txt)response = make_response(txt)return responseif __name__ == '__main__':app.run('0.0.0.0', port=5000, debug=False, threaded=True)
本地跑通就可以尝试用Cython打包了。
2. Cython打包
Cython打包目的 1:隐藏源代码 2:提高运行效率。
先在服务器上安装Cython
pip install Cython==0.29.26
编辑一个新的setup.py文件
# -*- coding: utf-8 -*-
from distutils.core import setup
from Cython.Build import cythonize
'''
apiTest.py是需要打包的文件名,若有多个py文件可以放进循环依次打包
'''
setup(ext_modules = cythonize("apiTest.py"), )
在终端执行:
python setup.py build
等待执行完毕就可以看一个.c文件和build目录,进入build下lib开头的目录,可以看到打包好的.so文件了,它可以直接用来python import。
直接在该目录下新建mian.py作为docker运行的入口:
import apiTestapiTest.app.run('0.0.0.0', port=5000, debug=False, threaded=True)
准备工作完成,开始打包进docker
3. 打包成docker
确定依赖的包:
pip freeze > requirements.txt
但这样会使得requirements文件很冗余,安装时容易出各种问题。
建议:直接把需要安装的包手动填进requirements。或可以采用pipreqs
进行依赖库的识别,在项目的当前目录中执行
pipreqs ./ --encoding=utf8 --force
,pipreqs会检索目录下所有的.py
文件,并基于用到的依赖生成 requirements.txt
本demo只有:
Flask==1.1.2
然后开始编写DockerFile(直接在服务器上,无后缀)
FROM python:3.7.10
COPY . /app
WORKDIR /app
RUN pip install --upgrade pip -i https://pypi.tuna.tsinghua.edu.cn/simple
&& pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
EXPOSE 5000
ENTRYPOINT [“/bin/sh”, “-c”]
CMD [“python main.py”]
Dockerfile步骤解析:
- 以镜像python作为基础镜像,如果本地没有这个镜像,会自动从Docker Hub拉取。
注意python的版本要和Cython打包的版本一致,不然import无法识别module。 - 复制Dockerfile所在目录的所有文件,包括main.py,apiTest的.so文件和requirements.txt,到容器内的虚拟目录/app中。
- 指定容器的默认工作目录为/app。
RUN指令在创建镜像时执行,相当于给基础镜像增加了一个改动层,然后固化为新的只读层,添加到新的镜像中。 - 升级pip工具,为安装依赖包做准备(使用清华的python库镜像,提高速度)。
- 从requirements.txt安装python的第三方依赖包。
- 暴露容器的5000端口,因为本例是一个web服务,需要暴露端口。
- ENTRYPOINT给出程序入口命令,使容器可以表现的像一个可执行程序,本例使用sh –c作为默认程序。本来也可以使用python命令作为入口,但是容器内想使用重定位符获得输出日志,必须在sh –c “CMD”中使用重定位。这里踩坑无数,docker的容器日志用起来又太麻烦。
可以有两种形式:
ENTRYPOINT [“executable”, “param1”, “param2”] :推荐使用的 exec形式
ENTRYPOINT command param1 param2 :shell 形式 - CMD给出容器启动时默认执行的命令,如果有ENTRYPOINT,则为ENTRYPOINT提供参数;如果没有,则是完整的默认命令。有三种形式:
CMD [“executable”,“param1”,“param2”]:推荐使用的 exec 形式
CMD [“param1”,“param2”]:无可执行程序形式
CMD command param1 param2:shell 形式
在服务器上应有的文件:
- apiTest.cpython-37m-x86_64-linux-gnu.so
- Dockerfile
- main.py
- requirements.txt
在该文件夹下运行
docker build -t apitestserver:1.0 .
等待运行成功,docker就做成了。
4. 运行docker,测试
可以看到新打包的docker:
[root@host236 usr]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
apitestserver 1.0 cbe2a8f0dbd3 41 minutes ago 928MB
运行docker并暴露出端口5000:
docker run -d -p 5000:5000 apitestserver:1.0
若想进入docker:
docker run -it -p 5000:5000 apitestserver:1.0 sh
打开浏览器访问docker服务器IP:5000
这篇关于Flask制作python web服务并用Cython打包再放进docker运行的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!