Back to home

Manage daemons as user with systemd

Ubuntu since Xenial uses systemd as its init service. In addition to the startup of the OS itself, systemd provides user instances. With those, it is possible to manage and start services running as your user yourself.

Systemd manages different type of units. The service unit being the most common one, representing a service or daemon. In this article, we will only take a look at service units.

In this article, we outline how you can interact with systemd and manage you services. More details about how to write a systemd unit file can be found in this article.

To interact with the user instance of systemd, the systemctl --user command is used. To configure the user instance, you should place the unit file in ~/.config/systemd/user.

Systemd comes with a variety of new conventions. Amongst others, it should be avoided by services to daemonize. Instead, they should run in the foreground and log to stdout and stderr. This helps systemd track the state of the service. In return, it will take care about daemonizing and forwarding the logging to the journal.

First mandatory step

“Failed to connect to bus: No such file or directory” Error

If you see this error, please contact support@nine.ch. We will enable the service for you. This will only happen the very first time you are using this service. As we are enforcing the initial password change, this also prevents the start of the daemon (pam-restriction)

User Systemd Status

When executing the command systemctl --user status, you can display the runtime status of all units. In the following example, the systemd instance (init.scope) and the myredis.service are running:

www-data@server:~ $ export XDG_RUNTIME_DIR=/run/user/$UID
www-data@server:~ $ systemctl --user status
● server
    State: running
     Jobs: 0 queued
   Failed: 0 units
    Since: <DATUM>
   CGroup: /user.slice/user-33.slice/user@33.service
           ├─myredis.service
           │ └─2935 /usr/bin/redis-server *:7777     
           └─init.scope
             ├─2930 /lib/systemd/systemd --user
             └─2932 (sd-pam)  

Single service status

By appending a service to the aforementioned command, you can get more information about the runtime status of this particular service. Beside the actual status, a list of processes and the last few lines of the journal are displayed:

www-data@server:~ $ systemctl --user status myredis.service
● myredis.service - User Redis on port 7777
   Loaded: loaded (/home/www-data/.config/systemd/user/myredis.service; enabled; vendor preset: enabled)
   Active: active (running) since <DATUM>
  Process: 6701 ExecStop=/usr/bin/redis-cli -p 7777 shutdown (code=exited, status=0/SUCCESS)
 Main PID: 6851 (redis-server)
   CGroup: /user.slice/user-33.slice/user@33.service/myredis.service
           └─6851 /usr/bin/redis-server *:7777     

<DATUM> server redis-server[6851]:  |`-._`-._    `-.__.-'    _.-'_.-'|
<DATUM> server redis-server[6851]:  |    `-._`-._        _.-'_.-'    |
<DATUM> server redis-server[6851]:   `-._    `-._`-.__.-'_.-'    _.-'
<DATUM> server redis-server[6851]:       `-._    `-.__.-'    _.-'
<DATUM> server redis-server[6851]:           `-._        _.-'
<DATUM> server redis-server[6851]:               `-.__.-'
...

Display logs of a service

journalctl is used to display logs from the journal. With the --user-unit parameter, the service in question can be selected as shown below:

www-data@server:~ $ journalctl --user-unit=myredis.service
...
<DATUM> server redis-server[6851]:  |`-._`-._    `-.__.-'    _.-'_.-'|
<DATUM> server redis-server[6851]:  |    `-._`-._        _.-'_.-'    |
<DATUM> server redis-server[6851]:   `-._    `-._`-.__.-'_.-'    _.-'
<DATUM> server redis-server[6851]:       `-._    `-.__.-'    _.-'
<DATUM> server redis-server[6851]:           `-._        _.-'
<DATUM> server redis-server[6851]:               `-.__.-'
<DATUM> server redis-server[6851]: 6851:M <DATUM> # Server started, Redis version 3.0.6
<DATUM> server redis-server[6851]: 6851:M <DATUM> * The server is now ready to accept connections on port 7777

Enable a service

To ensure a service is started by default, it has to be enabled in the default.target. The often used multi-user.target is not available in the user instance. The following examples show how to enable and disable a service.

www-data@server:~ $ systemctl --user enable myredis.service 
Created symlink from /home/www-data/.config/systemd/user/default.target.wants/myredis.service to /home/www-data/.config/systemd/user/myredis.service.
www-data@server:~ $ systemctl --user disable myredis.service 
Removed symlink /home/www-data/.config/systemd/user/default.target.wants/myredis.service.

With systemctl --user is-enabled, you can check whether a given service is enabled:

www-data@xenial1-dev:~ $ systemctl --user is-enabled myredis.service 
enabled

Didn't find what you were looking for?

Contact our support:

+41 44 637 40 40 Support Portal support@nine.ch