Score:2

Error running systemd as user - Failed to connect to bus: $DBUS_SESSION_BUS_ADDRESS and $XDG_RUNTIME_DIR not defined

sr flag

I have a script that is running as root and am trying to have it setup a user service to run an IPFS daemon. The problem is that I need to enable the service as the user rather than as root. It usually works after a restart but I'd like to avoid that if I can.

The service script is located at ~/.config/systemd/user/ipfs.service

It contains:

[Unit]
Description=IPFS daemon

[Service]
# Environment="IPFS_PATH=/data/ipfs"  # optional path to ipfs init directory if not default (\$HOME/.ipfs)
ExecStart=/usr/local/bin/ipfs daemon
Restart=on-failure

[Install]
WantedBy=default.target

(I took this code from here: https://github.com/ipfs/go-ipfs/tree/master/misc )

If I run these command as the user it works correctly:

systemctl --user enable ipfs
systemctl --user start ipfs

The problem is that my script is running as root, and I can't figure out how to get this to run as the user. I have tried this so far:

    # Enable linger so IPFS can run at boot
    loginctl enable-linger $USER_ACCOUNT

    # Enable the service to run at boot
    sudo -u $USER_ACCOUNT systemctl --user enable ipfs

    # Start the service now
    sudo -u $USER_ACCOUNT systemctl --user start ipfs

Unfortunately with this the service does not start and when I get this error message:

Failed to connect to bus: $DBUS_SESSION_BUS_ADDRESS and $XDG_RUNTIME_DIR not defined (consider using [email protected] --user to connect to bus of other user)

Once the script has finished, and I reboot, the service starts fine but I would like to avoid the user having to reboot if I can. Any help would be appreciated.

Nate T avatar
it flag
Does it matter where the script runs? If the answer is no, try to run from another TTY. Sometimes, this will work when it seems like it shouldn't. SystemD should be available from anywhere. It is a login shell, so the env. requirements will be different. Honestly, I dont know if it will work or not, but Im curious.
cn flag
In https://github.com/eriksjolund/user-systemd-service-actions-workflow/blob/main/.github/workflows/demo.yml#L18 I had to add a `sleep 1` and ` `XDG_RUNTIME_DIR=/run/user/$UID`. If you are running as root you could also try `systemd-run --quiet --machine= $USER_ACCOUNT@ --user --collect --pipe --wait systemctl --user enable ipfs`
Score:3
kh flag

The quick solution

Assuming someuser uses bash as their login shell, add the following exports to ~someuser/.profile [1]:

export XDG_RUNTIME_DIR="/run/user/$UID"
export DBUS_SESSION_BUS_ADDRESS="unix:path=${XDG_RUNTIME_DIR}/bus"

Then, a user with root/sudo privileges can interact with someuser's systemd by wrapping the command with runuser:

sudo runuser someuser -l -c "systemctl --user enable ipfs"
sudo runuser someuser -l -c "systemctl --user start ipfs"

runuser someuser -l -c "printenv" can help to troubleshoot these and other exported environment variables.


[1]: putting these exports into ~someuser/.bashrc instead may turn out ineffective, as the default .bashrc often is set up to early-exit when it detects it is running non-interactively; see https://unix.stackexchange.com/a/257613/20230

The clean solution

In general, setting XDG_RUNTIME_DIR and DBUS_SESSION_BUS_ADDRESS manually/explicitly is more of a workaround; what is preferable to it is to properly log in with user someuser. Properly logging in will automatically set these environment variables, and avoids pollution of someuser's environment variables with settings from the originating user.

Such a proper login can be accomplished with the machinectl command, which e.g. for Ubuntu 22.04 LTS jammy is available via apt package systemd-container.

With machinectl available, a proper login from any user to user someuser into their shell, with all the environment variables properly set up:

sudo machinectl shell lxc@
Score:1
hk flag

I faced this issue after installing docker-desktop following https://docs.docker.com/desktop/install/ubuntu/ on Ubuntu 22.04 LTS.

Following solved the issue. First check the permissions on the downloaded .deb file in your 'Downloads' directory or just set it:

sudo chmod 755 docker-desktop-<version>-<arch>.deb

Next add your user to docker group:

sudo usermod -aG docker $USER

Activate changes to the group:

newgrp docker

Now try executing command to launch docker-desktop:

systemctl --user start docker-desktop

To fix the docker-hub login issue from docker-desktop:

https://docs.docker.com/desktop/get-started/#credentials-management-for-linux-users

Ref: https://docs.docker.com/engine/install/linux-postinstall/

Score:0
us flag

These variables are user specific. They are set by the user instance of systemd when a user logs in. If your script runs as a system service then of course it does not have access to this variable for a specific user.

If you use systemctl --user --global enable then the service will be enabled for all users.

Nate T avatar
it flag
systemd isnt just a binary in the bin directory. It is a literal system. There aren't user specificic instances.
us flag
There are two systemd processes. The first one is run as /sbin/init and starts global services. The second one is launched when a user logs in and starts user services. The two variables in question here are set by the second process.
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.