Fix rootless Podman by owning /run/user/<uid> instead of redirecting to /tmp

Podman rootless unconditionally resets XDG_RUNTIME_DIR to /run/user/<uid>
if that directory exists, overriding any env var we set. Redirecting to
/tmp is therefore ineffective.

Instead, ensure /run/user/<uid> exists and is owned by the current user
(using sudo if needed), mirroring what PAM/logind does for login sessions.
All Podman runtime state (socket, events, netavark) then works correctly.

Remove the now-unnecessary storage.conf/containers.conf writes and the
inline env override on podman system service.

https://claude.ai/code/session_01FKCW3FDjNFj6jve4niMFXH
This commit is contained in:
Claude 2026-03-22 08:02:10 +00:00
parent 0932308ed6
commit d2cba788ab
No known key found for this signature in database

View file

@ -60,37 +60,26 @@ EOF
echo "[hiy] Generated proxy/caddy.json for ${DOMAIN_SUFFIX}" echo "[hiy] Generated proxy/caddy.json for ${DOMAIN_SUFFIX}"
# ── Ensure Podman socket is active ──────────────────────────────────────────── # ── Ensure Podman socket is active ────────────────────────────────────────────
# /run/user/<uid> is created by PAM/logind; it doesn't exist in non-login # Podman rootless resets XDG_RUNTIME_DIR to /run/user/<uid> if that directory
# shells. Unconditionally redirect all Podman runtime state to /tmp so we # exists (regardless of what the caller set). So we must ensure that directory
# never depend on logind, regardless of what XDG_RUNTIME_DIR was set to # exists and is writable by the current user — this is normally done by
# by the calling environment. # PAM/logind but doesn't happen in non-login shells.
_HIY_RUNTIME="/tmp/podman-$(id -u)" _HIY_XDG="/run/user/$(id -u)"
mkdir -p "$_HIY_RUNTIME" if [ ! -d "$_HIY_XDG" ]; then
export XDG_RUNTIME_DIR="$_HIY_RUNTIME" sudo mkdir -p "$_HIY_XDG"
fi
if [ ! -w "$_HIY_XDG" ]; then
sudo chown "$(id -u):$(id -g)" "$_HIY_XDG"
sudo chmod 0700 "$_HIY_XDG"
fi
export XDG_RUNTIME_DIR="$_HIY_XDG"
# Write storage.conf and containers.conf so Podman doesn't read stale PODMAN_SOCK="${_HIY_XDG}/podman.sock"
# RunRoot / tmp_dir values from existing user config files.
mkdir -p "$HOME/.config/containers"
cat > "$HOME/.config/containers/storage.conf" <<STOCONF
[storage]
driver = "overlay"
runroot = "$_HIY_RUNTIME/storage"
graphroot = "$HOME/.local/share/containers/storage"
STOCONF
cat > "$HOME/.config/containers/containers.conf" <<CCONF
[engine]
tmp_dir = "$_HIY_RUNTIME"
CCONF
PODMAN_SOCK="${_HIY_RUNTIME}/podman.sock"
export PODMAN_SOCK export PODMAN_SOCK
export DOCKER_HOST="unix://${PODMAN_SOCK}" export DOCKER_HOST="unix://${PODMAN_SOCK}"
if [ ! -S "$PODMAN_SOCK" ]; then if [ ! -S "$PODMAN_SOCK" ]; then
echo "[hiy] Starting Podman socket via podman system service…" echo "[hiy] Starting Podman socket via podman system service…"
# Use env to guarantee XDG_RUNTIME_DIR is correct even if the calling podman system service --time=0 "unix://${PODMAN_SOCK}" &
# shell environment has it set to a non-writable path.
env XDG_RUNTIME_DIR="$_HIY_RUNTIME" \
podman system service --time=0 "unix://${PODMAN_SOCK}" &
# Wait up to 5 s for the socket to appear # Wait up to 5 s for the socket to appear
for i in 1 2 3 4 5; do for i in 1 2 3 4 5; do
[ -S "$PODMAN_SOCK" ] && break [ -S "$PODMAN_SOCK" ] && break