Автоматический запуск навсегда (узел) при перезагрузке системы


191

Я использую модуль узла навсегда, чтобы сервер узла работал. Однако навсегда завершается при перезагрузке системы. Есть ли способ, которым я могу автоматически запустить сервер узла (с навсегда) при перезагрузке системы?


1
Этот сервер в облаке? У вас есть загрузочные скрипты для этого?
Хорхе Аранда

6
Оформить заказ PM2 ! Он также поддерживает генерацию сценариев запуска (systemd, systemv ...) pm2.keymetrics.io/docs/usage/startup
Unitech

Ответы:


344

Я бы предложил использовать crontab. Это просто в использовании.

Как

  1. Чтобы начать редактирование, выполните следующую замену «testuser» на нужного пользователя среды выполнения для процесса узла. Если вы выберете другого пользователя, кроме себя, вам придется запустить его с помощью sudo.

    $ crontab -u testuser -e
  2. Если вы никогда не делали этого раньше, он спросит вас, с каким редактором вы хотите редактировать. Мне нравится vim, но я рекомендую nano для простоты использования.

  3. Однажды в редакторе добавьте следующую строку:

    @reboot /usr/local/bin/forever start /your/path/to/your/app.js
  4. Сохраните файл. Вы должны получить некоторые отзывы о том, что cron был установлен.

  5. Для дальнейшего подтверждения установки cron выполните следующее (снова заменив «testuser» вашим целевым именем пользователя), чтобы вывести список текущих установленных cron:

    $ crontab -u testuser -l 

Обратите внимание, что, по моему мнению, вы всегда должны использовать полные пути при выполнении двоичных файлов в cron. Кроме того, если путь к вашему сценарию всегда неверен, запустите, which foreverчтобы получить полный путь.

Учитывая эти foreverвызовы node, вы также можете указать полный путь к node:

@reboot /usr/local/bin/forever start -c /usr/local/bin/node /your/path/to/your/app.js

Дальнейшее чтение


2
Этот подход хорош, но только для тех случаев, когда система перезагружается. Если сервер выключен и затем включен - это задание cron не будет выполнено.
ecdeveloper

6
Что заставляет вас думать, что? en.wikipedia.org/wiki/Cron#Predefined_scheduling_definitions Объясняет, что @rebootзапуск cron начинается с запуска cron deamon. Чтобы добавить, я никогда не сталкивался с ситуацией, которая предполагала бы, что мои cron, которые установлены в @reboot, не работают при загрузке системы. То, как вы его выключаете, для этого не имеет значения.
Джулиан Ланниган

16
Похоже, он /homeеще не смонтирован, поэтому он не будет работать, если ваш код живет в /home.
Чови

6
Я обнаружил, что вышеописанное не удалось для меня, потому что узел не находится в пути, когда cron пытается работать вечно, даже с опцией -c. Однако оказывается, что вы можете добавить оператор PATH = непосредственно в crontab, если он находится над операторами расписания. Как только PATH установлен, оператор @reboot работает как сон.
ЙоркширКев

2
Спасибо за ваш комментарий @chovy, это было очень полезно. Если вы используете переменные окружения из bashrc, обратите внимание на его комментарий. Поскольку / home не смонтирован, он не будет работать. Установите переменные в команде crontab как@reboot varname=value ...
lsborg

123

Вы можете использовать навсегда сервис для этого.

npm install -g forever-service
forever-service install test

Это обеспечит app.js в текущем каталоге как службу через вечность. Служба будет автоматически перезагружаться при каждом перезапуске системы. Также при остановке будет предпринята попытка изящной остановки. Этот скрипт также предоставляет скрипт logrotate.

URL Github: https://github.com/zapty/forever-service

ПРИМЕЧАНИЕ: я являюсь автором навсегда обслуживания.


2
Используйте параметр -e "PORT = 80 ENV = prod FOO = bar"
arva

2
Я не понимаю, как запустить навсегда службы. Что это за «тест» в «тесте на установку навсегда»? Моя команда для запуска моего приложения навсегда: "/ usr / local / bin / forever start -c / usr / local / bin / node / home / alex / public / node_modules / http-сервер / bin / http-server -s - д ложь ". Что бы мне написать?
Алекс

3
проверить здесь это название сервиса. когда вы запускаете тест установки навсегда-службы, он создает службу под названием test, чтобы запустить app.js в этом каталоге для запуска в качестве службы. Я бы предложил прочитать справочную документацию на странице gihub и добавить туда проблему, если вы не можете ее понять.
Арва

6
@Alex - уточнить комментарий ARVA в - в примере forever-service install test, testбудет название службы , но не имя файла самой программы / узла .js для запуска. По умолчанию, предполагается , название программы app.js, но вы можете изменить его с помощью --scriptфлага, следующим образом : forever-service install test --script main.js. (Не проверено, поэтому, пожалуйста, исправьте меня, если есть какие-либо синтаксические подробности неправильно.)
Дэн Ниссенбаум

3
@DanNissenbaum Спасибо за ответ. Я сейчас использую PM2, который прекрасно работает. Инструкции: digitalocean.com/community/tutorials/…
Алекс

27
  1. Установите PM2 глобально, используя NPM

    npm install pm2 -g

  2. Начните свой сценарий с pm2

    pm2 start app.js

  3. генерировать активный сценарий запуска

    pm2 startup

    ПРИМЕЧАНИЕ. Запуск pm2 предназначен для запуска PM2 при перезагрузке системы. PM2 после запуска перезапускает все процессы, которыми он управлял, прежде чем система вышла из строя.

Если вы хотите отключить автоматический запуск, просто используйте pm2 unstartup

Если вы хотите, чтобы скрипт запуска выполнялся под другим пользователем, просто используйте -u <username>опцию и--hp <user_home>:


Пожалуйста, не размещайте один и тот же ответ на несколько вопросов.
FelixSFD

Мне очень нравится, как улучшается pm2, и поставляется с отличным инструментом мониторинга. Надеюсь, что это выделено больше для других. @ rv7 Я уверен, что вы видели это, но есть решение для Windows: npmjs.com/package/pm2-windows-service . Хотя сам не пробовал.
Джон Ли

26

Этот случай действителен для Debian.

Добавьте следующее к /etc/rc.local

/usr/bin/sudo -u {{user}} /usr/local/bin/forever start {{app path}}

  • {{user}} заменяет ваше имя пользователя.
  • {{app path}}заменяет путь к вашему приложению. Например,/var/www/test/app.js

2
Этот метод не имеет дело с изящными выключениями, хотя для многих людей это, вероятно, не проблема.
UpTheCreek

6
Кстати - я думаю, что вы должны редактировать /etc/rc.local, а не/etc/init.d/rc.local
UpTheCreek

Согласитесь с @UpTheCreek, что /etc/rc.local является более подходящим местом для добавления этого - подробное объяснение см. На unix.stackexchange.com/a/59945 .
Итак,

2
Кроме того, вы можете указать «текущий рабочий каталог», app.jsчтобы убедиться, что относительные файлы загружены правильно - здесь естьprocess.chdir('/your/path/to/your/app'); ссылка на документацию Node.js
так что над этим

1
Если вам нужно установить переменные окружения для вашего скрипта Node.JS (например, $ PORT для экспресса), добавьте следующую строку, чтобы /etc/rc.localсделать ( cd /path/to/project && /usr/bin/sudo -u {{user}} env PORT={{port number}} PATH=$PATH:/usr/local/bin sh -c "forever start app.js" )
свое дело

11

Альтернативный метод crontab, вдохновленный этим ответом и этим сообщением в блоге.

1. Создайте файл сценария bash (измените bob на нужного пользователя).

vi /home/bob/node_server_init.sh

2. Скопируйте и вставьте это в файл, который вы только что создали.

#!/bin/sh

export NODE_ENV=production
export PATH=/usr/local/bin:$PATH
forever start /node/server/path/server.js > /dev/null

Обязательно отредактируйте пути выше в соответствии с вашей конфигурацией!

3. Убедитесь, что скрипт bash может быть выполнен.

chmod 700 /home/bob/node_server_init.sh

4. Протестируйте скрипт bash.

sh /home/bob/node_server_init.sh

5. Замените «bob» пользователем среды выполнения для узла.

crontab -u bob -e

6. Скопируйте и вставьте (измените bob на нужного пользователя).

@reboot /bin/sh /home/bob/node_server_init.sh

Сохраните crontab.

Вы сделали это до конца, ваш приз - перезагрузка (для проверки) :)


Этот метод работал лучше всего для меня. Навсегда вышло бы, когда я указывал полный путь к файлу server.js. Если бы я запускал его в том же каталоге, foreveer работал бы нормально. Причиной сбоя является то, что файл server.js содержит другие файлы, но пути были перепутаны. Используя этот метод, я мог записать CD в моем скрипте .sh в каталог, а затем запустить все, что там есть.
BeardedGeek

9

Скопированный ответ от прикрепленного вопроса .

Вы можете использовать PM2 , это менеджер производственных процессов для приложений Node.js со встроенным балансировщиком нагрузки.

Установить PM2

$ npm install pm2 -g

Запустить приложение

$ pm2 start app.js

Если вы используете экспресс, то вы можете запустить свое приложение, как

pm2 start ./bin/www --name="app"

Список всех запущенных процессов:

$ pm2 list

Будет перечислен весь процесс. Затем вы можете остановить / перезапустить службу, используя идентификатор или имя приложения с помощью следующей команды.

$ pm2 stop all                  
$ pm2 stop 0                    
$ pm2 restart all               

Для отображения логов

$ pm2 logs ['all'|app_name|app_id]

Как он запускается автоматически при загрузке системы? Вы просто копируете / вставляете ввод CLI вручную
Green

@Green, Run, $pm2 startupпосле этого вы увидите pm2 с просьбой вручную запустить команду, скопируйте и запустите ее. Тогда, $pm2 saveтеперь ваш app.js переживет перезагрузку системы
янешь

7

Для этого вам нужно создать сценарий оболочки в папке /etc/init.d. Это сложно, если вы никогда этого не делали, но в интернете достаточно информации о скриптах init.d.

Вот пример скрипта, который я создал для запуска сайта CoffeeScript навсегда:

#!/bin/bash
#
# initd-example      Node init.d 
#
# chkconfig: 345 
# description: Script to start a coffee script application through forever
# processname: forever/coffeescript/node
# pidfile: /var/run/forever-initd-hectorcorrea.pid 
# logfile: /var/run/forever-initd-hectorcorrea.log
#
# Based on a script posted by https://gist.github.com/jinze at https://gist.github.com/3748766
#


# Source function library.
. /lib/lsb/init-functions


pidFile=/var/run/forever-initd-hectorcorrea.pid 
logFile=/var/run/forever-initd-hectorcorrea.log 

sourceDir=/home/hectorlinux/website
coffeeFile=app.coffee
scriptId=$sourceDir/$coffeeFile


start() {
    echo "Starting $scriptId"

    # This is found in the library referenced at the top of the script
    start_daemon

    # Start our CoffeeScript app through forever
    # Notice that we change the PATH because on reboot
    # the PATH does not include the path to node.
    # Launching forever or coffee with a full path
    # does not work unless we set the PATH.
    cd $sourceDir
    PATH=/usr/local/bin:$PATH
    NODE_ENV=production PORT=80 forever start --pidFile $pidFile -l $logFile -a -d --sourceDir $sourceDir/ -c coffee $coffeeFile

    RETVAL=$?
}

restart() {
    echo -n "Restarting $scriptId"
    /usr/local/bin/forever restart $scriptId
    RETVAL=$?
}

stop() {
    echo -n "Shutting down $scriptId"
    /usr/local/bin/forever stop $scriptId
    RETVAL=$?
}

status() {
    echo -n "Status $scriptId"
    /usr/local/bin/forever list
    RETVAL=$?
}


case "$1" in
    start)
        start
        ;;
    stop)
        stop
        ;;
    status)
        status
        ;;
    restart)
        restart
        ;;
    *)
        echo "Usage:  {start|stop|status|restart}"
        exit 1
        ;;
esac
exit $RETVAL

Я должен был убедиться, что папка и PATH были явно установлены или доступны для пользователя root, так как сценарии init.d запускаются от имени root.


2
Если у вас есть какие-либо зависимости, которые также запускаются с init.d, у вас могут возникнуть проблемы с порядком загрузки.
UpTheCreek

@ alexandru.topliceanu Я исправил ссылку.
Гектор Корреа

6

Используйте PM2

Какой лучший вариант для запуска сервера производства сервера

Каковы преимущества запуска вашего приложения таким образом?

  • PM2 автоматически перезапустит ваше приложение в случае сбоя.

  • PM2 будет вести журнал ваших необработанных исключений - в этом случае в файле по адресу /home/safeuser/.pm2/logs/app-err.log.

  • С помощью одной команды PM2 может обеспечить перезапуск любых управляемых им приложений при перезагрузке сервера. По сути, ваше приложение узла будет запущено как сервис.

ссылка: https://www.digitalocean.com/community/tutorials/how-to-use-pm2-to-setup-a-node-js-production-environment-on-an-ubuntu-vps


5

Навсегда не было сделано, чтобы заставить приложения узла работать как сервисы. Правильный подход - создать запись / etc / inittab (старые системы Linux) или выскочку (более новые системы Linux).

Вот некоторая документация о том, как настроить это как выскочку: https://github.com/cvee/node-upstart


Upstart подвел меня на CentOS, и я прочитал, что он исчезнет. Создание записи init.d на самом деле не самый удобный способ, но я полагаю, что это linux :)
Jorre

5

crontabу меня не работает на CentOS x86 6.5. @reboot, похоже, не работает.

Наконец я получил это решение:

Редактировать: /etc/rc.local

sudo vi /etc/rc.local

Добавьте эту строку в конец файла. Поменяй USER_NAMEи PATH_TO_PROJECTна свой. NODE_ENV=productionозначает, что приложение работает в производственном режиме. Вы можете добавить больше строк, если вам нужно запустить более одного приложения node.js.

su - USER_NAME -c "NODE_ENV=production /usr/local/bin/forever start /PATH_TO_PROJECT/app.js"

Не устанавливайте NODE_ENVв отдельной строке, ваше приложение все равно будет работать в режиме разработки, потому что навсегда не получится NODE_ENV.

# WRONG!
su - USER_NAME -c "export NODE_ENV=production"

Сохранить и выйти из vi (нажмите ESC : w q return ). Вы можете попробовать перезагрузить свой сервер. После перезагрузки вашего сервера ваше приложение node.js должно запускаться автоматически, даже если вы не входите ни в какую учетную запись удаленно через ssh.

Вам лучше установить NODE_ENVсреду в вашей оболочке. NODE_ENVбудет установлен автоматически при USER_NAMEвходе в вашу учетную запись .

echo export NODE_ENV=production >> ~/.bash_profile

Таким образом, вы можете запускать такие команды, как навсегда остановка / запуск /PATH_TO_PROJECT/app.jsчерез ssh без установки NODE_ENVзаново.


есть та же проблема на Debian 7.6. Это исправлено для меня. Большое спасибо.
Даниэле Врут

На тот случай, если вы не хотите использовать «навсегда», вы можете изменить строку на «su - USER_NAME -c» NODE_ENV = производственный узел / PATH_TO_PROJECT / bin / www "'.
Яобин

3

Я написал скрипт, который делает именно это:

https://github.com/chovy/node-startup

Я не пробовал навсегда, но вы можете настроить команду, которую она запускает, поэтому она должна быть прямой:

/etc/init.d/node-app start
/etc/init.d/node-app restart
/etc/init.d/node-app stop

2

Проблема с rc.local заключается в том, что доступ к командам осуществляется с правами root, что отличается от входа в систему как пользователя и использования sudo.

Я решил эту проблему, добавив скрипт .sh с командами запуска, которые я хочу, в etc / profile.d. Любой файл .sh в profile.d будет загружен автоматически, и любая команда будет обрабатываться так, как если бы вы использовали обычный sudo.

Единственным недостатком этого является то, что указанный пользователь должен войти в систему, чтобы все началось, что в моей ситуации всегда было так.


1

Я перепробовал множество приведенных выше ответов. Никто из них не работал для меня. Мое приложение установлено /homeкак пользователь, а не как пользователь root. Это, вероятно, означает, что при запуске вышеупомянутых стартовых скриптов,/home еще не смонтированы, поэтому приложение не запускается.

Затем я нашел эти инструкции от Digital Ocean:

https://www.digitalocean.com/community/tutorials/how-to-use-pm2-to-setup-a-node-js-production-environment-on-an-ubuntu-vps

Использование PM2, как объяснено, было очень простым и прекрасно работает: с тех пор на моих виртуальных серверах произошли два физических сбоя - время простоя составило всего около минуты.


У PM2 гораздо больше звезд (2х) на github, чем навсегда, и у него больше возможностей. Я думаю, что большинство ответов здесь устарели.
inf3rno

0

полный пример crontab (находится в / etc / crontab).

#!/bin/bash

# edit this file with .. crontab -u root -e
# view this file with .. crontab -u root -l

# put your path here if it differs
PATH=/root/bin:/root/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin

# * * * * * echo "executes once every minute" > /root/deleteme

@reboot cd /root/bible-api-dbt-server; npm run forever;
@reboot cd /root/database-api-server; npm run forever;
@reboot cd /root/mailer-api-server; npm run forever;

-2

Вы можете использовать следующую команду в своей оболочке, чтобы запустить ваш узел навсегда:

forever app.js //my node script

Вы должны помнить, что сервер, на котором работает ваше приложение, всегда должен быть включен.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.