I'm trying to create a Docker image with a /dev/net/tun
device so that the image can be used across Linux, Mac and Windows host machines. The device does not need access to the host's network interface.
Note that passing --device /dev/net/tun:/dev/net/tun
to docker run
is undesirable because this only works on Linux.
Once the container is started, I can manually add the device by running:
$ sudo mkdir /dev/net
$ sudo mknod /dev/net/tun c 10 200
$ sudo ip tuntap add mode tap tap
but when I add these lines to the Dockerfile it results in an error:
Step 35/46 : RUN mkdir /dev/net
---> Running in 5475f2e4b778
Removing intermediate container 5475f2e4b778
---> c6f8e2998e1a
Step 36/46 : RUN mknod /dev/net/tun c 10 200
---> Running in fdb0ed813cdb
mknod: /dev/net/tun: No such file or directory
The command '/bin/sh -c mknod /dev/net/tun c 10 200' returned a non-zero code: 1
I believe the crux here is creating a filesystem node from within a docker build
step? Is this possible?
I managed to work around this by programmatically creating the TUN device in our software that needs it (which are mostly unit tests). In the setup of the program we can create a temporary file node with major/minor code 10/200:
and then in the tear-down of the program we close and delete the temporary file.
One issue remaining is this program only works when run as the root user because the program doesn't have
cap_net_admin,cap_net_raw
capabilities. Another annoyance that can be worked-around.