我有一个用于处理来自传感器的数据的容器化应用程序。该传感器具有多种可能的串行至 USB 转换器之一,每个转换器都有自己的路径(
/dev/path/to/deviceA
等)。我希望容器能够检测插入了哪个转换器(并且不绑定到现有容器)并安装该转换器(无需用户明确告知)。不同转换器仅挂载路径不同;应用程序的其余部分行为相同。
启动容器时,检查每个可能的设备挂载,看看是否在
/dev/path/to/device
处找到设备。安装到找到的列表中的第一个并忽略其余的。如果没有找到设备,则构建错误。换句话说,
if (/dev/path/to/deviceA exists and available) {
mount "/dev/path/to/deviceA:/dev/tty/USB0"
} else if (/dev/path/to/deviceB exists and available) {
mount "/dev/path/to/deviceB:/dev/tty/USB0"
} else if (...
...
} else { // No known devices are plugged in
fail to build
}
目前
docker-compose.yml
有
devices:
- "/dev/path/to/deviceA:/dev/ttyUSB0"
- "/dev/path/to/deviceB:/dev/ttyUSB0" - "/dev/path/to/deviceB:/dev/ttyUSB0"
- "/dev/path/to/deviceC:/dev/ttyUSB0"
但是,我的用例是用于检测几种可能的设备之一。在这种情况下,尝试构建容器会产生
error gathering device information while adding custom device
,因为 deviceA
、deviceB
和 deviceC
并非全部同时插入。
似乎一种可能性是卷安装整个
/dev
目录:
如果您想允许容器管理设备,您可以使用卷会话并挂载
,还可以添加privileged: true或设置适当的功能。/dev
但这只是部分解决方案。安装后,如何让它从整个
/dev
中“选择”正确的设备?
另一种可能性可能是将路径(根据存在的设备)放入环境变量中,然后将该变量传递给
devices
。但是,在与 docker compose build name-of-service
/docker compose run name-of-service
一起使用之前,何时/如何操作环境变量?
Ubuntu 22.04(主机和容器)(希望可部署到其他操作系统)
客户端/服务器:Docker 引擎 - 社区版本:27.3.1
Docker Compose 版本 v2.29.7
Compose 无法运行动态检查,执行任何类型的条件逻辑的能力也极其有限。 您在这里能做的最好的事情就是使用其环境变量替换来填充设备路径
devices:
- ${DEVICE_PATH}:/dev/ttyUSB0
您需要 Compose 之外的某种脚本或程序来检测这一点。 我可能会写一个shell脚本,比如
#!/bin/sh
is_device_available() {
# not a character-special device
if [ ! -c "$1" ]; then return 1; fi
# ... your logic here ...
return 0
}
for d in /dev/path/to/deviceA /dev/path/to/deviceB /dev/path/to/deviceC; do
if is_device_available "$d"; then
DEVICE_PATH="$d"
break
fi
done
if [ ! "$DEVICE_PATH" ]; then
echo could not detect a device
exit 1
fi
export DEVICE_PATH
exec "$@"
此脚本的末尾将运行它给出的命令,因此您可以像这样运行它
detect-device docker compose up
您还可以使用它来更改当前 shell 的环境,例如
. detect-device
docker compose up
请注意,每次运行时,它都会尝试再次检测设备,如果运行容器使其中一个设备“正在使用”,那么它将更改设备路径,这将重新创建容器。
detect-device docker-compose up -d
# If that makes the first device be "in use" then this will
# recreate the container on the second device
detect-device docker-compose up -d