j3soon / ros2-essentials

A repo containing essential ROS2 (Humble) features for controlling Autonomous Mobile Robots (AMRs).
Apache License 2.0
7 stars 3 forks source link

Permission Errors in Container Due to UID Mismatch When Host UID Is Not 1000 #53

Open YuZhong-Chen opened 3 weeks ago

YuZhong-Chen commented 3 weeks ago

In Ubuntu 20.04 or 22.04, the default user UID is 1000, when creating the default user in the Dockerfile, we also use 1000 as our default UID. However, in Ubuntu 24.04, the default UID has been changed to 1001, as UID 1000 is already occupied by a pre-existing user. While we can delete that default user and create our own, when we mount local files into the Docker container, we won’t be able to modify them because those files are owned by UID 1001, leading to many inconveniences during development.

This issue also occurs on servers. As long as our local user UID is not 1000, we won't be able to use our Dockerfile properly.

The simplest solution for now is to ask users whose UID is not 1000 to manually modify the default UID in the Dockerfile and build the Docker image themselves. However, this solution is somewhat inconvenient. We might need to think of a better approach in the future.

YuZhong-Chen commented 3 weeks ago

Maybe we can refer to how devcontainer handles this issue. After building the image, they check whether the user UID inside image matches the local one. If it doesn’t, they create a temporary image based on that one, directly forcing the UID to match the local UID. You can refer to the updateRemoteUserUID parameter in devcontainer for more details.

updateRemoteUserUID Example:

image

However, forcibly modifying the image’s UID/GID could potentially introduce some issues. See #45 and this comment for more details.

j3soon commented 15 hours ago

The UID mismatch between the host and container can cause the colcon build command in .bashrc to fail due to permission errors.

A simple workaround is to change the ownership of the entire workspace directory to UID 1000:

# in the container, at the default workdir
sudo chown -R 1000 .

I believe this is the current recommended approach. Although this resolves permission issues in the container, it makes modifying files from the host more difficult. (requires undoing the above chown command)


To allow direct file modifications on the host, it is preferred to keep the file owner as the host user. Currently I can think of two approaches that can support this:

  1. Keep the file owner as the host user while allowing read/write access for all users. However, new files created in the container, such as build and log files will still be owned by the container user, which could require an additional chown and chmod to maintain access from both the host and in the container. I'm also unsure about the security implications of this approach, especially on shared servers.

  2. Exec into the container as the host user by using docker exec -u $(id -u). This will require configuring the permissions to grant full access to arbitrary users in the Dockerfile. If this can be achieved easily, this may be the preferred approach.

PS. Creating a temporary Docker image doesn’t seem like a good solution, as it requires manual builds across multiple machines, which can be quite cumbersome.