Comment exécuter une application Node.js comme son propre processus?

195

Quelle est la meilleure façon de déployer Node.js?

J'ai un VPS Dreamhost (c'est ce qu'ils appellent une machine virtuelle ), et j'ai pu installer Node.js et configurer un proxy. Cela fonctionne très bien tant que je garde ouverte la connexion SSH avec laquelle j'ai démarré le nœud.

respectTheCode
la source
6
Hmm, il me semble étrange que vous appeliez l'utilisation de Forever comme "déploiement de node.js". N'est-ce pas simplement un outil de suivi / supervision des processus? Habituellement, le déploiement Web signifie (du moins ce que je rencontre dans les articles) plusieurs activités interdépendantes qui rendent une application Web disponible (cet outil de processus en fait partie). Quoi qu'il en soit, c'est toujours un excellent article ici dans StackOverflow, comme je l'ai appris des réponses de tout le monde.
mikong
Il s'agit simplement du déploiement le plus simple de node.js sur Dreamhost. L'objectif était simplement de faire fonctionner le nœud de manière fiable comme point de départ à partir duquel construire.
respectTheCode
Comment avez-vous géré le transfert du domaine vers le nœud de port exécuté?
grm
2
@grm J'utilise HTTP-Proxy github.com/nodejitsu/node-http-proxy
respectTheCode
Nous utilisons maintenant Elastic Beanstalk et cela fonctionne très bien.
respectTheCode

Réponses:

107

Réponse de 2016 : presque toutes les distributions Linux sont livrées avec systemd, ce qui signifie que pour toujours, monit, PM2, etc. ne sont plus nécessaires - votre système d'exploitation gère déjà ces tâches .

Créez un myapp.servicefichier (en remplaçant 'myapp' par le nom de votre application, évidemment):

[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

Notez que si vous êtes nouveau sur Unix: /var/www/myapp/app.js devrait avoir #!/usr/bin/env nodesur la toute première ligne.

Copiez votre fichier de service dans le /etc/systemd/systemdossier.

Parlez à systemd du nouveau service avec systemctl daemon-reload.

Commencez avec systemctl start myapp.

Activez-le pour démarrer au démarrage avec systemctl enable myapp.

Voir les journaux avec journalctl -u myapp

Ceci est tiré de Comment nous déployons les applications de nœuds sur Linux, édition 2018 , qui comprend également des commandes pour générer un AWS / DigitalOcean / Azure CloudConfig pour construire des serveurs Linux / nœuds (y compris le .servicefichier).

mikemaccana
la source
1
Une idée sur la façon de traiter Failed to issue method call: Unit name ... is not valid.?
Julien Genestoux
1
@JulienGenestoux le nom 'unité' est le même que votre service. Il semble qu'il y ait là une divergence. Après avoir copié le fichier, /etc/systemd/systemvous devrez peut-être exécuter systemctl daemon-reload(systemd vous indiquera normalement si cela est nécessaire). TBH, il vaut mieux poser cette question séparément.
mikemaccana
3
Au lieu de copier votre fichier de service dans /etc/systemd/system, vous pouvez simplement l'utiliser systemctl enable /full/path/to/myapp.service, ce qui crée un lien symbolique /etc/systemd/systempour vous.
Arne
1
Comment se compare-t-il avec pm2? Peut-il remplacer pm2 ou pm2 offre-t-il des fonctionnalités plus nécessaires?
Sergei Basharov
1
@VinodSrivastav nodeest appelé par /var/www/myapp/app.jslui-même. Sous Unix, si vous rendez un fichier exécutable, la première ligne commençant par #!/some/filele fichier sera interprétée avec ce binaire. L'interprète Unix de Google pour en savoir plus.
mikemaccana
101

Utilisez Forever . Il exécute les programmes Node.js dans des processus séparés et les redémarre en cas de mort.

Usage:

  • forever start example.js pour démarrer un processus.
  • forever list pour voir la liste de tous les processus démarrés pour toujours
  • forever stop example.jspour arrêter le processus ou forever stop 0pour arrêter le processus avec l'index 0 (comme indiqué par forever list).
David Tang
la source
C'est proche. Cela commence très bien mais ne me laisse rien arrêter. J'ai pu me déconnecter et me reconnecter, puis tuer le processus de nœud. Forever ne l'a pas redémarré. Je pense donc que la façon dont cela fonctionne n'est pas compatible avec DH.
respectTheCode
@Kevin, vous ne pouvez pas tuer le processus de nœud car Forever lui-même s'exécute sur le nœud! J'ai ajouté quelques instructions d'utilisation à ma réponse, notamment comment arrêter un processus. J'ai utilisé cela sur mon VPS et cela a fonctionné comme un charme.
David Tang
forever stop 0a eu une erreur et les choses se sont effondrées. J'ai essayé de le faire sans root sur son propre utilisateur afin de pouvoir nettoyer facilement une fois que j'ai trouvé la bonne solution. C'est peut-être mon problème. J'y reviendrai un peu plus.
respectTheCode
J'ai eu un problème avec npm qui posait des problèmes. Avec npm et le noeud installé correctement, cela fonctionne toujours à merveille. Ce que j'ai fini par faire était d'ajouter les commandes de démarrage pour toujours à un ensemble de tâches cron à exécuter au redémarrage. Je travaille maintenant sur une petite application de nœud qui me permettra de démarrer et d'arrêter indéfiniment les procs.
respectTheCode
Il existe une alternative à Forever qui utilise l'API de cluster natif du nœud: github.com/superjoe30/naught
andrewrk
41

J'ai écrit sur ma méthode de déploiement ici: Déploiement des applications node.js

En bref:

  • Utiliser le crochet post-réception git
  • Jake pour l'outil de construction
  • Upstart en tant que wrapper de service pour le nœud
  • Monit pour surveiller et redémarrer les applications si elles descendent
  • nginx pour acheminer les demandes vers différentes applications sur le même serveur
Ben
la source
2
Si j'ai toujours un seul site Node sur mon serveur, puis-je abandonner Nginx en toute sécurité?
Dor
3
Le lien semble rompu
verybadalloc
@ Je sais que c'est une réponse tardive, mais je ne le ferais pas. Mis à part des choses comme la terminaison SSL et la mise en cache, un proxy inverse nginx devant l'hôte vous offre une plus grande flexibilité d'infrastructure que l'exécution de node directement sur le port 80. Cela signifie également que vous n'avez pas à exécuter node en tant que root, ce qui, je pense, est un argument assez lourd en faveur de la configuration de nginx.
Chris Browne
16

pm2 fait les tours.

Les fonctionnalités sont les suivantes: surveillance, rechargement de code à chaud, équilibreur de charge intégré, script de démarrage automatique et processus de résurrection / vidage.

nickleefly
la source
Est-il compatible avec des services comme Heroku?
FRD
@FRD Je ne pense pas que cela fonctionne avec Heroku, vérifiez cet article
nickleefly
9

Vous pouvez utiliser monit, forever, upstartousystemd pour démarrer votre serveur.

Vous pouvez utiliser Varnish ou HAProxy au lieu de Nginx (Nginx est connu pour ne pas fonctionner avec les websockets).

En tant que solution rapide et sale , vous pouvez utiliser nohup node your_app.js &pour éviter que votre application se terminant par votre serveur, mais forever, monitet d' autres solutions proposées sont mieux.

nponeccop
la source
2
Un utilisateur "Sergey Yarotskiy" a tenté de modifier votre message en disant que Nginx prend désormais en charge les WebSockets (depuis la version 1.3). J'ai rejeté la modification car je pense qu'elle devrait plutôt être publiée en tant que commentaire. (Sinon, vous auriez deux phrases contradictoires dans le même message, ce qui prête à confusion.)
Backlin
7

J'ai créé un script Upstart actuellement utilisé pour mes applications:

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

Personnalisez tout avant #########, créez un fichier dans /etc/init/your-service.conf et collez-le là.

Ensuite vous pouvez:

start your-service
stop your-service
restart your-service
status your-service
Capy
la source
Merci, juste ce dont j'avais besoin.
Nilson Morais
6

J'ai écrit un guide assez complet pour déployer Node.js, avec des exemples de fichiers:

Tutoriel: Comment déployer des applications Node.js, avec des exemples

Il couvre des choses comme http-proxy, SSL et Socket.IO .

Rich Jones
la source
Ça a l'air génial. J'utilise heroku pour le développement et le lancement initial, mais je devrai éventuellement évoluer après heroku et déployer directement sur EC2. Je jouerai avec ça quand j'aurai le temps.
respectTheCode
5

Voici un article plus long sur la résolution de ce problème avec systemd: http://savanne.be/articles/deploying-node-js-with-systemd/

Quelques points à garder à l'esprit:

  • Qui commencera votre suivi de processus? Forever est un excellent outil, mais il a besoin d'un outil de surveillance pour continuer à fonctionner. C'est un peu idiot, pourquoi ne pas simplement utiliser votre système init?
  • Pouvez-vous surveiller adéquatement vos processus?
  • Exécutez-vous plusieurs backends? Si oui, avez-vous des dispositions en place pour empêcher l'une d'entre elles de faire baisser les autres en termes d'utilisation des ressources?
  • Le service sera-t-il toujours nécessaire? Sinon, envisagez l'activation du socket (voir l'article).

Toutes ces choses se font facilement avec systemd.

Ruben Vermeersch
la source
5

Si vous avez un accès root, vous feriez mieux de configurer un démon pour qu'il fonctionne sain et sauf en arrière-plan. Vous pouvez lire comment faire exactement cela pour Debian et Ubuntu dans le billet de blog Run Node.js as a Service on Ubuntu .

Seldaek
la source
Je ne pensais pas que j'avais root, mais il semble que je dois juste l'activer dans le panneau Web. J'essaierai.
respectTheCode
3

Forever fera l'affaire.

@Kevin: Vous devriez pouvoir tuer correctement les processus. Je revérifierais un peu la documentation. Si vous pouvez reproduire l'erreur, ce serait bien de la publier comme un problème sur GitHub.

Marak
la source
Qui est Kevin? L'OP?
Peter Mortensen du
2

Comme l'a dit Box9, Forever est un bon choix pour le code de production. Mais il est également possible de maintenir un processus en cours même si la connexion SSH est fermée du client.

Bien que ce ne soit pas nécessairement une bonne idée pour la production, cela est très pratique lorsque vous êtes au milieu de longues sessions de débogage, ou pour suivre la sortie de la console de processus longs, ou chaque fois que cela est utile pour déconnecter votre connexion SSH, mais garder le terminal en vie sur le serveur pour vous reconnecter plus tard (comme démarrer l'application Node.js à la maison et vous reconnecter à la console plus tard au travail pour vérifier comment les choses se passent).

En supposant que votre serveur est une boîte * nix, vous pouvez utiliser la commande screen du shell pour maintenir le processus en cours même si le client SSH est fermé. Vous pouvez télécharger / installer l'écran à partir du Web s'il n'est pas déjà installé (recherchez un package pour votre distribution si Linux, ou utilisez MacPorts si OS X).

Cela fonctionne comme suit:

  1. Lorsque vous ouvrez la connexion SSH pour la première fois, tapez «écran» - cela démarrera votre session d'écran.
  2. Commencez à travailler normalement (c'est-à-dire démarrez votre application Node.js)
  3. Lorsque vous avez terminé, fermez votre terminal. Le ou les processus de votre serveur continueront de fonctionner.
  4. Pour vous reconnecter à votre console, revenez au serveur, connectez-vous et entrez «screen -r» pour vous reconnecter. Votre ancien contexte de console réapparaîtra prêt pour que vous puissiez continuer à l'utiliser.
  5. Pour quitter l'écran, une fois connecté au serveur, tapez «exit» à l'invite de la console - qui vous déposera sur le shell normal.

Vous pouvez avoir plusieurs sessions d'écran qui s'exécutent simultanément comme ceci si vous en avez besoin, et vous pouvez vous connecter à n'importe laquelle depuis n'importe quel client. Lisez la documentation en ligne pour toutes les options.

cjcela
la source
De bonnes informations à avoir. Je suis d'accord que cela ne fonctionnerait pas pour la production mais pourrait être très utile lors du débogage sur un serveur distant.
respectTheCode
pourquoi ne pas simplement utiliser nohup node myapp.js & 2> /var/log/myapp.log 1> / dev / null
markus_p
J'ai trouvé cet av utile youtube.com/watch?v=P4mT5Tbx_KE expliquant nohupetforever
Vinod Srivastav
1

Forever est une bonne option pour garder les applications en cours d'exécution (et c'est npm installable en tant que module, ce qui est bien).

Mais pour un «déploiement» plus sérieux - des choses comme la gestion à distance du déploiement, du redémarrage, de l'exécution de commandes, etc. - j'utiliserais capistrano avec l'extension de nœud.

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

martyman
la source
1

https://paastor.com est un service relativement nouveau qui fait le déploiement pour vous, sur un VPS ou un autre serveur. Il y a une CLI pour pousser le code. Paastor a un niveau gratuit, du moins il le faisait au moment de la publication.

ruffrey
la source
1

Essayez node-deploy-server . Il s'agit d'un ensemble d'outils complexes pour déployer une application sur vos serveurs privés. Il est écrit dans Node.js et utilise npm pour l'installation.

AndyGrom
la source