Reputation: 83
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.
Upvotes: 5
Views: 8572
Reputation: 83
Actually with time i found another solution to the problem. If you want to have your devices mounted, without exactly knowing their names, you can use:
services:
service:
devices:
- /dev:/dev
This simple solution allows all devices to be mounted but you would need to change their permissions beforehand or add privileged
. Another fun part is that once you mount it if the device is disconnected, then you start your container and then connect the device, the container will not know about this device and you would need to restart for it to pick it up.
Upvotes: 2
Reputation: 9402
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
Upvotes: 3