the openhab user inside the container needs to be in the dialout group too. It’s inside the container that the file permissions are enforced.
That’s only half the problem though. What are the permissions on /dev/ttyACM0 outside the container? If the permissions of the file outside the container only allow root to read/write I’m not sure if you can override that inside the container. You might need something (e.g. a cron job that runs at system start) to add permissions to the file on the host so the group can read/write.
Finally, what’s your docker command? Are you passing rwm permissions when mounting the device?
You’ve given “other” full permissions on the file meaning you’ve taken the user and the group out of the picture. Any user now has permission to read and write to the file. If you want to test if the user and group work, use /bin/chmod g+rw /dev/ttyACM0. That will only add rw permissions for members of the group, not everyone.
The container has it’s own passwds file meaning it has it’s own users. It doesn’t inherit the users from the host. It’s like having the same user on two totally different machines. They can even have the same UID but they are managed separately on each machine.
This sort of isolation is the whole point of containers.
OH already has the file open for read/write. Changing the permissions on the file changes who can open that file from this point forward but it doesn’t kick any services who already have the file open off. You need to restart the container and then only add permissions for the group. Then, assuming the the openhab user inside the container is not a member of dialout, you’ll find OH cannot open that file any more.
Is there a way with the official Openhab image to set two groups to the openhab users on creation of the container ? I did find the dialout group already on the image/container with GID 20. I see that userID and groupID is specified as env variables. I was unable to set 997 and 20.
As far I remember linux ids are mapped as is between host and container. While you might not have enough of hooks on the container side, you can prepare host by using uids expected by container. I know it is a bit hacky.
Other way is doing UID mapping with existing tools: Align user IDs inside and outside Docker with subuser mapping - Linux-natives, which looks a bit more “rounded”.
I tend to do it the lazy way. I just mount /etc/passwd into the container and make sure the user on the host matches the user running in the container. It’s not the safest of things to do if you are trying to have a secure container (no reason to expose all the host users to the container) but I’m not as worried about that sort of thing so accept the risk.
I also usually pass in localtime and timezone to ensure the container matches the time of the host.
Note this approach doesn’t work for all containers, but it works for enough that I usually try it by default.
I’m a little surprised it’s not already which made me think maybe you are not using the official image or something else is going on.
I’ve not seen it mentioned since I asked to I’ll ask again, does the docker command that starts the container pass in the device with RWM permissions? Devices work the same as volumes. They get mounted into the container and you can set the permissions on what the container can do. I’m not certain the m option is required for a serial device or not but the rw is required.
What’s odd though is that the device should have rwm permissions by default. Without the docker run command it’s impossible to say what’s going on.
Seems like I’m at least passing in the devices, maybe not the RWM permissions correctly ? This is mainly copied from the Openhab docker documentation. And as far as I know I am using the official image like this:
Problem comes from missing group assignment to openhab user in the container. Looking at docker entrypoint I think it should be there if you specify USER_ID environment variable.
Have a look on line 32 of entrypoint script:
If USER_ID is set there is entire block of group assignments. Note if I read script properly - the NEW_GROUP_ID seem to be optional (?). Also there is number of groups assigned later on.
Another point - later part of entrypoint script attempts to load some scripts from /etc/cont-init.d/ directory if its available. So you might actually have a “hook” to start with, if you mount your script under this location.
# Check if the group dialout exists
if grep -q "^dialout:" /etc/group; then
echo "Group dialout exists."
# Add the user openhab to the group dialout with GID 20
usermod -aG dialout -g 20 openhab
echo "Group dialout does not exist. Please create the group manually first."
Usually. I’m wondering if something more fundamental is going on.
After all, the entrypoint.sh script also added user openhab to dialout (20).
I wonder if user 998 already exists inside the container.
if ! id -u openhab >/dev/null 2>&1; then
This line means the user will only have all those different versions of the dialout groups (and others) added to it if it doesn’t already exist. If UID 998 already exists inside the container it wouldn’t be a member of dialout and this block of code wouldn’t run.
What happens if you run the container without setting the user ID environment variable?
After doing so, what do you get when running id -u openhab inside the container?
What do you get when running `id -u 998?
What do you see in the logs from the container? There are some lines echoed out by the entrypoint.sh script which will appear in the docker logs. docker logs openhab. You can add the -f option to follow the logs.
Given the code of the entrypoint.sh script, the only way that user would not be a member of the dialout group (among others) is if the user already existed before that script ran.
I think that’s the problem.
You are passing gid 997 to the container to be openhab’s group. But GID is “reserved” for the gpio group. It looks like it bails at that point and never gets to the adduser commands that actually add the openhab user to all of these groups.
Use a different non reserved ID for the group (e.g. get rid of the group id environment variable too. Or at least choose a GID different from 11, 14, 16, 17, 18, 32, 63, 490, and 997.
It is unknown to me why these groups are being created in the first place but clearly you cannot try to use one of these group IDs.
Yep you are completely right. Omitting the GID of 997 makes everything work as it should and I now have the devices working and the user Openhab has all these groups added as you mentioned earlier.
So all of this just because I managed to use a reserved id for gpio ? I wonder where I got 997 from, my guess is that it was assigned to my Openhab user from a previous install on my debian system without docker, could that be ?
Maybe. If you are trying to match the host user to the container version, when you created the openhab user on the host it assigned 998 and for some reason I never understood, the gid is usually the uid-1 (997 in this case).
I’m a little surprised the gid of 997 is so high. In my experience service user ids tend to start at 999 and go down from there as you create users and login users start at 1000 and go up from there. But it’s been a very long time since I let the OS choose my uids so don’t know if I’m misremembering or if that’s still the case.
This might be something worth filing an issue on the openhab-docker repo. I’m pretty basic when it comes to bash scripting but there has to be a way to not bail if it encounters a group that already exists and finish all those adduser commands that come later no matter what.
This is definitely an edge case.
Maybe even just adding a note to the docs would be enough.