Names su - specifically as a confirmed cause, not just sudo -u

Traced live on the actual Pi: su - gitea-workflow left XDG_RUNTIME_DIR
unset even with the user manager already running and the bus socket
already there. None of su/sudo -i/sudo -u reliably go through
pam_systemd on Debian - only a real SSH login or sshd itself does,
which is what the deploy workflow already uses.
This commit is contained in:
2026-07-29 13:15:11 +02:00
parent 6882eda03f
commit 743c173257
2 changed files with 31 additions and 3 deletions
@@ -72,9 +72,26 @@ manually:
```bash
sudo systemctl start user@$(id -u gitea-workflow).service
```
And run `systemctl --user` commands from a **real login shell** for that account
(`sudo -i -u gitea-workflow`), not `sudo -u gitea-workflow systemctl --user ...` from your own
session — the latter often doesn't carry `XDG_RUNTIME_DIR` along, which produces this exact error.
And run `systemctl --user` commands from a **real login shell** for that account — not
`sudo -u gitea-workflow systemctl --user ...`, `sudo -i -u gitea-workflow`, **or `su - gitea-workflow`**
from your own session. All three are common ways to reach this exact error even when the user
manager is already running and `/run/user/<uid>/bus` already exists: none of them reliably go
through `pam_systemd` (the PAM module that actually exports `XDG_RUNTIME_DIR`), because
`/etc/pam.d/su` and most `sudo` PAM configs don't include it, unlike `/etc/pam.d/sshd` or
`/etc/pam.d/login`. Confirmed in practice: `su - gitea-workflow` reproduces this exactly.
Two fixes, in order of preference:
- **SSH in directly as `gitea-workflow`** instead of logging in as yourself and switching user —
a real SSH login does go through `sshd`'s PAM stack and sets `XDG_RUNTIME_DIR` correctly
- Or, after `su -`/`sudo -i -u`, just set it by hand once per shell:
```bash
export XDG_RUNTIME_DIR=/run/user/$(id -u)
```
**This does not affect the actual deploy workflow** — `deploy-scp.yaml` always connects over a
genuine SSH session (`sshpass ssh ...`), which sets `XDG_RUNTIME_DIR` correctly on its own. This
whole gotcha is specific to poking around on the host by hand via `su`/`sudo -i`.
Verify with `loginctl show-user gitea-workflow | grep Linger` (expect `Linger=yes`) and
`ls /run/user/<uid>` (should exist once the user manager has actually started).