systemd 서비스를 사용하여 데스크탑 알림을 시작하는 노드 애플리케이션을 실행하는 방법

systemd 서비스를 사용하여 데스크탑 알림을 시작하는 노드 애플리케이션을 실행하는 방법

이전에 검색해본 결과 이렇게는 할 수 없다는 답변이 나온 것 같은데, 제가 리눅스 전문가가 아니기 때문에 그래도 물어보고 싶었습니다. 매초 데스크톱 알림을 시작하는 nodejs로 만든 작은 앱이 있습니다.

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()

내가 달릴 때 이것은 훌륭하게 작동합니다 npm run start. systemd 서비스를 사용하여 실행하고 싶습니다.

[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

서비스를 시작한 지 몇 초 후에 상태 명령이 다음과 같이 표시됩니다.

● 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>

그러나 서비스가 실행되는 동안에는 데스크톱 알림이 시작되지 않습니다.

미리 감사드립니다.


편집하다 @edgar-magallon이 제안한 변경 사항을 적용한 후 추가 정보를 추가하세요.

$ 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.

그리고 로그:

$ 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.

내가 뭘 잘못했나요?

답변1

DBUS_SESSION_BUS_ADDRESSsystemd 서비스에서 환경 변수를 지정하고 RemainAfterExit=yes섹션에서 이를 사용해야 합니다 [Service].

내 경우에는 echo $DBUS_SESSION_BUS_ADDRESS그 가치를 얻었습니다.

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

따라서 systemd 서비스는 다음과 같습니다.

[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

실행 중이므로 /home/myuser/.nvm/versions/node/v16.13.1/bin/node /home/myuser/notify_send/notify_node/build/index.jssystemd 서비스에서 일부 오류가 발생할 수 있다고 생각합니다(종속성으로 인해 확실하지 않지만 노드에 대해 잘 모릅니다). 따라서 /home/myuser/notify_send/notify_node/build아래와 같은 스크립트를 생성하는 것이 좋습니다.

애플리케이션 실행

#!/bin/bash

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

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

시스템 서비스

[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

Systemd Timers노드 앱에서 크론 작업을 사용하는 대신 더 많은 기능이 있는 노드 앱을 사용할 수 있습니다.

관련 정보