如何将 docker 快速 api 与 mqtt 代理连接?
How to connect the docker fast api with mqtt broker?
没有 docker,我可以将我的 fastapi 应用程序与 mqtt 代理连接。但是,对于 docker,我无法将我的 fastapi 应用程序与 docker mqtt 代理连接。我收到错误 -
{"log":" ', '.join(str(exc) for exc in exceptions)))\n","stream":"stderr","time":"2022-02-21T04:42:21.137558005Z"}
{"log":"OSError: Multiple exceptions: [Errno 111] Connect call failed ('127.0.0.1', 1883), [Errno 99] Cannot assign requested address\n","stream":"stderr","time":"2022-02-21T04:42:21.137562299Z"}
{"log":"\n","stream":"stderr","time":"2022-02-21T04:42:21.137566492Z"}
{"log":"ERROR: Application startup failed. Exiting.\n","stream":"stderr","time":"2022-02-21T04:42:21.137570669Z"}
这是我的main.app
from fastapi import FastAPI
from fastapi_mqtt import FastMQTT, MQTTConfig
from pydantic import BaseModel
from ipaddress import IPv4Address
import jsonpickle
app = FastAPI()
class Nmap(BaseModel):
host: IPv4Address
portRange: str
class Config:
schema_extra = {
"example" : {
"host": "10.0.2.15",
"portRange": "22-80",
"description": "Scan the port from 22 to 80 of the ip address 10.0.2.15"
}
}
mqtt_config = MQTTConfig()
mqtt = FastMQTT(config=mqtt_config)
mqtt.init_app(app)
@mqtt.on_connect()
def connect(client, flags, rc, properties):
mqtt.client.subscribe("/mqtt/toModel/#") # subscribing mqtt topic wildcard- multi-level
print("connected: ", client, flags, rc, properties)
@mqtt.on_message()
async def message(client, topic, payload, qos, properties):
print("received message: ", topic, jsonpickle.decode(payload.decode()), qos, properties)
return 0
@mqtt.on_disconnect()
def disconnect(client, packet, exc=None):
print("Disconnected")
@mqtt.on_subscribe()
def subscribe(client, mid, qos, properties):
print("subscribed", client, mid, qos, properties)
@app.get("/")
async def func():
mqtt.client.publish("/mqtt", "Hello from fastApi")
return {"result": True, "message": "Published"}
@app.post("/scan/{host}")
async def scan_host_port(nmap_details : Nmap):
results = {"got_val" : nmap_details}
print(type(nmap_details))
mqtt.client.publish("/mqtt/fromModel/nmap", jsonpickle.encode(nmap_details))
return results
这是我的应用 docker 文件 -
FROM python:3.7
WORKDIR /code
COPY ./requirements.txt /code/requirements.txt
RUN pip install -r /code/requirements.txt
COPY ./app /code/app
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
对于 MQTT,我使用 -
docker-compose.yml
version: "3"
services:
mqtt:
image: toke/mosquitto
network_mode: bridge
container_name: mqtt
expose:
- 1883
ports:
- 1883:1883
restart: unless-stopped
我确定这与我的 docker 有关,但我不知道如何部署 it.My 我的理解是 docker 旨在 运行 单个过程。因此,一个过程用于代理,另一个 docker 简单地 运行 我的快速 api 另一个 docker 用于 nginx
127.0.0.1
始终指向当前代码绑定到的 TCP/IP 堆栈。
每个 Docker 容器都有自己的 TCP/IP 堆栈。因此,如果您尝试从 python 容器连接到 127.0.0.1
,则在它自己的 TCP/IP 堆栈的端口 1883 上将没有 MQTT 代理 运行。
你应该让两个容器在同一个 docker compose 文件中使用相同的网络(如果需要,容器可以绑定到多个网络)然后你可以用代理的三个服务名称替换 IP 地址例如mqtt
version: '3.5'
services:
mqtt:
image: toke/mosquitto
container_name: mqtt
expose:
- 1883
ports:
- 1883:1883
restart: unless-stopped
networks:
- my_network
fast:
container_name: fast
expose:
- 8000
networks:
- my_network
ports:
- 8000:8000
restart: unless-stopped
build:
context: .
dockerfile: Dockerfile
depends_on:
- mqtt
networks:
my_network:
driver: bridge
没有 docker,我可以将我的 fastapi 应用程序与 mqtt 代理连接。但是,对于 docker,我无法将我的 fastapi 应用程序与 docker mqtt 代理连接。我收到错误 -
{"log":" ', '.join(str(exc) for exc in exceptions)))\n","stream":"stderr","time":"2022-02-21T04:42:21.137558005Z"}
{"log":"OSError: Multiple exceptions: [Errno 111] Connect call failed ('127.0.0.1', 1883), [Errno 99] Cannot assign requested address\n","stream":"stderr","time":"2022-02-21T04:42:21.137562299Z"}
{"log":"\n","stream":"stderr","time":"2022-02-21T04:42:21.137566492Z"}
{"log":"ERROR: Application startup failed. Exiting.\n","stream":"stderr","time":"2022-02-21T04:42:21.137570669Z"}
这是我的main.app
from fastapi import FastAPI
from fastapi_mqtt import FastMQTT, MQTTConfig
from pydantic import BaseModel
from ipaddress import IPv4Address
import jsonpickle
app = FastAPI()
class Nmap(BaseModel):
host: IPv4Address
portRange: str
class Config:
schema_extra = {
"example" : {
"host": "10.0.2.15",
"portRange": "22-80",
"description": "Scan the port from 22 to 80 of the ip address 10.0.2.15"
}
}
mqtt_config = MQTTConfig()
mqtt = FastMQTT(config=mqtt_config)
mqtt.init_app(app)
@mqtt.on_connect()
def connect(client, flags, rc, properties):
mqtt.client.subscribe("/mqtt/toModel/#") # subscribing mqtt topic wildcard- multi-level
print("connected: ", client, flags, rc, properties)
@mqtt.on_message()
async def message(client, topic, payload, qos, properties):
print("received message: ", topic, jsonpickle.decode(payload.decode()), qos, properties)
return 0
@mqtt.on_disconnect()
def disconnect(client, packet, exc=None):
print("Disconnected")
@mqtt.on_subscribe()
def subscribe(client, mid, qos, properties):
print("subscribed", client, mid, qos, properties)
@app.get("/")
async def func():
mqtt.client.publish("/mqtt", "Hello from fastApi")
return {"result": True, "message": "Published"}
@app.post("/scan/{host}")
async def scan_host_port(nmap_details : Nmap):
results = {"got_val" : nmap_details}
print(type(nmap_details))
mqtt.client.publish("/mqtt/fromModel/nmap", jsonpickle.encode(nmap_details))
return results
这是我的应用 docker 文件 -
FROM python:3.7
WORKDIR /code
COPY ./requirements.txt /code/requirements.txt
RUN pip install -r /code/requirements.txt
COPY ./app /code/app
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
对于 MQTT,我使用 -
docker-compose.yml
version: "3"
services:
mqtt:
image: toke/mosquitto
network_mode: bridge
container_name: mqtt
expose:
- 1883
ports:
- 1883:1883
restart: unless-stopped
我确定这与我的 docker 有关,但我不知道如何部署 it.My 我的理解是 docker 旨在 运行 单个过程。因此,一个过程用于代理,另一个 docker 简单地 运行 我的快速 api 另一个 docker 用于 nginx
127.0.0.1
始终指向当前代码绑定到的 TCP/IP 堆栈。
每个 Docker 容器都有自己的 TCP/IP 堆栈。因此,如果您尝试从 python 容器连接到 127.0.0.1
,则在它自己的 TCP/IP 堆栈的端口 1883 上将没有 MQTT 代理 运行。
你应该让两个容器在同一个 docker compose 文件中使用相同的网络(如果需要,容器可以绑定到多个网络)然后你可以用代理的三个服务名称替换 IP 地址例如mqtt
version: '3.5'
services:
mqtt:
image: toke/mosquitto
container_name: mqtt
expose:
- 1883
ports:
- 1883:1883
restart: unless-stopped
networks:
- my_network
fast:
container_name: fast
expose:
- 8000
networks:
- my_network
ports:
- 8000:8000
restart: unless-stopped
build:
context: .
dockerfile: Dockerfile
depends_on:
- mqtt
networks:
my_network:
driver: bridge