0

Based on my previous searches, I think that the answer is that I can't do that, but anyway I would like to ask because I'm not a linux pro. I have a small app made with nodejs that launch a desktop notification every second:

import notifier from 'node-notifier'
import {CronJob} from 'cron';

/* Create a cron job that send a desktop notification every second */
const job = new CronJob('* * * * * *', () => {

  notifier.notify({
    title: 'My notification',
    message: 'Hello, there!',
  });
}, null, true, 'America/Los_Angeles');

job.start()

This works well when I run npm run start. I want to run this using a systemd service:

[Unit]
Description=should run node app which launch a desktop notification
After=network.target

[Service]
Environment="DISPLAY=:0" "XAUTHORITY=/home/myuser/.Xauthority"
Type=simple
User=myuser
ExecStart=/home/myuser/.nvm/versions/node/v16.13.1/bin/node /home/myuser/notify_send/notify_node/build/index.js
Restart=on-failure

[Install]
WantedBy=multi-user.target

Several seconds after start the service, the status command shows this:

● runjs.service - should run node app which launch a desktop notification
     Loaded: loaded (/etc/systemd/system/runjs.service; disabled; vendor preset: enabled)
     Active: active (running) since Sun 2022-12-04 17:47:40 CET; 22s ago
   Main PID: 5606 (node)
      Tasks: 20 (limit: 18651)
     Memory: 18.1M
     CGroup: /system.slice/runjs.service
             ├─5606 /home/myuser/.nvm/versions/node/v16.13.1/bin/node /home/myuser/notify_send/notify_node/build/index.js
             ├─5633 /bin/sh -c notify-send "My notification" "Hello, there!" --expire-time "10000"
             ├─5634 notify-send My notification Hello, there! --expire-time 10000
             ├─5639 dbus-launch --autolaunch=017e96ffe51b466384d899f21cbecdc5 --binary-syntax --close-stderr
             ├─5640 /usr/bin/dbus-daemon --syslog-only --fork --print-pid 5 --print-address 7 --session
             ├─5642 /usr/bin/dbus-daemon --syslog-only --fork --print-pid 5 --print-address 7 --session
             └─5643 /usr/bin/plasma_waitforname org.freedesktop.Notifications

dic 04 17:47:40 slimbook systemd[1]: Started should run node app which launch a desktop notification.
dic 04 17:48:00 slimbook dbus-daemon[5640]: [session uid=1000 pid=5638] AppArmor D-Bus mediation is enabled
dic 04 17:48:00 slimbook dbus-daemon[5640]: [session uid=1000 pid=5638] Activating service name='org.freedesktop.Notifications' requested by ':1.0>

But no desktop notification is launched when service is running.

Thanks in advance.


Edit After doing changes suggested by @edgar-magallon, add additional information:

$ sudo systemctl status runjs.service 
● runjs.service - should run node app which launch a desktop notification
     Loaded: loaded (/etc/systemd/system/runjs.service; disabled; vendor preset: enabled)
     Active: failed (Result: exit-code) since Sat 2022-12-24 00:26:59 CET; 4s ago
    Process: 3281 ExecStart=/home/user/notify_send/notify_node/build/runApp (code=exited, status=127)
   Main PID: 3281 (code=exited, status=127)

dic 24 00:26:59 slimbook systemd[1]: runjs.service: Scheduled restart job, restart counter is at 5.
dic 24 00:26:59 slimbook systemd[1]: Stopped should run node app which launch a desktop notification.
dic 24 00:26:59 slimbook systemd[1]: runjs.service: Start request repeated too quickly.
dic 24 00:26:59 slimbook systemd[1]: runjs.service: Failed with result 'exit-code'.
dic 24 00:26:59 slimbook systemd[1]: Failed to start should run node app which launch a desktop notification.

and the logs:

$ sudo journalctl -xeu runjs.service
-- Support: http://www.ubuntu.com/support
-- Support: http://www.ubuntu.com/support
-- 
-- The unit runjs.service has entered the 'failed' state with result 'exit-code'.
dic 24 00:26:59 slimbook systemd[1]: runjs.service: Scheduled restart job, restart counter is at 5.
-- Subject: Automatic restarting of a unit has been scheduled
-- Defined-By: systemd
-- Support: http://www.ubuntu.com/support
-- 
-- Automatic restarting of the unit runjs.service has been scheduled, as the result for
-- the configured Restart= setting for the unit.
dic 24 00:26:59 slimbook systemd[1]: Stopped should run node app which launch a desktop notification.
-- Subject: A stop job for unit runjs.service has finished
-- Defined-By: systemd
-- Support: http://www.ubuntu.com/support
-- 
-- A stop job for unit runjs.service has finished.
-- 
-- The job identifier is 2072 and the job result is done.
dic 24 00:26:59 slimbook systemd[1]: runjs.service: Start request repeated too quickly.
dic 24 00:26:59 slimbook systemd[1]: runjs.service: Failed with result 'exit-code'.
-- Subject: Unit failed
-- Defined-By: systemd
-- Support: http://www.ubuntu.com/support
-- 
-- The unit runjs.service has entered the 'failed' state with result 'exit-code'.
dic 24 00:26:59 slimbook systemd[1]: Failed to start should run node app which launch a desktop notification.
-- Subject: A start job for unit runjs.service has failed
-- Defined-By: systemd
-- Support: http://www.ubuntu.com/support
-- 
-- A start job for unit runjs.service has finished with a failure.
-- 
-- The job identifier is 2072 and the job result is failed.

What am I doing wrong?

4
  • In the lines where you have myuser are you actually using that name? For example, User=myuser should be replaced by your user (e.g. User=biorubenfs) as well as in the paths: /home/myuser/.nvm/... changes to /home/biorubenfs/.nvm/.... I tried my answer and works but If I try using something incorrect, such as User=myuser instead of my actual username I get the same logs: Start request repeated too quickly. Dec 24, 2022 at 5:21
  • If you are using correctly your username then try removing this line: Restart=on-failure and run the service (it will fail, but you might get more detailed logs). After run the service run this command again: sudo journalctl -xeu runjs.service and add it to your question please. Dec 24, 2022 at 5:22
  • 1
    It worked! All myuser references were right. The problem was on the runApp script (I didn't review the logs file before). It was logging /home/rubenfs/notify_send/notify_node/build/runApp: line 5: node: command not found so I changed node ./index.js &>/home/user/logs by /home/myuser/.nvm/versions/node/v16.13.1/bin/node ./index.js &>/home/myuser/logs. I'm not sure why is happening this, because when I run the script manually (without using the systemd service) , it works. I really appreciate your time, thank you so much.
    – biorubenfs
    Dec 24, 2022 at 11:37
  • Glad to know that! About the problem I'm thinking is about your node installation, maybe yo don't have it globally or the $PATH is not correctly set Dec 24, 2022 at 18:37

1 Answer 1

1

You should specify the environment variable: DBUS_SESSION_BUS_ADDRESS in your systemd service and use RemainAfterExit=yes in the section [Service].

In my case, I used echo $DBUS_SESSION_BUS_ADDRESS to get its value:

echo $DBUS_SESSION_BUS_ADDRESS
#output:
unix:path=/run/user/1000/bus

So the systemd service would be:

[Unit]
Description=should run node app which launch a desktop notification
After=network.target

[Service]
Environment="DISPLAY=:0" "XAUTHORITY=/home/myuser/.Xauthority" "DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus"
Type=simple
User=myuser
RemainAfterExit=yes
ExecStart=/home/myuser/.nvm/versions/node/v16.13.1/bin/node /home/myuser/notify_send/notify_node/build/index.js
Restart=on-failure

[Install]
WantedBy=multi-user.target

Since you are running: /home/myuser/.nvm/versions/node/v16.13.1/bin/node /home/myuser/notify_send/notify_node/build/index.js from your systemd service I think you could get some errors (because of dependencies, but I'm not really sure, I do not know much about node) so I suggest you create a script under /home/myuser/notify_send/notify_node/build like this:

runApp

#!/bin/bash

cd "$(dirname $(realpath $0))"

node ./index.js &>/home/user/logs

Systemd service

[Unit]
Description=should run node app which launch a desktop notification
After=network.target

[Service]
Environment="DISPLAY=:0" "XAUTHORITY=/home/myuser/.Xauthority" "DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus"
Type=simple
User=myuser
RemainAfterExit=yes
ExecStart=/home/myuser/notify_send/notify_node/build/runApp
Restart=on-failure

[Install]
WantedBy=multi-user.target

Instead of using cron-jobs in your node app you can use Systemd Timers whose have more features

4
  • I did everything you wrote: edit the service (including the dbus session) and create the script runApp but didn't work. I know that I can use Systemd Timers but the idea was do some stuff in the node app interacting with some APIs, etc, and I feel more comfortable using javascript. Thanks anyway.
    – biorubenfs
    Dec 23, 2022 at 19:24
  • @biorubenfs In fact systemd timers are more complex, so in your case and since your familiarized with JavaScript than that's the best choice. About your problem, what's exactly the error? Why didn't work? You can see error logs by using: sudo journalctl -xeu runjs.service (to position the cursor at the end) or sudo journalctl -xu runjs.service (to see the output from the beginning) Dec 23, 2022 at 19:30
  • @biorubenfs include your error in your question, I tried your code (using the systemd service of my answer) and the same code of your JavaScript and all worked correctly. Dec 23, 2022 at 19:33
  • Question edited adding required information.
    – biorubenfs
    Dec 23, 2022 at 23:38

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .