Beim Neustart des Systems automatisch für immer (Knoten) starten

190

Ich verwende das Forever-Modul des Knotens, um meinen Knotenserver am Laufen zu halten. Für immer wird jedoch beendet, wenn ein Systemneustart erfolgt. Gibt es eine Möglichkeit, den Knotenserver beim Neustart des Systems automatisch (mit für immer) zu starten?

kehers
quelle
1
Befindet sich dieser Server in der Cloud? Haben Sie Boot-Skripte dafür?
Jorge Aranda
6
Kasse PM2 ! Es unterstützt auch die Generierung von Startskripten (systemd, systemv ...) pm2.keymetrics.io/docs/usage/startup
Unitech

Antworten:

341

Ich würde vorschlagen, Crontab zu verwenden. Es ist einfach zu bedienen.

Wie man

  1. Um mit der Bearbeitung zu beginnen, führen Sie Folgendes aus, indem Sie den "Testbenutzer" durch Ihren gewünschten Laufzeitbenutzer für den Knotenprozess ersetzen. Wenn Sie einen anderen Benutzer als sich selbst auswählen, müssen Sie dies mit sudo ausführen.

    $ crontab -u testuser -e
  2. Wenn Sie dies noch nie zuvor getan haben, werden Sie gefragt, mit welchem ​​Editor Sie bearbeiten möchten. Ich mag Vim, werde aber Nano empfehlen, um die Bedienung zu vereinfachen.

  3. Fügen Sie im Editor die folgende Zeile hinzu:

    @reboot /usr/local/bin/forever start /your/path/to/your/app.js
  4. Speicher die Datei. Sie sollten eine Rückmeldung erhalten, dass der Cron installiert wurde.

  5. Führen Sie zur weiteren Bestätigung der Installation des Cron Folgendes aus (ersetzen Sie erneut "testuser" durch Ihren Zielbenutzernamen), um die aktuell installierten Cron aufzulisten:

    $ crontab -u testuser -l 

Beachten Sie, dass Sie meiner Meinung nach immer vollständige Pfade verwenden sollten, wenn Sie Binärdateien in cron ausführen. Wenn der Pfad zu Ihrem Skript für immer nicht korrekt ist, führen Sie ihn aus which forever, um den vollständigen Pfad abzurufen.

Angesichts dieser foreverAnrufe nodemöchten Sie möglicherweise auch den vollständigen Pfad angeben zu node:

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

Weiterführende Literatur

Julian Lannigan
quelle
2
Dieser Ansatz ist gut, aber nur in den Fällen, in denen das System neu gestartet wird. Wenn der Server heruntergefahren und dann eingeschaltet wird, wird dieser Cron-Job nicht ausgeführt.
Ecdeveloper
6
Was bringt dich dazu, das zu denken? en.wikipedia.org/wiki/Cron#Predefined_scheduling_definitions Erklärt, dass @rebootCron's auf dem Cron Deamon gestartet werden. Außerdem bin ich noch nie auf eine Situation gestoßen, die darauf hindeutet, dass meine Cron-Werte, die auf eingestellt sind, beim @rebootSystemstart nicht ausgeführt werden. Die Art und Weise, wie Sie es herunterfahren, spielt dabei keine Rolle.
Julian Lannigan
16
Es scheint /homenoch nicht gemountet zu sein, daher funktioniert dies nicht, wenn Ihr Code darin lebt /home.
Chovy
6
Ich habe festgestellt, dass das oben Gesagte für mich fehlgeschlagen ist, weil sich der Knoten nicht im Pfad befindet, wenn cron versucht, für immer zu laufen, selbst mit der Option -c. Es stellt sich jedoch heraus, dass Sie eine PATH = -Anweisung direkt in der crontab hinzufügen können, solange sie über den Schedule-Anweisungen liegt. Sobald PATH gesetzt ist, hat die @ reboot-Anweisung wie ein Traum funktioniert.
YorkshireKev
2
Vielen Dank für Ihren Kommentar @chovy, es war sehr hilfreich. Beachten Sie für diejenigen, die Umgebungsvariablen von bashrc verwenden, seinen Kommentar. Da / home nicht gemountet ist, funktioniert es nicht. Setzen Sie die Variablen am Befehl crontab wie@reboot varname=value ...
lsborg
123

Sie können dazu den Forever-Service verwenden.

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

Dadurch wird app.js im aktuellen Verzeichnis für immer als Dienst bereitgestellt. Der Dienst wird bei jedem Neustart des Systems automatisch neu gestartet. Auch wenn es gestoppt wird, wird es einen anmutigen Stopp versuchen. Dieses Skript stellt auch das Logrotate-Skript bereit.

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

HINWEIS: Ich bin der Autor von forever-service.

arva
quelle
2
Verwenden Sie die Option -e "PORT = 80 ENV = prod FOO = bar"
arva
2
Ich verstehe nicht, wie ich für immer arbeiten soll. Was ist dieser "Test" in "Forever-Service-Installationstest"? Mein Befehl, meine App für immer zu starten, lautet: "/ usr / local / bin / für immer starten -c / usr / lokal / bin / knoten / home / alex / public / knotenmodule / http-server / bin / http-server -s - d false ". Was müsste ich schreiben?
Alex
3
Test hier ist der Name des Dienstes. Wenn Sie den Installationstest für immer ausführen, wird ein Dienst namens test erstellt, um app.js in diesem Verzeichnis auszuführen und als Dienst auszuführen. Ich würde empfehlen, die Hilfedokumentation auf der Gihub-Seite zu lesen und dort ein Problem hinzuzufügen, wenn Sie es nicht verstehen können.
Arva
6
@ Alex - im Beispiel - arva Kommentar zu klären forever-service install test, testwird der Name des Service , aber nicht der Name des aktuellen Programms / node js - Datei auszuführen. Standardmäßig wird davon ausgegangen, dass der Name des Programms lautet app.js. Sie können ihn jedoch --scriptwie folgt mit dem Flag überschreiben : forever-service install test --script main.js. (Ungetestet, bitte korrigieren Sie mich, wenn Syntaxdetails falsch sind.)
Dan Nissenbaum
3
@ DanNissenbaum Danke für die Antwort. Ich benutze jetzt PM2, was wunderbar funktioniert. Anleitung: digitalocean.com/community/tutorials/…
Alex
26

Dieser Fall gilt für Debian.

Fügen Sie Folgendes hinzu: /etc/rc.local

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

  • {{user}} ersetzt Ihren Benutzernamen.
  • {{app path}}ersetzt Ihren App-Pfad. Beispielsweise,/var/www/test/app.js
NiLL
quelle
2
Diese Methode behandelt keine ordnungsgemäßen Abschaltungen, obwohl dies für viele Menschen wahrscheinlich kein Problem darstellt.
UpTheCreek
6
Übrigens - ich denke, Sie sollten bearbeiten /etc/rc.local, nicht/etc/init.d/rc.local
UpTheCreek
Stimmen Sie mit @UpTheCreek überein, dass /etc/rc.local der geeignetere Ort ist, um dies hinzuzufügen - eine gute Erklärung finden Sie unter: unix.stackexchange.com/a/59945 .
Also
2
Möglicherweise möchten Sie auch das 'aktuelle Arbeitsverzeichnis' angeben, app.jsum sicherzustellen, dass die relativen Dateien korrekt geladen werden - process.chdir('/your/path/to/your/app'); Node.js Referenzdokumente hier
So Over It
1
Wenn Sie Umgebungsvariablen für Ihr Node.JS-Skript festlegen müssen (wie $ PORT für Express), haben Sie die folgende Zeile hinzugefügt, um /etc/rc.localden Trick für mich zu ( cd /path/to/project && /usr/bin/sudo -u {{user}} env PORT={{port number}} PATH=$PATH:/usr/local/bin sh -c "forever start app.js" )
erledigen
25
  1. Installieren Sie PM2 global mit NPM

    npm install pm2 -g

  2. Starten Sie Ihr Skript mit pm2

    pm2 start app.js

  3. Generieren Sie ein aktives Startskript

    pm2 startup

    HINWEIS: Der Start von pm2 dient zum Starten von PM2 beim Neustart des Systems. PM2 startet nach dem Start alle Prozesse neu, die vor dem Systemausfall verwaltet wurden.

Wenn Sie den automatischen Start deaktivieren möchten, verwenden Sie einfach pm2 unstartup

Wenn Sie möchten, dass das Startskript unter einem anderen Benutzer ausgeführt wird, verwenden Sie einfach die -u <username>Option und die--hp <user_home>:

fsamuel
quelle
Bitte posten Sie nicht dieselbe Antwort auf mehrere Fragen.
FelixSFD
Ich liebe es wirklich, wie pm2 verfeinert wird und mit einem großartigen Überwachungstool geliefert wird. Hoffe, dies wird mehr für andere hervorgehoben. @ rv7 Ich bin sicher, Sie haben das gesehen, aber es gibt eine Windows-Lösung: npmjs.com/package/pm2-windows-service . Ich habe es aber nicht selbst versucht.
John Lee
11

Eine alternative Crontab-Methode, die von dieser Antwort und diesem Blog-Beitrag inspiriert wurde .

1. Erstellen Sie eine Bash-Skriptdatei (ändern Sie Bob in den gewünschten Benutzer).

vi /home/bob/node_server_init.sh

2. Kopieren Sie diese und fügen Sie sie in die gerade erstellte Datei ein.

#!/bin/sh

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

Stellen Sie sicher, dass Sie die obigen Pfade entsprechend Ihrer Konfiguration bearbeiten!

3. Stellen Sie sicher, dass das Bash-Skript ausgeführt werden kann.

chmod 700 /home/bob/node_server_init.sh

4. Testen Sie das Bash-Skript.

sh /home/bob/node_server_init.sh

5. Ersetzen Sie "bob" durch den Laufzeitbenutzer für den Knoten.

crontab -u bob -e

6. Kopieren und einfügen (Bob auf gewünschten Benutzer ändern).

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

Speichern Sie die Crontab.

Du hast es bis zum Ende geschafft, dein Preis ist ein Neustart (zum Testen) :)

Emre
quelle
Diese Methode hat bei mir am besten funktioniert. Forever würde beendet, wenn ich einen vollständigen Pfad zur Datei server.js eingebe. Wenn ich es im selben Verzeichnis ausführen würde, würde Foreveer gut funktionieren. Der Grund, warum dies fehlgeschlagen ist, ist, dass die Datei server.js andere Dateien enthielt, die Pfade jedoch durcheinander gebracht wurden. Mit dieser Methode konnte ich in meinem .sh-Skript eine CD in das Verzeichnis erstellen und dann alles relativ dazu ausführen.
BeardedGeek
9

Kopierte Antwort von der beigefügten Frage .

Sie können PM2 verwenden , einen Produktionsprozessmanager für Node.js-Anwendungen mit integriertem Load Balancer.

Installieren Sie PM2

$ npm install pm2 -g

Starten Sie eine Anwendung

$ pm2 start app.js

Wenn Sie Express verwenden, können Sie Ihre App wie starten

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

Auflistung aller laufenden Prozesse:

$ pm2 list

Es werden alle Prozesse aufgelistet. Sie können Ihren Dienst dann stoppen / neu starten, indem Sie die ID oder den Namen der App mit dem folgenden Befehl verwenden.

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

Protokolle anzeigen

$ pm2 logs ['all'|app_name|app_id]
Vikash Rajpurohit
quelle
Wie startet es beim Systemstart AUTOMATISCH ? Sie kopieren / fügen gerade CLI manuelle Eingabe
Grün
@Green, Run, $pm2 startupDanach wird pm2 aufgefordert, einen Befehl manuell auszuführen, zu kopieren und auszuführen. Dann, $pm2 savejetzt überlebt Ihre app.js Systemneustarts
yajnesh
7

Dazu müssen Sie im Ordner /etc/init.d ein Shell-Skript erstellen. Es ist etwas kompliziert, wenn Sie es noch nie getan haben, aber es gibt im Web viele Informationen zu init.d-Skripten.

Hier ist ein Beispiel für ein Skript, das ich erstellt habe, um eine CoffeeScript-Site für immer auszuführen:

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

Ich musste sicherstellen, dass der Ordner und die PATHs explizit festgelegt wurden oder dem Root-Benutzer zur Verfügung standen, da init.d-Skripte als root ausgeführt werden.

Hector Correa
quelle
2
Wenn Sie Abhängigkeiten haben, die auch mit init.d gestartet werden, können jedoch Probleme mit der Ladereihenfolge auftreten.
UpTheCreek
@ alexandru.topliceanu Ich habe den Link behoben.
Hector Correa
6

Verwenden Sie die PM2

Welches ist die beste Option, um den Server Produktionsserver auszuführen

Was sind die Vorteile einer solchen Ausführung Ihrer Anwendung?

  • PM2 startet Ihre Anwendung automatisch neu, wenn sie abstürzt.

  • PM2 führt ein Protokoll Ihrer nicht behandelten Ausnahmen - in diesem Fall in einer Datei unter /home/safeuser/.pm2/logs/app-err.log.

  • Mit einem Befehl kann PM2 sicherstellen, dass alle von ihm verwalteten Anwendungen beim Neustart des Servers neu gestartet werden. Grundsätzlich wird Ihre Knotenanwendung als Dienst gestartet.

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

Vishnu Mishra
quelle
5

Forever wurde nicht erstellt, um Knotenanwendungen als Dienste auszuführen. Der richtige Ansatz besteht darin, entweder einen / etc / inittab-Eintrag (alte Linux-Systeme) oder einen Upstart (neuere Linux-Systeme) zu erstellen.

Hier finden Sie einige Dokumentationen zum Einrichten als Upstart: https://github.com/cvee/node-upstart

snez
quelle
Upstart hat mich unter CentOS gescheitert und ich habe gelesen, dass es verschwinden wird. Das Erstellen eines init.d-Eintrags ist nicht wirklich die benutzerfreundlichste Methode, aber ich nehme an, es ist Linux :)
Jorre
5

crontabfunktioniert bei mir unter CentOS x86 6.5 nicht. @reboot scheint nicht zu funktionieren.

Endlich habe ich diese Lösung:

Bearbeiten: /etc/rc.local

sudo vi /etc/rc.local

Fügen Sie diese Zeile am Ende der Datei hinzu. Ändern Sie USER_NAMEund PATH_TO_PROJECTzu Ihren eigenen. NODE_ENV=productionbedeutet, dass die App im Produktionsmodus ausgeführt wird. Sie können weitere Zeilen hinzufügen, wenn Sie mehr als eine node.js-App ausführen müssen.

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

Nicht NODE_ENVin einer separaten Zeile festlegen , Ihre App wird weiterhin im Entwicklungsmodus ausgeführt, da dies für immer nicht möglich ist NODE_ENV.

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

Speichern und beenden Sie vi (drücken Sie ESC : w q return ). Sie können versuchen, Ihren Server neu zu starten. Nach dem Neustart Ihres Servers sollte Ihre node.js-App automatisch ausgeführt werden, auch wenn Sie sich nicht über ssh remote bei einem Konto anmelden.

Sie sollten die NODE_ENVUmgebung besser in Ihre Shell einfügen. NODE_ENVwird automatisch festgelegt, wenn sich Ihr Konto USER_NAMEanmeldet.

echo export NODE_ENV=production >> ~/.bash_profile

So können Sie Befehle wie für immer stoppen / starten /PATH_TO_PROJECT/app.jsüber ssh ausführen, ohne sie NODE_ENVerneut einzustellen .

Vince Yuan
quelle
habe das gleiche Problem auf Debian 7.6. Das ist für mich behoben. Danke vielmals.
Daniele Vrut
Nur für den Fall, dass Sie 'für immer' nicht verwenden möchten, können Sie die Zeile in 'su - USER_NAME -c "NODE_ENV = Produktionsknoten / PATH_TO_PROJECT / bin / www"' ändern.
Yaobin
3

Ich habe ein Skript geschrieben, das genau das tut:

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

Ich habe es nicht für immer versucht, aber Sie können den ausgeführten Befehl anpassen, sodass er einfach sein sollte:

/etc/init.d/node-app start
/etc/init.d/node-app restart
/etc/init.d/node-app stop
chovy
quelle
1

Ich habe viele der oben genannten Antworten ausprobiert. Keiner von ihnen hat für mich gearbeitet. Meine App ist in /homeund als Benutzer installiert , nicht als root. Dies bedeutet wahrscheinlich, dass, wenn die oben genannten Startskripte ausgeführt werden,/home noch nicht gemountet ist und die App daher nicht gestartet wird.

Dann habe ich diese Anleitung von Digital Ocean gefunden:

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

Die Verwendung von PM2 war sehr einfach und funktioniert einwandfrei: Meine virtuellen Server hatten seitdem zwei physische Abstürze - die Ausfallzeit betrug nur etwa eine Minute.

Alex
quelle
PM2 hat viel mehr Sterne (2x) auf Github als für immer und es hat auch mehr Funktionen. Ich denke, die meisten Antworten sind hier veraltet.
inf3rno
1

Das Problem mit rc.local besteht darin, dass auf die Befehle als root zugegriffen wird, was sich von der Anmeldung als Benutzer und der Verwendung von sudo unterscheidet.

Ich habe dieses Problem gelöst, indem ich ein .sh-Skript mit den Startbefehlen hinzugefügt habe, die ich usw. / profile.d möchte. Jede .sh-Datei in profile.d wird automatisch geladen und jeder Befehl wird so behandelt, als ob Sie das reguläre sudo verwendet hätten.

Der einzige Nachteil dabei ist, dass sich der angegebene Benutzer anmelden muss, damit Dinge beginnen, was in meiner Situation immer der Fall war.

Moe Elsharif
quelle
0

vollständiges Beispiel crontab (befindet sich unter / 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
quelle
-1

Sie können den folgenden Befehl in Ihrer Shell verwenden, um Ihren Knoten für immer zu starten:

forever app.js //my node script

Sie müssen berücksichtigen, dass der Server, auf dem Ihre App ausgeführt wird, immer eingeschaltet bleiben sollte.

Gaurav Singh
quelle