对话机器人 Rasa(十八):使用 docker compose 及 dockerfile 部署 python flask 图片服务

更新日期: 2023-08-28 阅读次数: 1085 字数: 976 分类: docker

使用 Flask 的原因

因为我觉得用 Rasa 处理图片 base64 编码是不合理的,不适合 intent 识别,再者影响 rasa 接口的性能。

所以,独立出一个 flask 服务来处理图片上传的使用场景。

使用 docker 的原因

原本想在服务器上直接用自带的 python 3.8 部署一个 flask 服务,用来模拟一套接口, 方便 Rasa Actions 服务来调用测试数据。

其中 Rasa Actions 服务部署在 docker 容器中,但是其无法直接访问宿主机中的 flask 服务。

尝试了几种方式都不行,所以想干脆也把 flask 采用 docker 的部署方式。

host.docker.internal

StackOverflow 上很多人提到了 host.docker.internal 方案,以此访问宿主机的网络,但是我测试并不好使。

即,docker-compose.yaml 中给相应的 service 添加。

extra_hosts:
  - "host.docker.internal:host-gateway"

同时,接口调用时,使用 host.docker.internal 替换掉 localhost。

例如: http://host.docker.internal:5000

然而,我在 Ubuntu 20.04 Server + Docker version 24.0.2 上,并没有测试成功。

直接访问宿主网络并不推荐

因为宿主机被访问是一种很危险的行为!

Docker 容器默认使用的是桥接网络模式,即容器之间互相隔离,而且容器和宿主机之间也是隔离的。这种网络模式可以保证容器的安全性和独立性,但是也限制了容器的网络访问能力。

直接使用宿主机的网络可能会带来一些安全风险。如果容器能够直接访问宿主机的网络,攻击者可以通过容器攻击宿主机上的其他应用程序或数据。此外,直接使用宿主机的网络可能会导致网络冲突和性能问题。

那还是老老实实地用 docker 部署吧。

flask main.py

from flask import Flask

app = Flask(__name__)


@app.route("/")
def hello_world():
    return "<p>Hello, World!</p>"


if __name__ == "__main__":
    app.run(debug=True, host="0.0.0.0")

requirements.txt

Flask

最好加上版本号。

dockerfile

第一次写 dockerfile, 发现简单且实用。 这个文件放到 flask 项目的根目录。

FROM python:3
#RUN apt−get −y update
#RUN apt−get install −y pip3 build−essential
COPY . .
RUN pip install -r requirements.txt
ENTRYPOINT ["python"]
CMD ["main.py"]

好处是:

  • 规范了部署流程,比部署文档更好地实现了自动化
  • 可以放进 git 管理

需要注意的是,网上的 dockerfile 不要随便抄,一定要去 docker 官方网站去确认镜像的实用方法。

例如,这里的 pip3 的安装就是不必要的。所以注释掉了。

docker-compose.yml

假设 flask 代码在 api_demo 目录中。

version: '3.0'

services:
  rasa_core:
    ...

  action_server:
    ...

  api_demo:
    build: ./api_demo
    ports:
      - 5000:5000
    volumes:
      - ./api_demo:/code

localhost 地址修改

例如这里,需要对应的修改为 api_demo,如:

http://api_demo:5000/some_api

部署

把 flask 项目目录同步到服务器上之后,执行

docker compose up -d

即可。测试了一下确实接口访问正常了。

若之前的需要关闭,可以执行

docker compose stop

docker compose 如何只重启一个服务

docker compose restart [service_name]

或者

docker compose stop [service_name]
docker compose up -d [service_name]

更新代码不生效

需要注意的是,这样发布,即便 python main.py 文件发生变更,实际运行的代码也不会更新。

可以参考

https://stackoverflow.com/questions/62193878/docker-container-not-updating-on-code-change

先 stop 掉对应的 container, 然后重新 build

执行:

docker compose up xxx --build

或后台运行

docker compose up -d xxx --build

多并发支持

参考 生产服务器 Flask 多并发支持,基于 Gunicorn

TODO

  • 如何将接口地址区分开发环境和生产环境,依然实用 .env ?

查看合集

📖 对话机器人 Rasa 中文系列教程

参考

  • https://www.tutorialspoint.com/build-a-flask-app-using-docker-compose
  • 国内 docker hub 镜像 https://gist.github.com/y0ngb1n/7e8f16af3242c7815e7ca2f0833d3ea6

tags: rasa

关于作者 🌱

我是来自山东烟台的一名开发者,有敢兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊, 查看更多联系方式