The driver runs fine on the host, then finds nothing once you move it into a container. That is rarely an SDK bug: an Ethernet 3D camera is discovered over the network, and a container gets its own network namespace by default, cut off from the UDP broadcast or multicast the driver relies on. This guide is for anyone containerizing a vision cell or AGV computer that talks to a networked depth camera, ToF sensor or laser profiler. You will pick between host networking, macvlan and a bridged network with published ports, run the driver, and prove streaming with a packet capture and the camera's frame counter — including the bandwidth arithmetic that tells you whether one port can carry the stream at all.
The decision: put the container on the camera's network
One rule decides everything below: every packet the driver sends — its discovery query and its control commands — and every reply and data packet the camera sends back must cross the same physical NIC and subnet, from inside the container's namespace. There are three ways to arrange that:
| Network mode | Discovery works inside the container? | Isolation | Use it when |
|---|---|---|---|
| Host networking | Yes — the container shares the host NICs | None | Default on a dedicated cell or vehicle PC |
| macvlan | Yes — the container gets its own IP on the camera's subnet | High, per network | You must keep the container off the host network stack |
| Bridge + published ports | No for broadcast discovery; direct-IP connection only | High | Policy forbids host networking and the driver accepts a camera IP |
The reason ping proves nothing: discovery in GenICam-style drivers and most ToF SDKs is a link-layer UDP broadcast or multicast, which does not cross a default bridge. Our GenICam discovery walkthrough shows why a successful ping with an empty device list is the normal case, not a contradiction.
Decision: default to --network host. Leave it only for a documented isolation requirement, and then use macvlan on a dedicated NIC — not a published-port bridge, unless the SDK cannot work any other way.
What you need
- The camera on a fixed IP address, set with the manufacturer's own configuration tool, and the subnet it sits on.
- One host NIC on that same subnet, with its interface name written down (
ip addrprints it; the examples below useenp2s0). - The driver image, built from the SDK the camera's manufacturer distributes, with its behaviour known: does it discover by broadcast, and does it accept a direct camera IP?
-
tcpdumpon the host, plus a view of the camera's frame counter or status page. - Sudo on the host.
The steps are identical for any Ethernet depth camera, ToF sensor or laser profiler; the ToF class the card below belongs to is one example from the 3D sensors range.
- Type
- Depth / ToF camera
Step 1: pin the camera's address and put the host NIC on its subnet
- Set the camera to a fixed address on the cell subnet — for example
192.168.10.20/24, an example subnet used throughout; substitute yours — with the manufacturer's configuration tool. Do not leave it on DHCP: a new lease after a reboot silently changes the subnet your container is bound to. - Put one host NIC on the same subnet, for example
192.168.10.10/24, and record the interface name. - Check reachability from the host:
ping 192.168.10.20must answer. This is the last time ping is evidence of anything; from here it only proves the host side of the path. - Keep the office or IT NIC on its own subnet. Discovery queries go to the broadcast address of the camera's subnet —
192.168.10.255for a /24 — or to the multicast group the SDK documentation names, and they must leave on the interface that owns that subnet.
If the camera answers but frames later arrive slowly, the path between subnets is usually the cause; the depth camera latency diagnosis takes that failure apart.
Step 2: host networking, the default answer
docker run --rm -it --network host \
--cap-add NET_RAW --cap-add NET_ADMIN \
your-camera-driver:latest
--network host removes the separate network namespace: sockets inside the container bind the host's interfaces, so the discovery broadcast to 192.168.10.255 leaves enp2s0 exactly as it would from a host-installed driver. NET_RAW and NET_ADMIN cover drivers that open raw sockets for discovery or set interface parameters; drop the flags if your SDK does not need them.
If the driver is a ROS node, ROS_MASTER_URI still points at your master and topics publish normally — the camera path and the ROS topic path are independent.
Run the SDK's discovery or device list now. The camera appears with its address, or you go to the verification section below.
Step 3: macvlan, one container per camera subnet
docker network create -d macvlan \
--subnet=192.168.10.0/24 --gateway=192.168.10.1 \
-o parent=enp2s0 camnet
docker run --rm -it --network camnet --ip 192.168.10.50 \
your-camera-driver:latest
The container now has its own address on the camera's link, so broadcast and multicast reach it in both directions. Pick the --ip address inside the subnet and outside any DHCP pool; the gateway is only needed if the driver must also route off-subnet.
One behaviour to plan for: the host cannot address the macvlan container over the parent interface by default. That is the isolation you asked for — reach the container from your second interface, or not at all.
Step 4: bridged network with published ports, only for direct-IP drivers
A default bridge hands the container an address like 172.17.0.5 on docker0, and -p then publishes individual ports:
docker run --rm -it -p 50000:50000/udp -p 50001:50001/tcp \
your-camera-driver:latest
The port numbers above are placeholders; publish the TCP and UDP ports your SDK documentation lists. Understand what this mode cannot do: the driver's discovery query is a subnet broadcast, and it does not reach the camera's link from the bridge. This path works only when the driver lets you type the camera's IP address directly. Then the stream needs a destination the container actually owns — set the camera's stream-target address to the host IP and publish the data ports, because the camera sends its data where it was configured to, not where the request came from.
For a GigE Vision camera the stream-side addressing is its own subject; the multicast receiver setup article covers it. We treat this bridge mode as the fragile option and use it only when policy forbids the first two.
Verify: packet capture first, frame counter second
- Capture the camera's NIC while the driver starts:
sudo tcpdump -n -i enp2s0 udp. You want the query leaving and the reply returning within milliseconds. Query leaves, no reply: wrong subnet or a VLAN between them. Reply reaches the host but the container still finds nothing: your container is still on the bridge — go back to Step 2 or 3. - Watch the stream settle:
sudo tcpdump -n -i enp2s0 host 192.168.10.20. A steady packet rate at the size your pixel format implies should appear within a second. A stream that starts and stalls after a few seconds almost always means the camera is sending to a destination the container does not own — set the stream target as in Step 4. - In the driver's status view, confirm the frame counter increments at the expected rate with a drop counter that stays at zero. The capture proves packets arrive; the counter proves the pipeline keeps them.
Will one Ethernet port carry the stream?
That is 29.5% of a 1,000 Mbit/s GigE port. We plan camera ports at no more than about 70% of line rate for 3D streams, so one port takes two such cameras (59%) and not three (88.5%). The same inputs on a 1280 × 960 sensor scale by exactly four: 1,228,800 px × 2 B × 2 images × 30 /s × 8 ≈ 1,180 Mbit/s, past one GigE port — use a 2.5 or 10 Gbit/s port, or drop the frame rate or image count.
Splitting camera groups across ports is the fix, and port count is how we size the host machine: the controller below carries five or more LAN ports with PoE camera ports, so each camera group gets its own link.
- LAN ports
- 5+ LAN ports
- USB 3 ports
- 3-4 USB 3 ports
- PoE
- PoE camera ports
- Light outputs
- 8 built-in channels
Five mistakes that cost an afternoon
- Trusting ping. Unicast ICMP follows the route table; broadcast discovery follows the link. A green ping with an empty device list means a container network problem, not a camera problem.
-
Container and camera on different subnets. The bridge's
172.17.0.xand the camera's192.168.10.xnever exchange broadcasts. Test:docker inspectthe running container and read its address; if it is not on the camera's subnet, Step 2 or 3 applies. - Two NICs holding the same subnet. The kernel answers on the wrong interface and the driver's sockets behave unpredictably. Give each camera group its own subnet; the duplicate discovery diagnosis covers the multi-interface case.
- Two owners, one camera. A leftover host-side driver process still holds the control session; the container finds the camera but configuration fails mid-stream. Stop the host copy, restart the container.
- Fixing the network when the image is broken. If discovery works and the SDK then crashes or fails to load its libraries, networking is solved and the container itself is not. The 3D camera control software in Docker article handles that failure — startup, libraries and paths — separately from this one.
When the camera is not on the network
USB and CSI depth cameras need the device passed into the container, not a network path: pass the V4L2 media nodes, not just /dev/video0, and the CDI device specification shows the declarative way for USB. Mixing the two approaches on one host is fine — an Ethernet profiler on host networking beside a USB ToF camera passed in by device.
If you are sizing the computer that runs these containers, start at the vision controllers — multiple camera ports, built-in light channels, fanless industrial builds — or work the camera-to-computer configurator end to end. For a build that matches no card, contact us with the camera SDK and base image you run, and we will spec the port count and network layout with you.
Questions
Why does ping reach the camera but the driver still finds nothing?
Ping is a unicast exchange that follows the host's route table, while discovery is a UDP broadcast or multicast that must leave on the camera's own link and be answered there. A default bridge network keeps the container off that link, so the query never reaches the camera or the reply never returns. Put the container on the camera's network with host networking or macvlan and the device list fills in.
Can two containers share one Ethernet 3D camera?
Treat the camera's control channel as single-owner. Whichever process opens discovery and configuration first holds the session, and a second client that reconfigures the camera mid-stream breaks the first one's frames. Run one container that owns the camera and republish its frames to other consumers, or give the second container its own camera on its own port and subnet. Two drivers pointed at one camera is a race, not a design.
Does Power over Ethernet change any of this?
No. PoE only feeds the camera power; to the software it is still an Ethernet device on its subnet. The container still needs host or macvlan networking on that subnet, and the host still needs a PoE port or an injector behind the camera. Several vision controllers include PoE camera ports, which removes the injector and puts the camera on a port you can dedicate to the container.
Is host networking acceptable in production?
On a dedicated cell or vehicle computer, yes, and it is what we default to. The cost is isolation: the container shares every host interface and port, so a service inside it can collide with the PLC link or other listeners. If that matters, use macvlan on a dedicated camera NIC — you keep the camera path and lose almost none of the isolation. Avoid host networking on a shared server that runs unrelated workloads.
What if the camera's default subnet is unreachable from the container?
Readdress one side rather than routing between them. Many industrial cameras ship on a 192.168.x.x default; put the host NIC on that subnet, or set a permanent address on your cell subnet with the vendor's configuration tool. Routing through the host works for unicast streaming but still breaks broadcast discovery, so it hides the problem instead of fixing it. Fixed camera address, fixed NIC address, container on that NIC.

