有一个这样子的需求:前端页面输入IP:端口号,后端是Linux(Ubuntu 22.04.1)服务器,在此环境中装有docker,前端和此后端docker通信,发送post请求,服务器处理后返回。且需要将此post服务一直运行在后台。
实现思路:前端其实可以用postman模拟发送post请求,懒得整了,就网上找到了代码。也可以使用python代码,requests库中有get和post方法,这个get和post都是http请求方式,是为了模拟浏览器前端的操作。后端就flask库执行接收json请求,然后修改json,再return回去,想看return回去的json内容,print(response.content)即可。因为我们用了docker容器,所以应该写好代码后,再写好Dockerfile(一定是Dockerfile,注意D大写,其他小写,不要改任何一个字母,写的时候加上CMD,达到退出后也能后台运行的效果),然后使用pipreqs(不要pip freeze,不然会把Ubuntu自带的包装进去,到时候Dockerfile里pip requirements.txt就会失败),得到镜像后,将其run -d,注意要使用-d命令,让容器一直运行。这时候就OK了
实现方法:
前端:
1.模拟前端发送post请求,发送json。注意此次发送的192.168.xx.xx是虚拟机的IP。端口号定为5678,可根据自己需求更改。
import requests
import json
rdata={"lesson":"Operation System","score":100}
headers2 = {'Content-Type': 'application/json',
'Connection':'close'}
response = requests.post(url="http://192.168.XX.XXX:5678/sendjson",headers=headers2,data = json.dumps(rdata).encode("utf-8"),verify=False)
#返回200即为成功
print(response)
#查看返回的json内容
print(response.content)
后端Linux:
1.先执行apt update,如果没问题的话,可以直接安装docker。apt update有问题,需要查看Ubuntu版本,然后网上找下相关源。
2.确定docker安装成功: docker --version
3.新建目录,我这里目录结构如下:
进入f2后,执行 vim f2.py,代码如下,尤其注意app.run中,host写为0.0.0.0,不要写成虚拟机IP,不然可能会报 can not resign address的错误。
from flask import Flask,render_template,request,Response,jsonify
import json
app=Flask(__name__)
#写上method=POST,不然可能会报错的
@app.route('/sendjson', methods=['POST'])
def sendjson():
print(request.get_json())
print("###################")
# 接受前端发来的数据
data = json.loads(request.get_data("data"))
# lesson: "Operation System"
# score: 100
lesson = data["lesson"]
score = data["score"]
print(lesson,score)
# 自己在本地组装成Json格式,用到了flask的jsonify方法
info = dict()
info['name'] = "NIhao"
info['lesson'] = lesson
info['score'] = score
info['list']="array"
print(jsonify(info))
return jsonify(info)
if __name__ == '__main__':
app.run(host='0.0.0.0',port=5678,debug=True)
这时候光有代码是不够的。我们看下目录,还需要有requirements.txt和Dockerfile。
Dockerfile是手写的,执行 vim Dockerfile,一定不要改名字,不然后面识别不出来。Dockerfile里代码如下:CMD写上去,就可以在docker运行的时候,自动运行我们写好的f2.py了。
FROM python:3.10-slim
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt -i http://mirrors.aliyun.com/pypi/simple --trusted-host mirrors.aliyun.com
COPY . /app
WORKDIR /app
#CMD写进去,容器运行后,这段代码也会自动运行。
CMD [ "python", "f2.py" ]
下面是requirements.txt。我们步骤如下:
先安装pipreqs
pip install pipreqs -i http://mirrors.aliyun.com/pypi/simple --trusted-host mirrors.aliyun.com
然后执行以下代码,就可以自动生成requirements.txt
pipreqs ./ --encoding=utf8
像我这里,就只有Flask 环境,python自带的环境,都在Dockerfile的FROM python里包括了
执行完这些后,我们f2的目录下就有了
在f2的目录下,我们开始制作镜像。
docker build -t h_flask:v2 .
我们会得到一个image,比如我的是 ad75·····f3
再执行以下命令,将net=host,后面的/bin/bash写上,
docker run -it --net=host -p 5678:5678 -d --name=houduan ad75f08c0ef3 /bin/bash
执行上述代码后,这时候我们docker ps,就可以看到这个容器是运行的。注意,docker ps查到的是运行后的docker,而docker ps -a是所有的容器,很多情况下如果说docker xxx is not running,就是没加/bin/bash
至此,我们就都写完了。下面来检验一下看看结果。
先验证下,我们已经运行了这个叫做houduan的容器,那么他会自动使用5678端口监听。还有需要注意,lsof命令要在root的权限下运行才能有结果。执行 lsof -i:5678 可以看到代码已经在自动运行了
这时候,我们前端执行发送post的代码,response 200,成功返回,并且看到了json内容。
忙活了一早上,从docker 0基础开始,总算完事了。