docker-py
docker-py copied to clipboard
network.containers raises docker.errors.NotFound
Details
Python
Version: 3.8.5
docker-py
Version: 4.4.0
Docker
Version: 20.10.6, build 370c289
Using Docker Desktop with WSL Backend and Windows 10 Version 20H2 (Build 19042.1348)
The Problem
For some reason network.containers
raises an docker.errors.NotFound
when executed:
This is the code:
print(self.docker_network)
print(self.docker_network.attrs)
print(self.docker_network.containers) # <- here it crashes.
Output:
<Network: 8ed90c045f>
{'Name': 'my-network', 'Id': '8ed90c045fb21381f193d2772030e21e02ed3bf7c368f40e0b60e92d8d8ef385', 'Created': '2022-01-28T09:19:54.2036542Z', 'Scope': 'local', 'Driver': 'bridge', 'EnableIPv6': False, 'IPAM': {'Driver': 'default', 'Options': None, 'Config': [{'Subnet': '172.19.0.0/16', 'Gateway': '172.19.0.1'}]}, 'Internal': False, 'Attachable': False, 'Ingress': False, 'ConfigFrom': {'Network': ''}, 'ConfigOnly': False, 'Containers': {'60eb864274beceb8649df2e507a7dad6c6139953f5f5ef8b612249ddf23eb084': {'Name': 'my-container', 'EndpointID': '8b902c88ee667a2bc1177a947a79a63dda98094e1db5a115ac0eab445140d063', 'MacAddress': '02:42:ac:13:00:02', 'IPv4Address': '172.19.0.2/16', 'IPv6Address': ''}}, 'Options': {}, 'Labels': {}}
docker.errors.NotFound: 404 Client Error for http+docker://localnpipe/v1.41/containers/c2ee758d369714df097e5394d33a41e73be9765845cf8a5deec0cd3147dd2d83/json: Not Found ("No such container: c2ee758d369714df097e5394d33a41e73be9765845cf8a5deec0cd3147dd2d83")
As it seems it searches for a container that does not exist. But there is something odd: The ID is always changing when I re-execute the code. But there is only 1 Container in that network. I really don't know where it is taking that ID from.
It seems to me that Network.containers looks for every container ID that it finds on the network then does a GET request for more detail. While it is still iterating over a list of IDs, and a container is removed, then Docker cannot find it any more, resulting in a 404.
Maybe we should use client.containers.list with a filter instead? I don't know Docker's API very well, but this could be atomic...
Workaround
Instead of doing
network = client.networks.get('my-network')
containers = network.containers
You can do
containers = client.containers.list(filters={'network': 'my-network'})
At least that's what worked for me. :)