python - Docker 无法识别 asyncio_mqtt?
问题描述
我目前正在将我的代码转换为 docker 图像,以基于传感器控制灯光。我在这方面是个新手。它在本地运行,但是当我使用 docker build 将其转换为带有此 dockerfile 的图像时:
#set base image (host OS)
FROM python:3.8-slim
# set the working directory in the container
WORKDIR /code
# copy the dependencies file to the working
directory
COPY requirements.txt .
# install dependencies
RUN pip install -r requirements.txt
# copy the content of the local src directory to the working directory
COPY src/ .
# command to run on container start
CMD [ "python", "./main.py"]
我收到以下错误:
Traceback (most recent call last):
File "/usr/local/lib/python3.8/site-
packages/asyncio_mqtt/client.py", line 79, in
connect
await loop.run_in_executor(None,
self._client.connect, self._hostname, self._port,
60)File
"/usr/local/lib
/python3.8/concurrent/futures/thread.p y", line
57, in run
result = self.fn(*self.args, **self.kwargs)
File "/usr/local/lib/python3.8/site-
packages/paho/mqtt/client.py", line 941, in
connect
return self.reconnect()
File "/usr/local/lib/python3.8/site-
packages/paho/mqtt/client.py", line 1075, in
reconnect
sock = self._create_socket_connection()
File "/usr/local/lib/python3.8/site-
packages/paho/mqtt/client.py", line 3546, in
_create_socket_connection
return socket.create_connection(addr,
source_address=source, timeout=self._keepalive)
File "/usr/local/lib/python3.8/socket.py", line
787, in create_connection
for res in getaddrinfo(host, port, 0,
SOCK_STREAM):
File "/usr/local/lib/python3.8/socket.py", line
918, in getaddrinfo
for res in _socket.getaddrinfo(host, port,
family, type, proto, flags):
socket.gaierror: [Errno -2] Name or service not
known
在处理上述异常的过程中,又出现了一个异常:
Traceback (most recent call last):
File "./main.py", line 89, in <module>
asyncio.run(main())
File
"/usr/local/lib/python3.8/asyncio/runners.py",
line 44, in run
return loop.run_until_complete(main)
File
"/usr/local/lib/
python3.8/asyncio/base_events.py", line 616, in
run_until_complete
return future.result()
File "./main.py", line 86, in main
await asyncio.gather(*tasks)
File "./main.py", line 26, in sub_and_listen_task
async with Client(self.broker) as client:
File "/usr/local/lib/python3.8/site-
packages/asyncio_mqtt/client.py", line 324, in
__aenter__
await self.connect()
File "/usr/local/lib/python3.8/site-
packages/asyncio_mqtt/client.py", line 88, in
connect
raise MqttError(str(error))
asyncio_mqtt.error.MqttError: [Errno -2] Name or
service not known
据我所知,基本上服务未知,连接。问题是我之前做过这个并且它有效但是现在当我运行完全相同的dockerfile并且我在portainer中查看它正在运行的python 3.8.10而不是3.8.9(工作容器运行3.8.9而不工作的容器是运行 3.8.10),这是我能检测到的唯一区别。我尝试删除旧的 python 图像,但我不知道如何专门获取 3.8.9(如果这甚至是导致此问题的问题)。
除此之外,我的代码基于 asyncio_mqtt。在我指定的需求文件中:
orjson==3.5.1
asyncio_mqtt==0.8.1
连接、发布等代码如下:
class mqtt_task():
def __init__(self, broker, subscription):
self.broker = broker
self.subscription = subscription
async def sub_and_listen_task(self):
async with Client(self.broker) as client:
self.client = client
async with client.filtered_messages(self.subscription) as
messages:
await client.subscribe(self.subscription)
async for message in messages:
if "ON" in message.payload.decode("utf-8"):
space_name = config[0]
spaces[space_name].moved()
async def publish_msg(self, space_name, state):
msg = {'state': state}
try:
await self.client.publish(space_name + '/desired/light' ,
orjson.dumps(msg))
except AttributeError as ex:
print('Unable to publish to ' + space_name +
'/desired/light')
#print(ex)
mqtt = mqtt_task(broker_local, subscription_local)
class SpaceCode:
def __init__(self, name):
self.name = name
self.event = asyncio.Event()
self.task = asyncio.create_task(self.motion_task())
def moved(self):
print('Movement detected...')
self.event.set()
async def movement_detected(self):
await self.event.wait()
self.event.clear()
async def motion_task(self):
while True:
await mqtt.publish_msg(self.name, 'on')
print('TURNING ON.... ' + self.name)
try:
await asyncio.wait_for(self.movement_detected(), timeout=time_untill_dim)
continue
except asyncio.TimeoutError:
print('TIMEOUT...DIMMING ' + self.name)
await mqtt.publish_msg(self.name, 'dim')
try:
await asyncio.wait_for(self.movement_detected(), timeout=time_untill_shutoff)
continue
except asyncio.TimeoutError:
print('TIMEOUT...TURNING OFF ' + self.name)
await mqtt.publish_msg(self.name, 'off')
await self.movement_detected()
spaces = dict()
async def main():
tasks = []
for name in config:
spaces[name] = SpaceCode(name)
tasks.append(mqtt.sub_and_listen_task())
for t in spaces.values():
tasks.append(t.task)
print(tasks)
await asyncio.gather(*tasks)
if __name__ == "__main__":
asyncio.run(main())
对于任何反馈,我们都表示感谢!
解决方案
@hardillb 是对的,错误消息与连接问题有关。由于在 docker 内它不在 docker 内的正确网络中,因此代理永远无法连接。
推荐阅读
- javascript - 如何将我的 json 对象插入 Google 图表行
- python - 存储要以加密形式存储的原始未加密文件的 sha256 哈希是否安全?
- wordpress - 过滤 Gutenberg 块编辑器控件
- google-chrome-devtools - puppeteer 中的性能分析
- unix - 将代码行转换为 usb 上 archlinux 的脚本(dos2unix 和 $HOME 不起作用)
- excel - 以 Excel 表格格式从 Excel 复制并粘贴到 Power Point(“保留源格式”)
- flutter - 我们如何使用 SHA256 或在 iOS 和 Android 中的 Flutter 中从相同的字符串生成相同的哈希码?
- ionic4 - 尝试使用 ngIf 显示离子标签
- r - 在 R 中使用 tempfile() 创建的临时文件会发生什么情况?
- node.js - 解析配置打字稿文件时跳过发射