Systemd-Run – Running systemd-run –user Inside a Systemd Service

dbussystemdsystemd-service

I have a web app that handles user input, and as part of that, runs some commands with systemd-run --user --scope ... to limit memory and CPU usage.

The application runs fine when run normally, but when run as a systemd service, I get:

Failed to connect to bus: No medium found

What do I need to do in the unit for the service to enable this?

Best Answer

--user contacts the per-user instance of systemd for that UID, which is only started when there is an actual login session for that UID. When there aren't any, you need to loginctl enable-linger <user> to have the service manager be always running for that user.

The webapp needs to have the correct XDG_RUNTIME_DIR= in its environment so that it could find the bus socket; it's always at the same location /run/user/<uid>. (The directory will be created by systemd when linger is enabled.)

You will probably need to use --service instead of --scope. The latter won't be able to migrate your process between cgroups due to lack of "common ancestor" permissions, so it becomes necessary to have systemd itself start the process.

(In a user session, your own per-UID user-1234.slice cgroup is the common ancestor of both your interactive terminal cgroup and the new systemd scope cgroup, but when trying to do this from a service, the only common ancestor would be -.slice which you do not have permissions to.)


Configuring the webapp .service with a PAMName= so that the webapp actually runs in a login session would avoid some of the above problems, but I also have the feeling it'll cause new problems, so I'm not suggesting it as the first option.

Related Topic