Come posso eseguire un'applicazione Node.js come processo proprio?


195

Qual è il modo migliore per distribuire Node.js?

Ho un VPS Dreamhost (è quello che chiamano a virtuale ) e sono stato in grado di installare Node.js e impostare un proxy. Funziona alla grande finché mantengo aperta la connessione SSH con cui ho avviato il nodo.


6
Hmm, mi sembra strano che tu chiami usando Forever come "distribuzione di node.js". Non è solo uno strumento di monitoraggio / supervisione del processo? Di solito la distribuzione sul web significa (almeno quello che incontro negli articoli) diverse attività correlate che rendono disponibile un'app Web (questo strumento di processo ne fa parte). Comunque, questo è ancora un ottimo post qui in StackOverflow, come ho imparato dalle risposte di tutti.
mikong,

Questa è solo la distribuzione più semplice di node.js su Dreamhost. L'obiettivo era semplicemente far funzionare il nodo in modo affidabile come punto di partenza da cui partire.
rispettare Il codice

Come hai gestito l'inoltro del dominio al nodo della porta?
grm,


Stiamo usando Elastic Beanstalk ora e funziona abbastanza bene.
rispettare Il codice

Risposte:


107

Risposta 2016 : quasi ogni distribuzione Linux viene fornita con systemd, il che significa che per sempre, monit, PM2, ecc. Non sono più necessari - il tuo sistema operativo gestisce già queste attività .

Crea un myapp.servicefile (sostituendo "myapp" con il nome della tua app, ovviamente):

[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

Nota se sei nuovo su Unix: /var/www/myapp/app.js dovrebbe avere#!/usr/bin/env node la prima riga.

Copia il tuo file di servizio in /etc/systemd/system cartella.

Informa systemd del nuovo servizio con systemctl daemon-reload .

Inizia con systemctl start myapp .

Attivalo per l'avvio con systemctl enable myapp .

Vedi i log con journalctl -u myapp

Questo è tratto da Come implementiamo le app nodo su Linux, edizione 2018 , che include anche i comandi per generare un AWS / DigitalOcean / Azure CloudConfig per costruire server Linux / nodo (incluso il .servicefile).


1
Qualche idea su come affrontare Failed to issue method call: Unit name ... is not valid.?
Julien Genestoux

1
@JulienGenestoux il nome 'unit' è lo stesso del tuo servizio. Sembra che ci sia una discrepanza lì. Dopo aver copiato il file /etc/systemd/system, potrebbe essere necessario eseguirlo systemctl daemon-reload(normalmente systemd ti dirà se è necessario). TBH è meglio fare una domanda separata.
mikemaccana,

3
Invece di copiare il tuo file di servizio /etc/systemd/system, puoi semplicemente usare systemctl enable /full/path/to/myapp.service, il che crea un collegamento simbolico /etc/systemd/systemper te.
Arne,

1
Come si confronta con pm2? Può sostituire pm2 o pm2 offre più funzioni necessarie?
Sergei Basharov,

1
@VinodSrivastav nodeè chiamato da /var/www/myapp/app.jssolo. In Unix, se si #!/some/fileesegue un file eseguibile e la prima riga inizia con il file verrà interpretato con quel file binario. Google "interprete Unix" per saperne di più.
mikemaccana,

101

Usa per sempre . Esegue i programmi Node.js in processi separati e li riavvia se muore.

Uso:

  • forever start example.js per iniziare un processo.
  • forever list per vedere l'elenco di tutti i processi avviati da sempre
  • forever stop example.jsper interrompere il processo o forever stop 0per interrompere il processo con l'indice 0 (come mostrato da forever list).

Questo è vicino Inizia bene ma non mi lascerà fermare nulla. Sono stato in grado di disconnettermi, rientrare e quindi terminare il processo del nodo. Per sempre non lo ha riavviato. Quindi sto pensando a come funziona non è compatibile con DH.
rispettare il codice

@Kevin, non puoi uccidere il processo del nodo perché Forever stesso gira sul nodo! Ho aggiunto alcune istruzioni per l'uso alla mia risposta, incluso come fermare un processo. Ho usato questo sul mio VPS e ha funzionato come un fascino.
David Tang,

forever stop 0ha avuto un errore e le cose sono andate in pezzi. Ho provato a farlo senza root sul suo stesso utente in modo da poter ripulire facilmente una volta trovata la soluzione giusta. Questo potrebbe essere il mio problema. Ci penserò ancora.
rispettare il codice

Ho avuto qualcosa di sbagliato in npm che stava causando problemi. Con npm e il nodo installati correttamente per sempre funziona alla grande. Quello che ho finito per fare è stato aggiungere i comandi di avvio per sempre a un set cronjob da eseguire al riavvio. Ora sto lavorando a un'app per piccoli nodi che mi permetterà di avviare e arrestare per sempre i proc.
rispettare il codice

Esiste un'alternativa a Forever che utilizza l'API cluster nativa del nodo: github.com/superjoe30/naught
andrewrk,

41

Ho scritto del mio metodo di distribuzione qui: Distribuzione di app node.js

In breve:

  • Usa il gancio post-ricezione git
  • Jake per lo strumento di compilazione
  • Avvia come wrapper di servizio per il nodo
  • Monit per monitorare e riavviare le applicazioni che vanno giù
  • nginx per instradare le richieste a diverse applicazioni sullo stesso server

2
Se avrò sempre un singolo sito Node sul mio server, posso tranquillamente abbandonare Nginx?
Dor

3
Il collegamento sembra interrotto
verybadalloc

@ So che questa è una risposta tardiva, ma non lo farei. Oltre a cose come la terminazione SSL e la memorizzazione nella cache, un proxy inverso nginx davanti all'host ti offre una maggiore flessibilità infrastrutturale rispetto all'esecuzione del nodo direttamente sulla porta 80. Significa anche che non devi eseguire il nodo come root, che penso sia un argomento piuttosto pesante a favore della configurazione di nginx.
Chris Browne,

16

PM2 fa i trucchi.

Le caratteristiche sono: monitoraggio, ricarica di hot code, bilanciamento del carico integrato, script di avvio automatico e processi di resurrect / dump.


È compatibile con servizi come Heroku?
FRD

@FRD Non credo che funzioni con Heroku, controlla questo articolo
Nickleefly,

9

È possibile utilizzare monit, forever, upstarto systemdper avviare il server.

Puoi usare Varnish o HAProxy invece di Nginx (è noto che Nginx non funziona con i websocket).

Come una soluzione rapida e sporca è possibile utilizzare nohup node your_app.js &per evitare che la vostra applicazione che termina con il server, ma forever, monite le altre soluzioni proposte sono meglio.


2
Un utente "Sergey Yarotskiy" ha provato a modificare il tuo post dicendo che Nginx ora supporta WebSocket (dalla versione 1.3). Ho rifiutato la modifica in quanto penso che dovrebbe essere pubblicato come commento. (Altrimenti avresti due frasi contraddittorie nello stesso post, il che è confuso.)
Backlin

7

Ho creato uno script Upstart attualmente utilizzato per le mie app:

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

Personalizza tutto prima di #########, crea un file in /etc/init/your-service.conf e incollalo lì.

Allora puoi:

start your-service
stop your-service
restart your-service
status your-service

Grazie, proprio quello di cui avevo bisogno.
Nilson Morais,


5

Ecco un articolo più lungo sulla risoluzione di questo problema con systemd: http://savanne.be/articles/deploying-node-js-with-systemd/

Alcune cose da tenere a mente:

  • Chi inizierà il monitoraggio del processo? Per sempre è un ottimo strumento, ma ha bisogno di uno strumento di monitoraggio per mantenersi in funzione. È un po 'sciocco, perché non usare semplicemente il tuo sistema init?
  • Puoi monitorare adeguatamente i tuoi processi?
  • Stai eseguendo più backend? In tal caso, sono in atto disposizioni per impedire a qualcuno di loro di abbattere gli altri in termini di utilizzo delle risorse?
  • Il servizio sarà sempre necessario? In caso contrario, prendere in considerazione l'attivazione del socket (consultare l'articolo).

Tutte queste cose possono essere facilmente eseguite con systemd.



3

Per sempre farà il trucco.

@Kevin: dovresti essere in grado di uccidere bene i processi. Vorrei ricontrollare un po 'la documentazione. Se riesci a riprodurre l'errore, sarebbe bello pubblicarlo come problema su GitHub.


Chi è Kevin? L'OP?
Peter Mortensen,


2

Come detto Box9, Forever è una buona scelta per il codice di produzione. Ma è anche possibile continuare un processo anche se la connessione SSH è chiusa dal client.

Sebbene non sia necessariamente una buona idea per la produzione, questo è molto utile quando si è nel mezzo di lunghe sessioni di debug o per seguire l'output della console di lunghi processi o quando è utile per disconnettere la connessione SSH, ma mantenere il terminale attivo nel server per riconnettersi in un secondo momento (come avviare l'applicazione Node.js a casa e riconnettersi alla console più tardi al lavoro per verificare come stanno andando le cose).

Supponendo che il server sia una casella * nix, è possibile utilizzare il comando screen dalla shell per mantenere il processo in esecuzione anche se il client SSH è chiuso. Puoi scaricare / installare lo schermo dal Web se non è già installato (cerca un pacchetto per la tua distribuzione se Linux o usa MacPorts se OS X).

Funziona come segue:

  1. Quando si apre per la prima volta la connessione SSH, digitare 'screen' - questo avvierà la sessione dello schermo.
  2. Inizia a lavorare normalmente (ovvero avvia l'applicazione Node.js)
  3. Al termine, chiudere il terminale. I processi del server continueranno a essere eseguiti.
  4. Per riconnetterti alla tua console, torna al server, accedi e inserisci 'screen -r' per riconnetterti. Il vecchio contesto della console tornerà pronto per riprendere a utilizzarlo.
  5. Per uscire dalla schermata, mentre sei connesso al server, digita "esci" sul prompt della console, che ti farà cadere sulla shell normale.

Puoi avere più sessioni dello schermo in esecuzione contemporaneamente in questo modo, se necessario, e puoi collegarti a qualsiasi di esso da qualsiasi client. Leggi la documentazione online per tutte le opzioni.


Buone informazioni da avere. Sono d'accordo che non funzionerebbe per la produzione ma potrebbe essere molto utile durante il debug su un server remoto.
rispettare il codice

perché non usare semplicemente il nodo nohup myapp.js e 2> /var/log/myapp.log 1> / dev / null
markus_p

Ho trovato utile questo youtube.com/watch?v=P4mT5Tbx_KE che spiega nohupeforever
Vinod Srivastav il

1

Per sempre è una buona opzione per mantenere le app in esecuzione (ed è npm installabile come modulo che è bello).

Ma per una "distribuzione" più seria - cose come la gestione remota della distribuzione, del riavvio, dell'esecuzione di comandi ecc. - Userei capistrano con l'estensione del nodo.

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


1

https://paastor.com è un servizio relativamente nuovo che esegue la distribuzione per te, su un VPS o su un altro server. C'è una CLI per inviare il codice. Paastor ha un livello gratuito, almeno al momento della pubblicazione.



1

Prova il nodo-deploy-server . Si tratta di un set di strumenti complesso per la distribuzione di un'applicazione sui server privati. È scritto in Node.js e utilizza npm per l'installazione.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.