
NodeJS : Service et redémarrage automatique
Depuis que je travaillais sous NodeJS au travail, je me posais une question sur sa mise en place côté serveur. Comment l’exécuter en tant que service et comment faire pour qu’il se relance automatiquement en cas de gros crash. Effectivement, si votre serveur NodeJS crash à cause d’une erreur de développement, il se coupe. De plus, nodeJS se lance au premier plan, avec l’output sur stdin et stderr. Nous allons donc voir ces deux points pour avoir une solution solide aà mettre en place sur vos serveurs.
Prérequis
Pour commencer, je tiens à préciser que tous ces tests ont été effectués sur un Mac OSX, un serveur Ubuntu 12.10 64bits et un Ubuntu Desktop 12.10 64 bits. La version de NodeJS utilisée est la dernière en date au moment de l’écriture de cet article. À savoir la version 0.10.7
.
Superviser les crash et mises à jour de son projet Node.
Comme dit plus haut, si jamais un crash non intercepté dans votre code a lieux, nodeJS affiche la stack trace dans son output et se quitte. Si vous exécutez votre script sur votre serveur et que l’erreur survient à 3h du matin, vous aurez l’agréable surprise de recevoir 5000 mails, autant de messages en absence pour vous dire qu’il y a un problème.
Je me suis donc tourneé vers différentes solutions existantes :
- Forever : Si vous souhqitez seulement exécuter votre script en tant que daemon, alors forever est pour vous. Il vous permet de lancer/redémarrer/arrêter indépendamment chacun de vos scripts nodeJS. Seul souci pour ma problématique, il ne s’utilise pas comme un service unix.
- nodemon : Nodemon relance votre script si un fichier a été modifié mais en cas d’erreur, il attends qu’un fichier soit modifié pour se relancer.
- always : Ce script semble être abandonné car la fonctionnalité du redémarrage en cas d’erreur ne marche pas.
- supervisor : Supervisor lance un script nodejs sur stdin, il redémarre le script tout seul en cas d’erreur et je crois même qu’il le redémarre aussi en cas de modification des fichiers sources.
Parmi tous ces choix, je me suis arrêté sur supervisor car il fait le minimum requis et il s’emboitera très bien avec la mise en place d’un service pour lancer le tout. Nous allons donc installer supervisor
en module node global afin de pouvoir l’utiliser directement en commande au sein du terminal :
sudo npm install supervisor -g
Puis ensuite, pour lancer votre script :
supervisor script.js
Normalement, en cas d’erreur, supervisor relancera automatiquement votre script.
Mise en place du service
Maintenant que nous avons trouvé comment redémarrer automatiquement notre script nodeJS, nous allons le « transformer » en service. De plus, nous le rajouterons à notre liste des services à exécuter au démarrage.
Pour cela, nous allons utiliser un programme codeé en python du nom de supervisor
. Encore un programme Supervisor ? Oui et il va nous permettre de faire ceci :
- exécuter directement le programme avec un utilisateur propre
- exécuter le programme directement dans le répertoire cible
- définir les variables d’environnement
Autant de choses utiles pour ma problématique. Voici la procédure d’installation du programme supervisor
:
sudo apt-get install python-setuptools
sudo easy_install supervisor
Ensuite, créez le fichier /etc/init.d/supervisord
et placez y le code suivant afin d’utiliser supervisor
comme un service :
#! /bin/bash -e
SUPERVISORD=/usr/local/bin/supervisord
PIDFILE=/tmp/supervisord.pid
OPTS="-c /etc/supervisord.conf"
test -x $SUPERVISORD || exit 0
. /lib/lsb/init-functions
export PATH="${PATH:+$PATH:}/usr/local/bin:/usr/sbin:/sbin"
case "$1" in
start)
log_begin_msg "Starting Supervisor daemon manager..."
start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $SUPERVISORD -- $OPTS || log_end_msg 1
log_end_msg 0
;;
stop)
log_begin_msg "Stopping Supervisor daemon manager..."
start-stop-daemon --stop --quiet --oknodo --pidfile $PIDFILE || log_end_msg 1
log_end_msg 0
;;
restart|reload|force-reload)
log_begin_msg "Restarting Supervisor daemon manager..."
start-stop-daemon --stop --quiet --oknodo --retry 30 --pidfile $PIDFILE
start-stop-daemon --start --quiet --pidfile /var/run/sshd.pid --exec $SUPERVISORD -- $OPTS || log_end_msg 1
log_end_msg 0
;;
*)
log_success_msg "Usage: /etc/init.d/supervisor
{start|stop|reload|force-reload|restart}"
exit 1
esac
exit 0
Nous le rendons ensuite exécutable et nous le rajoutons aux programmes relancés au démarrage :
sudo chmod +x /etc/init.d/supervisord
sudo update-rc.d supervisord defaults
Maintenant que supervisord
est mis en place, nous devons le configurer. Pour cela, nous allons générer le fichier de configuration par défaut comme ceci :
sudo echo_supervisord_conf > supervisord.conf
sudo mv supervisord.conf /etc/supervisord.conf
Avant de rajouter les scripts NodeJS à exécuter, nous éditons maintenant les configurations de supervisor en touchant au fichier /etc/supervisord.conf
et en modificant les valeurs suivantes comme indiqué :
chmod=0777 ; sockef file mode (default 0700)
user=user ; utiliateur devat exécuter les programmes de supervisord
Maintenant, rajoutez ce qui suit en fin du fichier de configuration pour chaque programmes serveur nodeJS que vous devez exécuter :
[program:yourapplicationname]
command=supervisor votrescript.js
directory=/application/directory
environment=NODE_ENV=production
Voilà. Pour lancer votre serveur nodeJS, exécutez simplement la commande sudo service supervisord start
et remplacez start
par stop
pour y mettre fin.
Conclusion
Je ne sais pas si ce que j’ai fait est la meilleure méthode mais c’est celle que j’ai trouvé être la plus simple à réaliser et qui répondait à mo problème. Bien entendu, supervisord
peut lancer en même temps différentes applications dans différents langages. Si vous avez des questions, des conseils ou d’autres solutions, n’hésitez surtout pas à me les proposer. Sur ce, je vous souhaite un bon week-end.
Commentaires : 3
NodeJS : Service et redémarrage automatique http://t.co/RPPsnwK98Q
Merci pour cet article, j’ai enfin pu déployer ma petite application sur node ! 🙂
Merciiiii ! 🙂