Wie führe ich eine Node.js-Anwendung als eigenen Prozess aus?

194

Was ist der beste Weg, um Node.js bereitzustellen?

Ich habe einen Dreamhost-VPS (so nennt man eine VM ), und ich konnte Node.js installieren und einen Proxy einrichten. Dies funktioniert hervorragend, solange ich die SSH-Verbindung, mit der ich den Knoten gestartet habe, offen halte.

respektiere den Code
quelle
6
Hmm, es scheint mir seltsam, dass Sie Forever als "Bereitstellen von node.js" aufrufen. Ist es nicht nur ein Tool zur Prozessüberwachung / -überwachung? Normalerweise bedeutet Webbereitstellung (zumindest das, was mir in Artikeln begegnet) mehrere miteinander verbundene Aktivitäten, die eine Webanwendung verfügbar machen (dieses Prozesstool ist ein Teil davon). Wie auch immer, dies ist immer noch ein großartiger Beitrag hier in StackOverflow, wie ich aus den Antworten aller gelernt habe.
Mikong
Dies ist nur die einfachste Bereitstellung von node.js auf Dreamhost. Das Ziel war einfach, den Knoten als Ausgangspunkt für den Aufbau zuverlässig zum Laufen zu bringen.
Respektieren Sie den Code
Wie haben Sie mit der Weiterleitung der Domäne an den Portknoten umgegangen?
grm
2
@grm Ich benutze HTTP-Proxy github.com/nodejitsu/node-http-proxy
RespektTheCode
Wir verwenden jetzt Elastic Beanstalk und es funktioniert ganz gut.
Respektieren Sie den Code

Antworten:

106

Antwort 2016 : Fast jede Linux-Distribution wird mit systemd geliefert , was bedeutet, dass für immer Monit, PM2 usw. nicht mehr erforderlich sind - Ihr Betriebssystem erledigt diese Aufgaben bereits .

myapp.serviceErstellen Sie eine Datei (ersetzen Sie 'myapp' natürlich durch den Namen Ihrer App):

[Unit]
Description=My app

[Service]
ExecStart=/var/www/myapp/app.js
Restart=always
User=nobody
# Note Debian/Ubuntu uses 'nogroup', RHEL/Fedora uses 'nobody'
Group=nobody
Environment=PATH=/usr/bin:/usr/local/bin
Environment=NODE_ENV=production
WorkingDirectory=/var/www/myapp

[Install]
WantedBy=multi-user.target

Beachten Sie, wenn Sie neu in Unix sind: /var/www/myapp/app.js sollte #!/usr/bin/env nodein der ersten Zeile stehen.

Kopieren Sie Ihre Servicedatei in den /etc/systemd/systemOrdner.

Informieren Sie systemd über den neuen Dienst mit systemctl daemon-reload.

Beginnen Sie mit systemctl start myapp.

Aktivieren Sie es, um beim Booten mit ausgeführt zu werden systemctl enable myapp.

Siehe Protokolle mit journalctl -u myapp

Dies stammt aus der Bereitstellung von Knoten-Apps unter Linux, Ausgabe 2018 , die auch Befehle zum Generieren einer AWS / DigitalOcean / Azure-CloudConfig zum Erstellen von Linux- / Knotenservern (einschließlich der .serviceDatei) enthält.

Mikemaccana
quelle
1
Irgendeine Idee, wie man damit umgeht Failed to issue method call: Unit name ... is not valid.?
Julien Genestoux
1
@ JulienGenestoux Der Name der Einheit entspricht Ihrem Service. Es klingt so, als gäbe es dort eine Diskrepanz. Nachdem Sie die Datei kopiert haben, müssen /etc/systemd/systemSie sie möglicherweise ausführen systemctl daemon-reload(systemd teilt Ihnen normalerweise mit, ob dies erforderlich ist). TBH Dies wird am besten als separate Frage gestellt.
Mikemaccana
3
Anstatt Ihre Servicedatei in zu kopieren /etc/systemd/system, können Sie einfach verwenden systemctl enable /full/path/to/myapp.service, wodurch ein Symlink /etc/systemd/systemfür Sie erstellt wird.
Arne
1
Wie ist es mit pm2 zu vergleichen? Kann es pm2 ersetzen oder bietet pm2 mehr notwendige Funktionen?
Sergei Basharov
1
@VinodSrivastav nodewird von /var/www/myapp/app.jsselbst aufgerufen . Wenn Sie unter Unix eine Datei ausführbar machen und die erste Zeile mit #!/some/fileder Datei beginnt, wird sie mit dieser Binärdatei interpretiert. Google 'Interpreter Unix', um mehr zu erfahren.
Mikemaccana
101

Verwenden Sie für immer . Es führt Node.js-Programme in separaten Prozessen aus und startet sie neu, wenn eines stirbt.

Verwendung:

  • forever start example.js einen Prozess starten.
  • forever list um eine Liste aller Prozesse zu sehen, die für immer gestartet wurden
  • forever stop example.jsum den Prozess forever stop 0zu stoppen oder um den Prozess mit dem Index 0 zu stoppen (wie durch gezeigt forever list).
David Tang
quelle
Das ist nah. Es fängt ganz gut an, lässt mich aber nichts aufhalten. Ich konnte mich abmelden und wieder anmelden und dann den Knotenprozess beenden. Für immer nicht neu gestartet. Ich denke also darüber nach, wie es funktioniert und nicht mit DH kompatibel ist.
Respektieren Sie den Code
@ Kevin, Sie können den Knotenprozess nicht beenden, da Forever selbst auf dem Knoten ausgeführt wird! Ich habe meiner Antwort einige Verwendungsanweisungen hinzugefügt, darunter das Stoppen eines Prozesses. Ich habe dies auf meinem VPS verwendet und es hat wie ein Zauber funktioniert.
David Tang
forever stop 0hatte einen Fehler und die Dinge fielen einfach irgendwie auseinander. Ich habe versucht, dies ohne root auf seinem eigenen Benutzer zu tun, damit ich leicht aufräumen kann, sobald ich die richtige Lösung gefunden habe. Das kann mein Problem sein. Ich werde mich noch etwas damit befassen.
Respektieren Sie den Code
Ich hatte etwas falsch mit npm, das Probleme verursachte. Wenn npm und node für immer korrekt installiert sind, funktioniert das großartig. Am Ende habe ich die Befehle für immer gestartet zu einem Cronjob-Set hinzugefügt, das beim Neustart ausgeführt werden soll. Ich arbeite jetzt an einer kleinen Knoten-App, mit der ich für immer Prozesse starten und stoppen kann.
Respektieren Sie den Code
Es gibt eine Alternative zu Forever, die die native Cluster-API des Knotens verwendet: github.com/superjoe30/naught
andrewrk
41

Ich habe hier über meine Bereitstellungsmethode geschrieben: Bereitstellen von node.js-Apps

Zusamenfassend:

  • Verwenden Sie den Git-Post-Receive-Hook
  • Jake für das Build-Tool
  • Starten Sie als Service Wrapper für den Knoten
  • Überwachen Sie, um Anwendungen zu überwachen und neu zu starten, wenn sie ausfallen
  • nginx zum Weiterleiten von Anforderungen an verschiedene Anwendungen auf demselben Server
Ben
quelle
2
Kann ich Nginx sicher loswerden, wenn ich immer eine einzige Node-Site auf meinem Server habe?
Dor
3
Die Verbindung scheint unterbrochen zu sein
verybadalloc
@ Oder ich weiß, dass dies eine späte Antwort ist, aber ich würde nicht. Abgesehen von Dingen wie SSL-Terminierung und Caching bietet Ihnen ein Nginx-Reverse-Proxy vor dem Host eine größere infrastrukturelle Flexibilität als das Ausführen eines Knotens direkt auf Port 80. Dies bedeutet auch, dass Sie den Knoten nicht als Root ausführen müssen, was meiner Meinung nach der Fall ist Ein ziemlich heftiges Argument für das Nginx-Setup.
Chris Browne
16

pm2 macht die Tricks.

Zu den Funktionen gehören: Überwachung, erneutes Laden von Hotcode, integrierter Load Balancer, automatisches Startskript und Wiederbelebungs- / Speicherauszugsprozesse.

Nickleefly
quelle
Ist es mit Diensten wie Heroku kompatibel?
FRD
@ FRD Ich glaube nicht, dass es mit Heroku funktioniert, überprüfen Sie diesen Artikel
Nickleefly
9

Sie können verwendet werden monit, forever, upstartoder den systemdServer zu starten.

Sie können Lack oder HAProxy anstelle von Nginx verwenden (Nginx funktioniert bekanntermaßen nicht mit Websockets).

Als schnelle und schmutzige Lösung können Sie mit nohup node your_app.js &Ihrer App mit dem Server, sondern verhindern , beendet forever, monitund andere vorgeschlagenen Lösungen sind besser.

nponeccop
quelle
2
Ein Benutzer "Sergey Yarotskiy" hat versucht, Ihren Beitrag zu bearbeiten. Er sagte, dass Nginx jetzt WebSockets unterstützt (seit Version 1.3). Ich habe die Bearbeitung abgelehnt, da ich denke, dass sie stattdessen als Kommentar veröffentlicht werden sollte. (Andernfalls hätten Sie zwei widersprüchliche Sätze im selben Beitrag, was verwirrend ist.)
Backlin
7

Ich habe ein Upstart-Skript erstellt, das derzeit für meine Apps verwendet wird:

description "YOUR APP NAME"
author "Capy - http://ecapy.com"

env LOG_FILE=/var/log/node/miapp.log
env APP_DIR=/var/node/miapp
env APP=app.js
env PID_NAME=miapp.pid
env USER=www-data
env GROUP=www-data
env POST_START_MESSAGE_TO_LOG="miapp HAS BEEN STARTED."
env NODE_BIN=/usr/local/bin/node
env PID_PATH=/var/opt/node/run
env SERVER_ENV="production"

######################################################

start on runlevel [2345]
stop on runlevel [016]

respawn
respawn limit 99 5

pre-start script
    mkdir -p $PID_PATH
    mkdir -p /var/log/node
end script

script
    export NODE_ENV=$SERVER_ENV
    exec start-stop-daemon --start --chuid $USER:$GROUP --make-pidfile --pidfile $PID_PATH/$PID_NAME --chdir $APP_DIR --exec $NODE_BIN -- $APP >> $LOG_FILE 2>&1
end script

post-start script
    echo $POST_START_MESSAGE_TO_LOG >> $LOG_FILE
end script

Passen Sie alle vor ######### an, erstellen Sie eine Datei in /etc/init/your-service.conf und fügen Sie sie dort ein.

Dann kannst du:

start your-service
stop your-service
restart your-service
status your-service
Capy
quelle
Danke, genau das, was ich brauchte.
Nilson Morais
6

Ich habe eine ziemlich umfassende Anleitung zum Bereitstellen von Node.js mit Beispieldateien geschrieben:

Tutorial: Bereitstellen von Node.js-Anwendungen anhand von Beispielen

Es behandelt Dinge wie http-Proxy, SSL und Socket.IO .

Rich Jones
quelle
Das sieht gut aus. Ich verwende Heroku für die Entwicklung und den ersten Start, muss aber eventuell über Heroku hinaus skalieren und direkt auf EC2 bereitstellen. Ich werde damit spielen, wenn ich Zeit habe.
RespektTheCode
5

Hier ist ein längerer Artikel zur Lösung dieses Problems mit systemd: http://savanne.be/articles/deploying-node-js-with-systemd/

Einige Dinge zu beachten:

  • Wer startet Ihre Prozessüberwachung? Forever ist ein großartiges Tool, aber es benötigt ein Überwachungstool, um sich selbst am Laufen zu halten. Das ist ein bisschen albern, warum nicht einfach Ihr Init-System verwenden?
  • Können Sie Ihre Prozesse angemessen überwachen?
  • Führen Sie mehrere Backends aus? Wenn ja, haben Sie Vorkehrungen getroffen, um zu verhindern, dass einer von ihnen die anderen in Bezug auf die Ressourcennutzung stürzt?
  • Wird der Service ständig benötigt? Wenn nicht, ziehen Sie die Socket-Aktivierung in Betracht (siehe Artikel).

All diese Dinge sind mit systemd einfach zu erledigen.

Ruben Vermeersch
quelle
5

Wenn Sie Root-Zugriff haben, sollten Sie einen Daemon so einrichten, dass er sicher und solide im Hintergrund ausgeführt wird. Wie das für Debian und Ubuntu geht, lesen Sie im Blog-Beitrag Run Node.js as a Service unter Ubuntu .

Seldaek
quelle
Ich dachte nicht, dass ich root habe, aber es scheint, dass ich es nur im Webpanel aktivieren muss. Ich werde es versuchen.
Respektieren Sie den Code
3

Für immer wird der Trick tun.

@ Kevin: Sie sollten in der Lage sein, Prozesse gut zu beenden. Ich würde die Dokumentation ein wenig überprüfen. Wenn Sie den Fehler reproduzieren können, wäre es großartig, ihn als Problem auf GitHub zu veröffentlichen.

Marak
quelle
Wer ist Kevin? Die Operation?
Peter Mortensen
2

Wie Box9 sagte, ist Forever eine gute Wahl für Produktionscode. Es ist aber auch möglich, einen Prozess am Laufen zu halten, selbst wenn die SSH Verbindung vom Client geschlossen wird.

Dies ist zwar nicht unbedingt eine gute Idee für die Produktion, aber sehr praktisch, wenn Sie sich mitten in langen Debug-Sitzungen befinden oder die Konsolenausgabe langwieriger Prozesse verfolgen oder wenn es nützlich ist, Ihre SSH-Verbindung zu trennen, aber das Terminal auf dem Server am Leben zu halten um später wieder eine Verbindung herzustellen (wie das Starten der Node.js-Anwendung zu Hause und das erneute Verbinden mit der Konsole später bei der Arbeit, um zu überprüfen, wie die Dinge laufen).

Angenommen, Ihr Server ist eine * nix-Box, können Sie den Befehl screen aus der Shell verwenden, um den Prozess auch dann fortzusetzen, wenn der Client-SSH geschlossen ist. Sie können den Bildschirm aus dem Internet herunterladen / installieren, falls er noch nicht installiert ist (suchen Sie nach einem Paket für Ihre Distribution unter Linux oder verwenden Sie MacPorts unter OS X).

Es funktioniert wie folgt:

  1. Wenn Sie die SSH-Verbindung zum ersten Mal öffnen, geben Sie 'screen' ein. Dadurch wird Ihre Bildschirmsitzung gestartet.
  2. Beginnen Sie wie gewohnt zu arbeiten (dh starten Sie Ihre Node.js-Anwendung)
  3. Wenn Sie fertig sind, schließen Sie Ihr Terminal. Ihre Serverprozesse werden weiterhin ausgeführt.
  4. Um die Verbindung zu Ihrer Konsole wiederherzustellen, ssh zurück zum Server, melden Sie sich an und geben Sie 'screen -r' ein, um die Verbindung wiederherzustellen. Ihr alter Konsolenkontext wird wieder angezeigt, damit Sie ihn wieder verwenden können.
  5. Um den Bildschirm zu verlassen, während Sie mit dem Server verbunden sind, geben Sie an der Konsolenaufforderung 'exit' ein. Dadurch werden Sie auf die reguläre Shell verschoben.

Bei Bedarf können mehrere Bildschirmsitzungen gleichzeitig ausgeführt werden, und Sie können von jedem Client aus eine Verbindung zu einer beliebigen Sitzung herstellen. Lesen Sie die Dokumentation online für alle Optionen.

cjcela
quelle
Gute Informationen zu haben. Ich bin damit einverstanden, dass es für die Produktion nicht funktioniert, aber beim Debuggen auf einem Remote-Server sehr nützlich sein kann.
Respektieren Sie den Code
Warum nicht einfach den Nohup-Knoten myapp.js & 2> /var/log/myapp.log 1> / dev / null
markus_p
Ich fand diese av nützlich youtube.com/watch?v=P4mT5Tbx_KE erklären nohupundforever
Vinod Srivastav
1

Forever ist eine gute Option, um Apps am Laufen zu halten (und es ist npm als ein Modul installierbar, das nett ist).

Aber für eine ernsthaftere 'Bereitstellung' - Dinge wie die Fernverwaltung der Bereitstellung, des Neustarts, des Ausführens von Befehlen usw. - würde ich capistrano mit der Knotenerweiterung verwenden.

https://github.com/loopj/capistrano-node-deploy

Märtyrer
quelle
1

https://paastor.com ist ein relativ neuer Dienst, der die Bereitstellung für Sie auf einem VPS oder einem anderen Server übernimmt. Es gibt eine CLI zum Übertragen von Code. Paastor hat eine kostenlose Stufe, zumindest zum Zeitpunkt der Veröffentlichung.

Ruffrey
quelle
1

Versuchen Sie es mit Node-Deploy-Server . Es ist ein komplexes Toolset zum Bereitstellen einer Anwendung auf Ihren privaten Servern. Es ist in Node.js geschrieben und verwendet npm für die Installation.

AndyGrom
quelle