0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Podman rootlessでハマった

0
Last updated at Posted at 2026-05-06

Podman rootlessでハマった XDG_RUNTIME_DIRDBUS_SESSION_BUS_ADDRESS のズレ:/run/user/1000 を参照してpermission deniedになった話

はじめに

AlmaLinux / RHEL系の環境で、一般ユーザーから Podman rootless を使おうとしたところ、コンテナ起動時に以下のようなエラーが出ました。

XDG_RUNTIME_DIR directory "/run/user/1000" is not owned by the current user

また、別のタイミングでは以下のエラーも発生しました。

ERRO[0000] failed to move the rootless netns slirp4netns process to the systemd user.slice: dial unix /run/user/1000/bus: connect: permission denied

rootではコンテナを起動できるのに、一般ユーザー user02 ではPodmanが失敗する状態です。

最初はPodman側の問題かと思いましたが、調べていくと原因は、Linuxのユーザーセッションまわりの環境変数である以下2つのズレでした。

XDG_RUNTIME_DIR
DBUS_SESSION_BUS_ADDRESS

特に今回のポイントは次です。

user02 の UID は 1001
しかし一部の環境変数が user01 の UID 1000 用の /run/user/1000 を参照していた

この記事では、/run/user/$UID とは何か、XDG_RUNTIME_DIRDBUS_SESSION_BUS_ADDRESS が何を意味するのか、そしてPodman rootlessでなぜエラーになったのかを整理します。


環境

今回の環境は以下です。

OS: AlmaLinux / RHEL系
コンテナ: Podman rootless
SSHログインユーザー: user01
Podmanを動かしたいユーザー: user02

ユーザーのUIDは以下の通りです。

id -u user01
# 1000

id -u user02
# 1001

つまり、対応関係はこうです。

/run/user/1000 = user01 用
/run/user/1001 = user02 用

発生していたエラー

user02 ユーザーでPodmanを実行すると、次のようなエラーが出ました。

XDG_RUNTIME_DIR directory "/run/user/1000" is not owned by the current user

また、XDG_RUNTIME_DIR を修正した後にも、次のエラーが残りました。

ERRO[0000] failed to move the rootless netns slirp4netns process to the systemd user.slice: dial unix /run/user/1000/bus: connect: permission denied

/run/user/$UID とは何か

/run/user/$UID は、Linuxがユーザーごとに作る一時的な実行用ディレクトリです。

たとえば、以下のようなディレクトリが作られます。

/run/user/1000
/run/user/1001

この 10001001 は、ユーザーID、つまりUIDです。

今回の場合は以下の関係です。

user01  -> UID 1000 -> /run/user/1000
user02   -> UID 1001 -> /run/user/1001

/run はOS起動中だけ存在する一時領域です。
そのため、サーバを再起動すると /run/user/1000/run/user/1001 は一度消えます。

その後、ユーザーがログインしたり、systemd user managerが起動したりすると、再生成されます。

なので、再起動後に /run/user/1000user01 所有で作られるのは正常です。

問題は、user02 で作業しているのに、環境変数が /run/user/1000 を参照していたことです。


XDG_RUNTIME_DIR とは何か

XDG_RUNTIME_DIR は、そのユーザーの一時実行用ディレクトリを表す環境変数です。

user02 のUIDが1001なら、本来はこうなっている必要があります。

echo "$XDG_RUNTIME_DIR"
# /run/user/1001

Podman rootlessは、このディレクトリを使って一時ファイルやソケットなどを扱います。

そのため、以下の状態はNGです。

whoami
# user02

id -u
# 1001

echo "$XDG_RUNTIME_DIR"
# /run/user/1000

これは、user02 で作業しているのに、user01 用の /run/user/1000 を使おうとしている状態です。

この場合、Podmanは以下のように怒ります。

XDG_RUNTIME_DIR directory "/run/user/1000" is not owned by the current user

DBUS_SESSION_BUS_ADDRESS とは何か

今回もう一つ重要だったのが、DBUS_SESSION_BUS_ADDRESS です。

これは、ユーザーセッションのD-Busに接続するためのアドレスを表す環境変数です。

今回のエラーでは、ここが重要です。

dial unix /run/user/1000/bus: connect: permission denied

Podmanが /run/user/1000/bus に接続しようとして失敗しています。

実際に確認すると、以下のようになっていました。

echo "$DBUS_SESSION_BUS_ADDRESS"
# unix:path=/run/user/1000/bus

しかし、user02 のUIDは1001です。
本来は以下であるべきです。

echo "$DBUS_SESSION_BUS_ADDRESS"
# unix:path=/run/user/1001/bus

つまり、XDG_RUNTIME_DIR だけ直しても不十分でした。

正しい状態は以下です。

XDG_RUNTIME_DIR=/run/user/1001
DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1001/bus

なぜ /run/user/1000 を参照していたのか

今回のログインの流れは以下でした。

サーバ起動
↓
user01 でSSHログイン
↓
その後、su user02 でユーザー切り替え

ここが原因でした。

user01 でSSHログインすると、user01 用のユーザーセッションが作られます。

user01
UID 1000
/run/user/1000

このとき、環境変数も以下のようになります。

XDG_RUNTIME_DIR=/run/user/1000
DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus

その後、以下のように user02 に切り替えていました。

su user02

この場合、ユーザー自体は user02 に変わります。

しかし、元の user01 の環境変数を一部引き継ぐことがあります。

その結果、以下のような中途半端な状態になっていました。

whoami = user02
UID = 1001
XDG_RUNTIME_DIR = /run/user/1001
DBUS_SESSION_BUS_ADDRESS = unix:path=/run/user/1000/bus

ユーザーは user02 なのに、D-Busの接続先だけ user01 のまま、という状態です。


su user02su - user02 の違い

su user02

su user02

これは「ユーザーだけ切り替える」に近い動きです。

元ユーザーの環境変数を引き継ぎやすいため、今回のように user01 のセッション情報が残ることがあります。


su - user02

su - user02

これは「user02 としてログインし直す」に近い動きです。

~/.bash_profile なども読み込まれ、環境が比較的きれいになります。

ただし、SSHで直接 user02 にログインするのと完全に同じとは限りません。

Podman rootlessを安定して使うなら、理想は以下です。

ssh user02@サーバIP

つまり、Podmanを使うユーザーで直接ログインするのが一番きれいです。


状態確認に使ったコマンド

まず、現在のユーザーとUIDを確認します。

whoami
id
id -u

次に、問題の環境変数を確認します。

echo "$XDG_RUNTIME_DIR"
echo "$DBUS_SESSION_BUS_ADDRESS"

/run/user 配下の所有者も確認します。

ls -ld /run/user/1000 /run/user/1001

今回の例では、以下のようになっていました。

drwx------ 5 user01 user01 140 May  6 21:56 /run/user/1000
drwx------ 9 user02  user02  220 May  6 21:58 /run/user/1001

これは正常です。

/run/user/1000user01 用、/run/user/1001user02 用です。

次に、D-Busのソケットを確認します。

ls -l /run/user/1000/bus /run/user/1001/bus 2>/dev/null

今回、user02 用の /run/user/1001/bus は存在していました。

srw-rw-rw- 1 user02 user02 0 May  6 21:55 /run/user/1001/bus

しかし、環境変数は /run/user/1000/bus を向いていました。


一時的な解決方法

一時的に直すだけなら、user02 で以下を実行します。

export XDG_RUNTIME_DIR="/run/user/$(id -u)"
export DBUS_SESSION_BUS_ADDRESS="unix:path=${XDG_RUNTIME_DIR}/bus"

確認します。

echo "$XDG_RUNTIME_DIR"
echo "$DBUS_SESSION_BUS_ADDRESS"

期待値は以下です。

/run/user/1001
unix:path=/run/user/1001/bus

その後、Podmanを実行します。

podman info
podman-compose up --build

または環境によっては以下です。

podman compose up --build

.bashrc で強制補正する

今回は、user02.bashrcXDG_RUNTIME_DIRDBUS_SESSION_BUS_ADDRESS を現在のUIDに合わせて強制補正することで解決しました。

~/.bashrc の末尾に以下を追加します。

# for rootless Podman
# Fix XDG_RUNTIME_DIR and DBUS_SESSION_BUS_ADDRESS for the current user

_my_uid="$(id -u)"
_my_runtime_dir="/run/user/${_my_uid}"

if [ -d "$_my_runtime_dir" ] && [ "$(stat -c '%u' "$_my_runtime_dir" 2>/dev/null)" = "$_my_uid" ]; then
    export XDG_RUNTIME_DIR="$_my_runtime_dir"

    if [ -S "${_my_runtime_dir}/bus" ]; then
        export DBUS_SESSION_BUS_ADDRESS="unix:path=${_my_runtime_dir}/bus"
    else
        unset DBUS_SESSION_BUS_ADDRESS
    fi
else
    unset XDG_RUNTIME_DIR
    unset DBUS_SESSION_BUS_ADDRESS
fi

unset _my_uid
unset _my_runtime_dir

ポイントは、以下の2つをセットで補正することです。

XDG_RUNTIME_DIR
DBUS_SESSION_BUS_ADDRESS

XDG_RUNTIME_DIR だけ直しても、DBUS_SESSION_BUS_ADDRESS/run/user/1000/bus のままだと、Podmanがそちらに接続しに行って失敗します。


.bash_profile.bashrc の使い分け

.bash_profile はログインシェルで読まれます。

su - user02

のような入り方では、.bash_profile が読み込まれます。

一方、.bashrc は対話型シェルで読まれます。

今回のような補正は、実用上 .bashrc に置くのが無難です。

.bash_profile では .bashrc を読み込むだけにしておくと分かりやすいです。

# ~/.bash_profile

if [ -f ~/.bashrc ]; then
    . ~/.bashrc
fi

これにより、su - user02 でログインした場合も、最終的に .bashrc の補正が効きます。


/run/user/1001 が存在しない場合

user02 用の /run/user/1001 が存在しない場合は、user02 の systemd user manager が起動していない可能性があります。

rootで以下を実行します。

loginctl enable-linger user02
systemctl start user@$(id -u user02).service

確認します。

loginctl show-user user02 -p Linger -p RuntimePath
ls -ld /run/user/1001

期待値は以下です。

Linger=yes
RuntimePath=/run/user/1001

/run/user/1001 の所有者は user02 である必要があります。

drwx------ ... user02 user02 ... /run/user/1001

systemctl enable user@1001.service は必要か

通常、以下は不要です。

systemctl enable user@1001.service

user@UID.service は、通常の自作サービスのように自分でenableするものというより、systemd-logindがユーザーセッションやlinger設定に応じて管理するuser managerです。

自動起動やログアウト後の維持が目的なら、基本的には以下を使います。

loginctl enable-linger user02

その場ですぐ起動したい場合だけ、以下を実行します。

systemctl start user@$(id -u user02).service

/run/user/1000 が設定ファイルに固定されていないか確認する

念のため、どこかの設定ファイルに /run/user/1000 が固定で書かれていないか探します。

grep -RIn "XDG_RUNTIME_DIR\|DBUS_SESSION_BUS_ADDRESS\|/run/user/1000" \
  /etc/profile /etc/bashrc /etc/profile.d \
  /home/user01 /home/user02 2>/dev/null

もし以下のような行が出てきたら、削除またはコメントアウトします。

export XDG_RUNTIME_DIR=/run/user/1000
export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus

ただし、今回の場合は設定ファイルに固定値があったというより、user01 でSSHログイン後に su user02 していたことで、環境変数を引き継いだ可能性が高いです。


今回の流れを図で整理する

問題が起きていた流れは以下です。

正しい状態は以下です。


やってはいけないこと

/run/user/1000 の所有者を変えない

以下はやってはいけません。

chown user02:user02 /run/user/1000

/run/user/1000 はUID 1000のユーザー用です。

今回であれば、user01 用です。

user02 のUIDが1001なら、必要なのは /run/user/1001 です。


XDG_RUNTIME_DIR=/run/user/1000 を固定しない

以下もNGです。

export XDG_RUNTIME_DIR=/run/user/1000

user02 で動かすなら、以下である必要があります。

export XDG_RUNTIME_DIR=/run/user/1001

ただし、手動で固定するより、現在のUIDを使って補正する方が安全です。

export XDG_RUNTIME_DIR="/run/user/$(id -u)"

DBUS_SESSION_BUS_ADDRESS=/run/user/1000/bus を残さない

XDG_RUNTIME_DIR だけ直っていても、以下の状態ではまだダメです。

XDG_RUNTIME_DIR=/run/user/1001
DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus

この場合、Podmanが /run/user/1000/bus に接続しに行って失敗します。

正しくは以下です。

XDG_RUNTIME_DIR=/run/user/1001
DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1001/bus

/run/user/1001 を手動作成して終わりにしない

一時的には以下のように作成することもできます。

mkdir -p /run/user/1001
chown user02:user02 /run/user/1001
chmod 700 /run/user/1001

しかし、/run は再起動で消えます。

本来 /run/user/$UID は、systemd-logindやPAMによって管理されるものです。

そのため、根本的には以下のような方法で、systemd側に正しく用意させる方が自然です。

loginctl enable-linger user02
systemctl start user@$(id -u user02).service

一番きれいな運用

一番きれいなのは、Podman rootlessを使うユーザーで直接SSHログインすることです。

ssh user02@サーバIP

これなら、最初から以下の状態になりやすいです。

whoami = user02
id -u = 1001
XDG_RUNTIME_DIR = /run/user/1001
DBUS_SESSION_BUS_ADDRESS = unix:path=/run/user/1001/bus

user01 でSSHログインしてから切り替える場合は、少なくとも以下を使います。

su - user02

ただし、環境によってはDBus関連の環境変数が残ることがあるため、今回のように .bashrc で補正するのは実用上有効です。


最終的に目指す状態

user02 で以下の状態になっていればOKです。

whoami
# user02

id -u
# 1001

echo "$XDG_RUNTIME_DIR"
# /run/user/1001

echo "$DBUS_SESSION_BUS_ADDRESS"
# unix:path=/run/user/1001/bus

ls -ld "$XDG_RUNTIME_DIR"
# drwx------ ... user02 user02 ... /run/user/1001

そのうえで、Podmanを確認します。

podman info
podman ps -a
podman-compose up --build

または、

podman compose up --build

が動けば、user02 のrootless Podman環境としては正常な状態です。


まとめ

今回の原因は、Podmanそのものではなく、ユーザーセッション由来の環境変数のズレでした。

特に重要なのは次の2つです。

XDG_RUNTIME_DIR
DBUS_SESSION_BUS_ADDRESS

user02 のUIDが1001なら、正しい状態は以下です。

XDG_RUNTIME_DIR=/run/user/1001
DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1001/bus

一方、以下のような状態はNGです。

XDG_RUNTIME_DIR=/run/user/1000
DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus

また、途中で XDG_RUNTIME_DIR だけ直っていても、以下の状態ではまだ不完全です。

XDG_RUNTIME_DIR=/run/user/1001
DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus

XDG_RUNTIME_DIR はPodman rootlessの実行用ディレクトリに関係し、DBUS_SESSION_BUS_ADDRESS はsystemd user session / D-Busとの接続先に関係します。

そのため、Podman rootlessで /run/user/1000/run/user/1000/bus に関するエラーが出た場合は、片方だけでなく、必ず両方を確認するのが重要です。

今回の教訓は以下です。

Podman rootless のエラーでは、XDG_RUNTIME_DIR と DBUS_SESSION_BUS_ADDRESS をセットで確認する

特に、user01 でSSHログイン後に su user02 するような運用では、元ユーザーの環境変数を引き継ぐことがあります。

できれば、Podman rootlessを使うユーザーで直接SSHログインするのが望ましいです。

ssh user02@サーバIP

それが難しい場合でも、最低限 su - user02 を使い、必要に応じて .bashrcXDG_RUNTIME_DIRDBUS_SESSION_BUS_ADDRESS を現在のUIDに合わせて補正すると、今回のような問題を回避できます。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?