Automatycznie uruchom na zawsze (węzeł) przy ponownym uruchomieniu systemu

190

Korzystam z modułu wieczności węzła, aby utrzymać działanie serwera węzłów. Na zawsze jednak kończy się, gdy nastąpi restart systemu. Czy jest jakiś sposób, aby automatycznie uruchomić serwer węzłów (na zawsze) po ponownym uruchomieniu systemu?

kehers
źródło
1
Czy ten serwer jest w chmurze? Czy masz do tego jakieś skrypty rozruchowe?
Jorge Aranda
6
Kasa PM2 ! Obsługuje również generowanie skryptów startowych (systemd, systemv ...) pm2.keymetrics.io/docs/usage/startup
Unitech

Odpowiedzi:

343

Sugerowałbym użycie crontab. Jest łatwy w użyciu.

Jak

  1. Aby rozpocząć edycję, uruchom następującą procedurę, zastępując „testser” wybranym użytkownikiem środowiska wykonawczego dla procesu węzła. Jeśli wybierzesz innego użytkownika niż ty, będziesz musiał uruchomić to z sudo.

    $ crontab -u testuser -e
  2. Jeśli nigdy wcześniej tego nie robiłeś, pojawi się pytanie, z którym edytorem chcesz edytować. Lubię vima, ale polecę nano dla łatwości użytkowania.

  3. Raz w edytorze dodaj następujący wiersz:

    @reboot /usr/local/bin/forever start /your/path/to/your/app.js
  4. Zapisz plik. Powinieneś otrzymać informację zwrotną, że cron został zainstalowany.

  5. Aby uzyskać dalsze potwierdzenie instalacji crona, wykonaj następujące czynności (ponownie zastępując „testser” docelową nazwą użytkownika), aby wyświetlić listę aktualnie zainstalowanych cronów:

    $ crontab -u testuser -l 

Zauważ, że moim zdaniem zawsze powinieneś używać pełnych ścieżek podczas uruchamiania plików binarnych w cronie. Ponadto, jeśli ścieżka do twojego wiecznego skryptu jest nieprawidłowa, uruchom, which foreveraby uzyskać pełną ścieżkę.

Biorąc pod uwagę te foreverpołączenia node, możesz także podać pełną ścieżkę do node:

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

Dalsza lektura

Julian Lannigan
źródło
2
Takie podejście jest dobre, ale tylko w tych przypadkach, gdy system zostanie ponownie uruchomiony. Jeśli serwer zostanie zamknięty, a następnie włączony - to zadanie cron nie zostanie wykonane.
ecdeveloper
6
Dlaczego tak sądzisz? en.wikipedia.org/wiki/Cron#Predefined_scheduling_definitions Wyjaśnia, że @rebootcron jest uruchamiany na deamonie crona od początku. Aby dodać, nigdy nie spotkałem się z sytuacją, która sugerowałaby, że moje crony ustawione na @rebootnie uruchamiają się przy starcie systemu. Sposób, w jaki go wyłączasz, nie ma w tym przypadku znaczenia.
Julian Lannigan
16
wygląda na /hometo, że nie jest jeszcze zamontowany, więc to nie zadziała, jeśli Twój kod mieszka /home.
chovy
6
Odkryłem, że powyższe nie powiodło się, ponieważ węzeł nie znajduje się na ścieżce, gdy cron próbuje działać wiecznie, nawet z opcją -c. Okazuje się jednak, że można dodać instrukcję PATH = bezpośrednio do tabeli crontab, o ile jest ona powyżej instrukcji harmonogramu. Po ustawieniu PATH instrukcja @reboot działała jak sen.
YorkshireKev
2
Dzięki za komentarz @chovy, był bardzo pomocny. Jeśli używasz zmiennych środowiskowych z bashrc, zwróć uwagę na jego komentarz. Ponieważ / home nie jest zamontowane, nie będzie działać. Ustaw zmienne w poleceniu crontab, np.@reboot varname=value ...
lsborg,
123

W tym celu możesz skorzystać z usługi Forever-Service.

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

Zapewni to app.js w bieżącym katalogu jako usługę przez wieczność. Usługa zostanie automatycznie uruchomiona ponownie przy każdym ponownym uruchomieniu systemu. Również po zatrzymaniu spróbuje zatrzymać się z gracją. Ten skrypt zawiera również skrypt logrotate.

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

UWAGA: Jestem autorem serwisu na zawsze.

arva
źródło
2
Użyj opcji -e „PORT = 80 ENV = prod FOO = pasek”
arva
2
Nie rozumiem, jak uruchomić usługę na zawsze. Co to jest „test” w „teście instalacji na zawsze”? Moje polecenie, aby uruchomić moją aplikację na zawsze to: "/ usr / local / bin / forever start -c / usr / local / bin / node / home / alex / public / node_modules / http-server / bin / http-server -s - d false ”. Co miałbym napisać?
Alex
3
test tutaj to nazwa usługi. po uruchomieniu testu instalacji Forever-service tworzona jest usługa o nazwie test, aby uruchomić app.js w tym katalogu i uruchomić jako usługę. Proponuję przeczytać dokumentację pomocy na stronie gihub i dodać problem, jeśli nie możesz go zrozumieć.
arva
6
@Alex - wyjaśnienie komentarz ARVA użytkownika - w tym przykładzie forever-service install test, testbędzie to nazwa usługi , ale nie nazwa pliku właściwego programu / node .js do uruchomienia. Domyślnie zakłada nazwa programu jest app.js, ale można zastąpić go z --scriptflagą, co następuje: forever-service install test --script main.js. (Niesprawdzone, więc popraw mnie, jeśli coś jest nie tak.)
Dan Nissenbaum
3
@DanNissenbaum Dzięki za odpowiedź. Teraz używam PM2, który działa pięknie. Instrukcje: digitalocean.com/community/tutorials/…
Alex
26

Ten przypadek dotyczy Debiana.

Dodaj następujące elementy do /etc/rc.local

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

  • {{user}} zastępuje twoją nazwę użytkownika.
  • {{app path}}zastępuje ścieżkę aplikacji. Na przykład,/var/www/test/app.js
NiLL
źródło
2
Ta metoda nie radzi sobie z wdzięcznymi wyłączeniami, chociaż dla wielu osób prawdopodobnie nie stanowi to problemu.
UpTheCreek
6
BTW - Myślę, że powinieneś edytować /etc/rc.local, a nie/etc/init.d/rc.local
UpTheCreek
Zgadzam się z @UpTheCreek, że /etc/rc.local jest bardziej odpowiednim miejscem do dodania tego - zobacz: unix.stackexchange.com/a/59945, aby uzyskać świetne wyjaśnienie.
So Over It
2
Możesz także określić „bieżący katalog roboczy”, app.jsaby upewnić się, że względne pliki są ładowane poprawnie - process.chdir('/your/path/to/your/app'); Dokumenty referencyjne Node.js tutaj
So Over It
1
Jeśli musisz ustawić zmienne środowiskowe dla skryptu Node.JS (np. $ PORT dla express), dodaj następujący wiersz, aby załatwić sprawę /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" )
załatwić sprawę sffc
25
  1. Zainstaluj PM2 globalnie za pomocą NPM

    npm install pm2 -g

  2. Rozpocznij skrypt z pm2

    pm2 start app.js

  3. wygeneruj aktywny skrypt startowy

    pm2 startup

    UWAGA: Uruchomienie pm2 służy do uruchomienia PM2 po ponownym uruchomieniu systemu. Po uruchomieniu PM2 ponownie uruchamia wszystkie procesy, którymi zarządzał przed awarią systemu.

Jeśli chcesz wyłączyć automatyczne uruchamianie, po prostu użyj PM2 Unstartup

Jeśli chcesz, aby skrypt startowy był wykonywany przez innego użytkownika, po prostu użyj -u <username>opcji i--hp <user_home>:

fsamuel
źródło
Nie zamieszczaj tej samej odpowiedzi na wiele pytań.
FelixSFD
Naprawdę uwielbiam to, w jaki sposób PM2 jest dopracowane i zawiera niesamowite narzędzie do monitorowania. Mam nadzieję, że jest to podkreślone bardziej dla innych. @ rv7 Jestem pewien, że to widziałeś, ale istnieje rozwiązanie dla systemu Windows: npmjs.com/package/pm2-windows-service . Jednak sam tego nie próbowałem.
John Lee
11

Alternatywna metoda crontab zainspirowana odpowiedzią i tym wpisem na blogu.

1. Utwórz plik skryptu bash (zmień boba na żądanego użytkownika).

vi /home/bob/node_server_init.sh

2. Skopiuj i wklej to w właśnie utworzonym pliku.

#!/bin/sh

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

Edytuj powyższe ścieżki zgodnie z konfiguracją!

3. Upewnij się, że skrypt bash może zostać wykonany.

chmod 700 /home/bob/node_server_init.sh

4. Przetestuj skrypt bash.

sh /home/bob/node_server_init.sh

5. Zamień „bob” na użytkownika wykonawczego dla węzła.

crontab -u bob -e

6. Skopiuj i wklej (zmień boba na żądanego użytkownika).

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

Uratuj crontab.

Dotarłeś do końca, twoją nagrodą jest ponowne uruchomienie (do przetestowania) :)

Emre
źródło
Ta metoda działała dla mnie najlepiej. Forever przestanie działać, gdy podam pełną ścieżkę do pliku server.js. Gdybym uruchomił go w tym samym katalogu, Foreveer działałby dobrze. Przyczyną niepowodzenia był plik server.js, który zawierał inne pliki, ale ścieżki zostały pomieszane. Korzystając z tej metody, mogę wykonać CD w skrypcie .sh do katalogu, a następnie uruchomić wszystko względem niego.
BeardedGeek,
9

Skopiowano odpowiedź z załączonego pytania .

Możesz użyć PM2 , jest to menedżer procesów produkcyjnych dla aplikacji Node.js z wbudowanym modułem równoważenia obciążenia.

Zainstaluj PM2

$ npm install pm2 -g

Uruchom aplikację

$ pm2 start app.js

Jeśli używasz ekspresowego, możesz uruchomić aplikację tak jak

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

Lista wszystkich uruchomionych procesów:

$ pm2 list

Wyświetli listę wszystkich procesów. Następnie możesz zatrzymać / uruchomić ponownie usługę, używając identyfikatora lub nazwy aplikacji za pomocą następującego polecenia.

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

Aby wyświetlić dzienniki

$ pm2 logs ['all'|app_name|app_id]
Vikash Rajpurohit
źródło
Jak uruchamia się AUTOMATYCZNIE podczas uruchamiania systemu? Właśnie skopiowałeś / wkleiłeś ręczne pisanie w interfejsie CLI
Green
@Zielony, Uruchom, $pm2 startupPo tym zobaczysz pm2 z prośbą o ręczne uruchomienie polecenia, skopiowanie i uruchomienie tego. Wtedy $pm2 saveteraz Twoja aplikacja.js przetrwa
ponowne
7

W tym celu musisz utworzyć skrypt powłoki w folderze /etc/init.d. Jest to trochę skomplikowane, jeśli nigdy tego nie robiłeś, ale w Internecie jest mnóstwo informacji na temat skryptów init.d.

Oto przykład skryptu, który utworzyłem, aby uruchomić witrynę CoffeeScript na zawsze:

#!/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

Musiałem się upewnić, że folder i ścieżki są jawnie ustawione lub dostępne dla użytkownika root, ponieważ skrypty init.d są uruchamiane jako root.

Hector Correa
źródło
2
Jeśli masz jakieś zależności, które również zaczynają się od init.d, możesz mieć problemy z kolejnością ładowania.
UpTheCreek
@ alexandru.topliceanu Naprawiłem link.
Hector Correa,
6

Użyj PM2

Która jest najlepsza opcja do uruchomienia serwera produkcyjnego serwera

Jakie są zalety uruchamiania aplikacji w ten sposób?

  • PM2 automatycznie uruchomi ponownie aplikację, jeśli ulegnie awarii.

  • PM2 będzie przechowywać dziennik nieobsługiwanych wyjątków - w tym przypadku w pliku pod adresem /home/safeuser/.pm2/logs/app-err.log.

  • Za pomocą jednego polecenia PM2 może zapewnić, że wszystkie zarządzane przez niego aplikacje uruchomią się ponownie po ponownym uruchomieniu serwera. Zasadniczo aplikacja węzła zostanie uruchomiona jako usługa.

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

Wisznu Miszra
źródło
5

Forever nie został stworzony do uruchamiania aplikacji węzłów jako usług. Właściwym podejściem jest albo utworzenie wpisu / etc / inittab (stare systemy Linux) lub upstart (nowsze systemy Linux).

Oto dokumentacja, w jaki sposób ustawić to jako upstart: https://github.com/cvee/node-upstart

kichać
źródło
Upstart zawiódł mnie na CentOS i przeczytałem, że zniknie. Utworzenie wpisu init.d nie jest tak naprawdę najbardziej przyjazny dla użytkownika, ale przypuszczam, że jest to linux :)
Jorre
5

crontabnie działa dla mnie na CentOS x86 6.5. @reboot wydaje się nie działać.

Wreszcie mam to rozwiązanie:

Edytować: /etc/rc.local

sudo vi /etc/rc.local

Dodaj ten wiersz na końcu pliku. Zmień USER_NAMEi PATH_TO_PROJECTna własny. NODE_ENV=productionoznacza, że ​​aplikacja działa w trybie produkcyjnym. Możesz dodać więcej linii, jeśli chcesz uruchomić więcej niż jedną aplikację node.js.

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

Nie ustawiaj NODE_ENVw osobnym wierszu, Twoja aplikacja będzie nadal działać w trybie programowania, ponieważ wieczność się nie pojawi NODE_ENV.

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

Zapisz i wyjdź z vi (naciśnij ESC : w q return ). Możesz spróbować zrestartować serwer. Po ponownym uruchomieniu serwera aplikacja node.js powinna uruchomić się automatycznie, nawet jeśli nie logujesz się na żadne konto zdalnie przez ssh.

Lepiej ustaw NODE_ENVśrodowisko w swojej powłoce. NODE_ENVzostanie ustawiony automatycznie po USER_NAMEzalogowaniu się na konto .

echo export NODE_ENV=production >> ~/.bash_profile

Możesz więc uruchamiać polecenia takie jak na zawsze stop / start /PATH_TO_PROJECT/app.jsprzez ssh bez NODE_ENVponownego ustawiania .

Vince Yuan
źródło
dostałem ten sam problem w debianie 7.6. To naprawiło dla mnie. Wielkie dzięki.
Daniele Vrut
Na wypadek, gdybyś nie chciał używać „na zawsze”, możesz zmienić wiersz na „su - USER_NAME -c” NODE_ENV = węzeł produkcyjny / PATH_TO_PROJECT / bin / www ”.
yaobin
3

Napisałem skrypt, który robi dokładnie to:

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

Nie próbowałem z wiecznością, ale możesz dostosować uruchamiane polecenie, więc powinno być proste:

/etc/init.d/node-app start
/etc/init.d/node-app restart
/etc/init.d/node-app stop
chovy
źródło
1

Próbowałem wiele z powyższych odpowiedzi. Żadne z nich nie działało dla mnie. Moja aplikacja jest zainstalowana /homejako użytkownik, a nie jako użytkownik root. Prawdopodobnie oznacza to, że po uruchomieniu wyżej wymienionych skryptów startowych/home nie jest jeszcze zamontowane, więc aplikacja się nie uruchamia.

Potem znalazłem te instrukcje autorstwa Digital Ocean:

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

Używanie PM2 jak wyjaśniono było bardzo proste i działa idealnie: Moje wirtualne serwery miały dwie fizyczne awarie, ponieważ - czas przestoju wynosił tylko około minuty.

Alex
źródło
PM2 ma znacznie więcej gwiazdek (2x) na githubie niż na zawsze i ma również więcej funkcji. Myślę, że większość odpowiedzi jest tutaj nieaktualna.
inf3rno
1

Problem z rc.local polega na tym, że komendy są dostępne jako root, co różni się od zalogowania jako użytkownik i używania sudo.

Rozwiązałem ten problem, dodając skrypt .sh z poleceniami uruchamiania, które chcę etc / profile.d. Każdy plik .sh w profilu.d zostanie załadowany automatycznie, a każde polecenie będzie traktowane tak, jakbyś używał zwykłego sudo.

Jedynym minusem jest to, że określony użytkownik musi się zalogować, aby rozpocząć, co w mojej sytuacji zawsze miało miejsce.

Moe Elsharif
źródło
0

kompletny przykład crontab (znajduje się w / 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;
danday74
źródło
-1

Możesz użyć następującego polecenia w powłoce, aby uruchomić węzeł na zawsze:

forever app.js //my node script

Należy pamiętać, że serwer, na którym działa aplikacja, powinien być zawsze włączony.

Gaurav Singh
źródło