To create a systemd service in Linux, we need to create the unit file under /etc/systemd/system/ as myapp.service.

This means that to stop, restart or debug this service we need root access.

I wanted to create a service which a user without root access would be able to start, stop, debug.

A regular systemd service unit file might look something like this –

# /etc/systemd/system/app.service

[Unit]
Description=My App
After=network.target

[Service]
Type=simple
User=ubuntu
Group=ubuntu
WorkingDirectory=/var/www/app-folder
ExecStart=/usr/bin/bash -lc '/home/ubuntu/.asdf/shims/bundle exec puma'
Environment=RACK_ENV=production

[Install]
WantedBy=default.target

Here, ubuntu is the user and group the service should run under. The bash -lc options means that it runs in a) a login shell and b) the following string in double-quotes is the command to be run.

Of course, since this is a unit file, the full path of the command is to be given. So, the path to the bundle command is its full path.

For systemd unit file under user

Service Unit file

When we need to run a systemd service under a non-root user, the unit file needs to be under – ~/.config/systemd/user/ directory.

Also, now the user and group options above don’t apply. The unit file now becomes –

# ~/.config/systemd/user/app.service

[Unit]
Description=My App
After=network.target

[Service]
Type=simple
WorkingDirectory=/var/www/app-folder
ExecStart=/usr/bin/bash -lc '/home/douser/.asdf/shims/bundle exec puma'
Environment=RACK_ENV=production

[Install]
WantedBy=default.target

Service commands

All commands now have to have the --user option.

To reload systemd, the command now is –

systemctl --user daemon-reload

 To confirm service is available

systemctl --user list-unit-files app.service

Enable and Start the service

systemctl --user enable --now app.service

Start, Stop, Restart, Status commands

systemctl --user start app.service
systemctl --user stop app.service
systemctl --user restart app.service
systemctl --user status app.service

Checking logs

To see the logs

journalctl --user -u app

To see the logs in current boot –

journalctl --user -u app -b