I have this docker-compose service that i am trying to make work.
app:
build: ./
volumes:
- .:/app:delegated
devices:
- ${DEVICE:-/dev/null}:-/dev/ttyUSB*
Response when running docker-compose up app
Error response from daemon: error gathering device information while adding custom device "/dev/ttyUSB*": no such file or directory
The idea here is to get all devices that match /dev/ttyUSB*
from local and create them inside the container. This way i can have 0-N devices in the container, handling scenarios when no devices are connected. Also I do not have to know each device's tty<id>
I have read some old answers like this one : mapping all available devices in docker-compose but these either use
--privileged
or do not answer the question of how to get (all | no devices) copied and accessible.
I am aware that:
app:
build: ./
volumes:
- .:/app:delegated
devices:
- ${DEVICE:-/dev/null}:-/dev/ttyUSB0
works but not when the device is assigned a different number, hence the need to map them all.
docker-compose
able to read YAML
from STDIN
so just generate it on the fly.
Let's say that our original file is:
abc:
container_name: abc
image: alpine
entrypoint: ["watch", "-n", "5", "ls"]
And devices are:
$ ls -l /dev/ttyS*
crw-rw-rw- 1 root root 4, 64 Nov 11 09:34 /dev/ttyS0
crw-rw-rw- 1 root root 4, 65 Nov 11 09:34 /dev/ttyS1
crw-rw-rw- 1 root root 4, 66 Nov 11 09:34 /dev/ttyS2
crw-rw-rw- 1 root root 4, 67 Nov 11 09:34 /dev/ttyS3
So, let's add these device to YAML
:
$ printf '%s\n%s' "$(cat docker-compose.yml)" "$(if [ "$(ls /dev/ttyS*)x" != "x" ]; then echo -e " devices:"; for D in /dev/ttyS*; do echo " - ${D}:${D//ttyS/ttyUSB}"; done; fi )"
will print:
abc:
container_name: abc
image: alpine
entrypoint: ["watch", "-n", "5", "ls"]
devices:
- /dev/ttyS0:/dev/ttyUSB0
- /dev/ttyS1:/dev/ttyUSB1
- /dev/ttyS2:/dev/ttyUSB2
- /dev/ttyS3:/dev/ttyUSB3
Now let's try to run docker container using STDIN
:
$ printf '%s\n%s' "$(cat docker-compose.yml)" "$(if [ "$(ls /dev/ttyS*)x" != "x" ]; then echo -e " devices:"; for D in /dev/ttyS*; do echo " - ${D}:${D//ttyS/ttyUSB}"; done; fi )" | docker-compose -f /dev/stdin -f docker-compose.yml up -d
Creating abc ... done
Let's attach to container and check devices:
$ docker exec -it abc sh
# ls -l /dev
...
crw-rw-rw- 1 root root 4, 64 Nov 11 11:06 ttyUSB0
crw-rw-rw- 1 root root 4, 65 Nov 11 11:06 ttyUSB1
crw-rw-rw- 1 root root 4, 66 Nov 11 11:06 ttyUSB2
crw-rw-rw- 1 root root 4, 67 Nov 11 11:06 ttyUSB3
...
Profit
Also, you can check this answer