PC 環境
- Thinkpad X1 Intel Core i7
- Ubuntu 24.04
問題
こちらの branch で Docker コンテナをセットアップして、コンテナ内でコマンド実行すると、自動的に sudo 権限での実行になってしまいます。そのため、以下のようにファイル生成を行うと、owner と group が自動的に root ユーザーになってしまうという弊害があります。
Docker コンテナ内
remma@remma-ThinkPad-X1-Carbon-Gen-11:~/lab/ros2_nav2$ docker exec -it ros2_nav2 bash
root@remma-ThinkPad-X1-Carbon-Gen-11:/workspace# echo a > tmp.txt
root@remma-ThinkPad-X1-Carbon-Gen-11:/workspace# ls -l tmp.txt
-rw-r--r-- 1 root root 2 Feb 23 10:31 tmp.txt
ホスト環境(Docker コンテナ外)
remma@remma-ThinkPad-X1-Carbon-Gen-11:~/lab/ros2_nav2/workspace$ ls -l tmp.txt
-rw-r--r-- 1 root root 2 Feb 23 19:31 tmp.txt
対策
上述の問題を回避するために新たに .env ファイルを生成し、docker-compose.yml と Dockerfile を以下のように変更します。
変更後の Docker 関連ファイル
生成した .env ファイル、変更後の docker-compose.yml, Dockerfile ファイルはそれぞれ以下です。github repository はこちら。branch 名は article_7372
です。
同じディレクトリに以下の 3 ファイルを置いて docker compose up -d --build
を実行すれば、コンテナが立ち上がります。
UID=1000
GID=1000
※ ubuntu 環境だと一般的に UID, GID はそれぞれ 1000 になりますが、これらは環境によって異なるのでご自身の環境で以下を実施し、実行結果を UID, GID に入力してください。
$ id -u # UID の確認
$ id -g # GID の確認
version: '3.9'
services:
ros2_nav2:
build:
context: .
args:
UID: "${UID}"
GID: "${GID}"
container_name: ros2_nav2
network_mode: "host"
user: "${UID}:${GID}"
environment:
- DISPLAY=${DISPLAY}
- QT_X11_NO_MITSHM=1
- XAUTHORITY=/root/.Xauthority
volumes:
- /tmp/.X11-unix:/tmp/.X11-unix
- $XAUTHORITY:/root/.Xauthority
- ./workspace:/workspace:rw
stdin_open: true
tty: true
FROM ros:humble
ENV DEBIAN_FRONTEND=noninteractive
ARG UID=1000
ARG GID=1000
RUN groupadd -g $GID usergroup && \
useradd -m -u $UID -g usergroup -G sudo user && \
echo 'user ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
RUN apt update && apt install -y \
vim \
ros-humble-rviz2 \
ros-humble-navigation2 \
ros-humble-nav2-bringup \
ros-humble-turtlebot3-gazebo && \
rm -rf /var/lib/apt/lists/*
RUN echo "source /opt/ros/humble/setup.bash" >> /home/user/.bashrc
WORKDIR /workspace
CMD ["bash"]
実行結果
上記のようにファイルを追加・変更した上で以下を実行し、Docker コンテナを再ビルド & up してみましょう。
$ docker compose down --volumes
$ docker compose build --no-cache
$ docker compose up -d
その上で、Docker コンテナ内でファイルを作ると、ファイルの owner が root ではなくなります。
Docker コンテナ内
remma@remma-ThinkPad-X1-Carbon-Gen-11:~/lab/ros2_nav2$ docker exec -it ros2_nav2 bash
user@remma-ThinkPad-X1-Carbon-Gen-11:/workspace$ echo a > tmp2.txt
user@remma-ThinkPad-X1-Carbon-Gen-11:/workspace$ ls -l tmp2.txt
-rw-r--r-- 1 user usergroup 2 Feb 23 10:51 tmp2.txt
ホスト環境(Docker コンテナ外)
remma@remma-ThinkPad-X1-Carbon-Gen-11:~/lab/ros2_nav2/workspace$ ls -l tmp2.txt
-rw-r--r-- 1 remma remma 2 Feb 23 19:51 tmp2.txt
変更点説明
git diff
コマンドで出力した変更点をもとに、変更の意味を解説していきます。
.env
UID=1000
GID=1000
.env ファイルでは UID(ユーザー ID)と GID(グループ ID)を指定します。
docker-compose.yml
- build: .
+ build:
+ context: .
+ args:
+ UID: "${UID}"
+ GID: "${GID}"
上記により、Dockerfile に .env で指定された UID, GID の値を渡してビルドします。
container_name: ros2_nav2
network_mode: "host"
+ user: "${UID}:${GID}"
コンテナ内のプロセスの UID, GID を .env で指定したものにして実行します。
Dockerfile
+ARG UID=1000
+ARG GID=1000
UID, GID のデフォルト値を 1000 とします(docker-compose.yml から変数が与えられた場合はその変数で上書かれる)。
+RUN groupadd -g $GID usergroup && \
+ useradd -m -u $UID -g usergroup -G sudo user && \
+ echo 'user ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
- groupadd コマンドの -g オプションで $GID に対応するグループ usergroup を作成する。
- useradd コマンドで $UID に対応するユーザー user を作成する。
- -m オプションで /home/user にホームディレクトリを作成。
- -u オプションでユーザー ID を $UID に指定。
- -g オプションでユーザーが属するプライマリグループを usergroup に指定。
- -G sudo で user を sudo グループに追加し、管理者権限を持たせる。
- user が sudo を実行する際にパスワードを要求しないようにする。
以下のように Docker コンテナ内で sudo 権限でコマンドを実行することができます。このときパスワードは不要です。
remma@remma-ThinkPad-X1-Carbon-Gen-11:~/lab/ros2_nav2$ docker exec -it ros2_nav2 bash
user@remma-ThinkPad-X1-Carbon-Gen-11:/workspace$ sudo apt update
Get:1 http://security.ubuntu.com/ubuntu jammy-security InRelease [129 kB]
Get:2 http://archive.ubuntu.com/ubuntu jammy InRelease [270 kB]
Get:3 http://packages.ros.org/ros2/ubuntu jammy InRelease [4682 B]
Get:4 http://packages.ros.org/ros2/ubuntu jammy/main amd64 Packages [1650 kB]
...
-RUN echo "source /opt/ros/humble/setup.bash" >> /root/.bashrc
+RUN echo "source /opt/ros/humble/setup.bash" >> /home/user/.bashrc
.bashrc の格納先を root ディレクトリから /home/user に変更しています。
コメント