Как запустить приложение Node.js при загрузке системы?

Я работаю над Raspberry Pi с Raspbian, работающим с приложением Node.js, и пытаюсь запустить его при загрузке Pi. Я нашел пару примеров, но я не могу заставить его работать. Мой текущий код:

#! /bin/sh
# /etc/init.d/MyApp

### BEGIN INIT INFO
# Provides:          MyApp.js
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Starts MyApp.js
# Description:       Start / stop MyApp.js at boot / shutdown.
### END INIT INFO

# If you want a command to always run, put it here

# Carry out specific functions when asked to by the system
case "$1" in
   start)
    echo "Starting MyApp.js"
    # run application you want to start
    node /home/pi/app/MyApp/MyApp.js
   ;;
   stop)
    echo "Stopping MyApp.js"
    # kill application you want to stop
    killall MyApp.js
    ;;
  *)
    echo "Usage: /etc/init.d/MyApp {start|stop}"
    exit 1
    ;;
esac

exit 0

У меня это в папке etc/init.d, запускал chmod +x /etc/init.d/MyApp, могу запустить вручную, потом запускаю sudo update-rc.d MyApp defaults, перезагружаюсь, а скрипт так и не запускается. Я просмотрел несколько разных примеров, внес коррективы и все еще не повезло.


person user2650875    schedule 04.02.2014    source источник


Ответы (3)


Если вы используете готовый выпуск Pi, например 0.10.24, возможно, у вас возникла проблема с PATH.

Вы можете указать полный путь к двоичному файлу узла как часть команды start или убедиться, что PATH к двоичному файлу узла установлен до запуска /etc/init.d/MyApp. У меня была такая же проблема, и я пробовал оба с успехом. Кроме того, команда stop в том виде, в каком она у вас есть, может не работать.

#! /bin/sh
# /etc/init.d/test

### BEGIN INIT INFO
# Provides:          test
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Example initscript
# Description:       This file should be used to construct scripts to be
#                    placed in /etc/init.d.
### END INIT INFO

# Carry out specific functions when asked to by the system
case "$1" in
   start)
    echo "Starting test.js"
    # run application you want to start
    #node /home/pi/test.js > /home/pi/test.log
    /home/pi/downloads/node-v0.10.24-linux-arm-pi/bin/node /home/pi/test.js >> /home/pi/test.log
   ;;
   stop)
    echo "Stopping test.js"
    # kill application you want to stop
    killall -9 node
    # Not a great approach for running
    # multiple node instances
    ;;
  *)
    echo "Usage: /etc/init.d/test {start|stop}"
    exit 1
    ;;
esac

exit 0

Если вы хотите сделать sudo node, вы можете добавить PATH к Defaults secure_path, используя sudo visudo.

Кроме того, я бы рекомендовал использовать что-то вроде forever, чтобы ваш процесс продолжал работать после сбоев, а что нет.

person Kevin Reilly    schedule 04.02.2014
comment
Я попытался добавить полный путь к двоичному файлу, как было предложено, и вижу тот же результат. Я могу запустить его вручную, но он не запускается при загрузке. После внесения изменений я запустил chmod +x /etc/init.d/MyApp, удалил и снова добавил в rc.d. Мой план состоит в том, чтобы перейти к использованию навсегда после того, как я смогу заставить его запускаться при загрузке. - person user2650875; 04.02.2014
comment
Когда вы пытаетесь запустить его вручную, вы делаете sudo /etc/init.d/MyApp start? Вот как я определил, что у меня проблема с PATH. - person Kevin Reilly; 04.02.2014
comment
Правильный. Я звоню sudo /etc/init.d/MyApp start. - person user2650875; 04.02.2014
comment
Хм... странно. Вы также можете запустить приложение node как root? Это приложение, которое продолжает работать, например, веб-сервер? Вы пытались передать вывод в журнал, как в моем примере с > test.log, и проверить журнал? Мне не удалось найти журнал проблемы, начиная с любого файла /var/log, но, возможно, я его пропустил. Я не уверен, что проблема может быть в Provides: MyApp.js, но вместо этого вы можете попробовать Provides: MyApp. - person Kevin Reilly; 05.02.2014
comment
Да, я могу выполнить приложение node как root или не как root. Я создаю журнал, как в примере, который вы предоставили. У сценария есть веб-сервер, который продолжает работать непрерывно. Даже при запуске скрипта загрузки он будет работать без проблем. - person user2650875; 05.02.2014
comment
Пробовал оба способа Provides: MyApp.js и Provides: MyApp. Никаких изменений в поведении. - person user2650875; 05.02.2014
comment
Штопать. У меня нет идей. За исключением, может быть, попытки очень простого приложения, такого как небольшой пример веб-сервера. У меня есть пример для моего теста, который проверен, работает, если вы хотите попробовать его. Возможно, возникает ошибка запуска приложения только при выполнении через init.d - person Kevin Reilly; 05.02.2014
comment
Я тоже. Я пробовал этот пример #!/bin/bash NODE=/opt/node/bin/node SERVER_JS_FILE=/home/pi/app/server.js USER=pi OUT=/home/pi/nodejs.log case "$1" in start) echo "starting node: $NODE $SERVER_JS_FILE" sudo -u $USER $NODE $SERVER_JS_FILE > $OUT 2>$OUT & ;; stop) killall $NODE ;; *) echo "usage: $0 (start|stop)" esac exit 0 Это дает мне тот же результат. Выполняется вручную, но не автоматически. Он будет работать с простым веб-сервером, который возвращает Hello World, но не мое полное приложение. - person user2650875; 05.02.2014
comment
Понятно! В моем приложении была ошибка пути, которая вызывала ошибку при запуске из init.d. Журнал был перезаписан чем-то другим, поэтому я не мог достаточно хорошо уловить. Спасибо за помощь! - person user2650875; 05.02.2014
comment
Потрясающий! Так рад, что ты разобрался. Не за что. В чем заключалась конкретная проблема? Просто для моей будущей ссылки. Нужно использовать __dirname или стиль ./../ или что? - person Kevin Reilly; 05.02.2014
comment
О, и я только что понял, что ›› лучше, чем › в этом случае, потому что он будет добавляться в журнал, а не начинать новый. Это может объяснить сценарий перезаписи, о котором вы говорили. - person Kevin Reilly; 05.02.2014
comment
Мое приложение изначально пыталось загрузить config.json. Я изменил это на ./app/MyApp/config.json, потому что он не запускался при ручном вызове с самого начала. В итоге мне пришлось использовать полный путь, чтобы заставить его выполняться из кабины /home/pi/app/MyApp/config.json. - person user2650875; 05.02.2014

Я решил эту проблему, сначала проверив, где был установлен node.js на RaspberryPi:

which node

Это дало мне:

/usr/local/bin/node

Откройте конфигурацию кронтаба:

sudo crontab -e

Затем в моем crontab:

@reboot sudo /usr/local/bin/node <complete path to your .js app> &

Сохраняем, перезагружаемся и проблема решена!

person Mohit Athwani    schedule 17.02.2014
comment
Тупой вопрос: что делает >> &? У меня выдает ошибку. - person JeffThompson; 20.11.2015
comment
@JeffThompson, ›› это опечатка. Опустить угловые скобки. - person Mister Tea; 28.04.2016

Мохит прав, но просто для пояснения вы можете использовать readlink, чтобы найти полный путь к вашему приложению Node.js, так как позже потребуется добавить его в качестве задания cron.

readlink -f <<name of file >>

Например, readlink -f HAP-NodeJS/Core.js приводит к /home/pi/HAP-NodeJS/Core.js

Вы также можете использовать which node, чтобы найти полный путь, где установлен node.js.

Затем создайте новое задание cron, используя sudo crontab -e, и добавьте следующий код в самый конец:

@reboot sudo /usr/local/bin/node <<.js application path>> &

например, мой код выглядит так.

@reboot sudo /usr/local/bin/node /home/pi/HAP-NodeJS/Core.js &

После перезагрузки (или запуска) ваш Node.js должен запуститься. Надеюсь, это прояснит ситуацию.

person Adeel C    schedule 10.12.2015
comment
Спасибо за подробный ответ! - person Mar; 23.10.2016
comment
у меня это не работает, я сделал то же самое .. Я работаю удаленно, используя xrdp, это имеет какой-либо эффект? - person Tony; 02.09.2018