Docker 不认识 asyncio_mqtt?
Docker not recognizing asyncio_mqtt?
我目前正在将我的代码转换为 docker 图像以基于传感器控制灯光。我在这方面是个新手。它 运行 在本地,但是当我使用 docker build .:
使用此 docker 文件将其转换为图像时
#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
根据我的理解,连接上的服务基本上是未知的。问题是我以前做过这个并且它有效但是现在当我 运行 完全相同的 docker 文件并且我在 portainer 中查看它的 运行ning python 3.8.10 3.8.9 的(工作容器 运行 3.8.9 而不工作的容器是 运行ning 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.
内的正确网络中,因此代理永远无法连接
我目前正在将我的代码转换为 docker 图像以基于传感器控制灯光。我在这方面是个新手。它 运行 在本地,但是当我使用 docker build .:
使用此 docker 文件将其转换为图像时#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
根据我的理解,连接上的服务基本上是未知的。问题是我以前做过这个并且它有效但是现在当我 运行 完全相同的 docker 文件并且我在 portainer 中查看它的 运行ning python 3.8.10 3.8.9 的(工作容器 运行 3.8.9 而不工作的容器是 运行ning 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.
内的正确网络中,因此代理永远无法连接