Systemd user services examples

What are systemd user services?

Probably you are familiar with the system-wide systemd services, managed by the systemctl command. But systemd services can also be entirely controlled by regular unprivileged users.

So it means to configure this, you don't root access, you run the serices under a regular user account.

Systemd user services example for Akeneo, can be used for Laravel and other frameworks:

Create a file:

 ~/.config/systemd/user/pim_job_queue@.service

[Unit]
Description=Akeneo PIM Job Queue Service (#%i)
After=network-online.target
Requires=dbus.socket
StartLimitIntervalSec=0

[Service]
Type=simple
WorkingDirectory=%h/akeneo
ExecStart=%h/akeneo/bin/console messenger:consume --env=prod %I
RestartSec=10s
Restart=always

[Install]
WantedBy=default.target  

Notes:

  • Keep the "Requires=dbus.socket" and "After=network-online.target" parts, it is important for the user services to use the proper dependencies.
  • "StartLimitIntervalSec=0" allows endless trying of restart every 10s (otherwise it will stop trying when it fails after a while)
  • Also keep the "WantedBy=default.target" , because not all other targets are available in systemd user services.
  • You cannot depend on the system services like mysqld, it will not be found by the user services. Possible workarounds may exist...

Now enable and start some instances, for example:

# 2 Instances of ui_job
systemctl --user enable pim_job_queue@ui_job{1..2}
systemctl --user start pim_job_queue@ui_job{1..2}

# 1 Instance of import_export_job
systemctl --user enable pim_job_queue@import_export_job{1..1}
systemctl --user start pim_job_queue@import_export_job{1..1}

# 1 Instance of data_maintenance_job
systemctl --user enable pim_job_queue@data_maintenance_job{1..1}
systemctl --user start pim_job_queue@data_maintenance_job{1..1}

Restart it:

systemctl --user restart pim_job_queue@*.service

Status:

systemctl --user status pim_job_queue@*.service

Other examples of systemd user files

Laravel

~/.config/systemd/user/laravel-queue@.service

[Unit]
Description=Laravel queue worker (#%i)
After=network-online.target
Requires=dbus.socket
StartLimitIntervalSec=0
[Service]
Type=simple
WorkingDirectory=%h/app
ExecStart=/usr/local/php74/bin/php artisan queue:work --daemon --env=prod
RestartSec=10s
Restart=always
[Install]
WantedBy=default.target

CraftCMS

~/.config/systemd/user/craftcms-queue@.service

[Unit]
Description=CraftCMS queue runner (#%i)
After=network-online.target
Requires=dbus.socket
StartLimitIntervalSec=0
[Service]
Type=simple
WorkingDirectory=%h/domains/example.com/craftcms
ExecStart=/usr/local/php80/bin/php %h/domains/example.com/craftcms/craft queue/listen
ExecReload=/bin/kill -SIGABRT $MAINPID
RestartSec=10s
Restart=always
[Install]
WantedBy=default.target

After creating this systemd startup method, make sure to disable the "runqueueautomatically" in the general config settings!

See: https://craftcms.com/docs/4.x/config/general.html#runqueueautomatically

Shopware

See: https://portal.hosted-power.com/knowledgebase/article/152/shopware-message-queue/

Magento

~/.config/systemd/user/magento-consumer@.service

[Unit]
Description=Magento Consumer (%i)
After=network-online.target
Requires=dbus.socket
StartLimitIntervalSec=0

[Service]
Type=simple
WorkingDirectory=%h/public_html
ExecStart=php %h/public_html/bin/magento queue:consumers:start %I --single-thread --max-messages=10000
RestartSec=10s
Restart=always

[Install]
WantedBy=default.target

After Here we use the "%I" identifier to be able to run multiple workers with just a single systemd unit file. 

systemctl --user enable magento-consumer@sales.rule.update.coupon.usage.service
systemctl --user start magento-consumer@sales.rule.update.coupon.usage.service
systemctl --user status magento-consumer@sales.rule.update.coupon.usage.service

And then another queue , for example

systemctl --user enable magento-consumer@product_action_attribute.update
systemctl --user start magento-consumer@product_action_attribute.update
systemctl --user status magento-consumer@product_action_attribute.update

Repeat this for any more queue's you want to use :)

Troubleshooting systemd user services

My service crashed!? This can help to get more information about the cause

# Show last 1000 lines
journalctl --user --no-pager -n 1000
# Target specific user service and search for fatal error in the last 10000 lines
journalctl --user -u shopware_consumer* --no-pager -n 10000 | grep -i FATAL
# Follow log
journalctl --user -n 100 -f


Was this article helpful?

mood_bad Dislike 3
mood Like 6
visibility Views: 7746