Comment déployer une application Meteor.js sur Ubuntu 14.04 avec Nginx

À propos de Meteor.js

http://meteor.com [Meteor.js] est un framework pour JavaScript qui permet aux développeurs Web d’écrire du code JavaScript une fois et de le réutiliser à la fois côté client et côté serveur. C’est possible grâce au processus de construction unique de Meteor (pour en savoir plus sur http://docs.meteor.com/#structuringyourappappstructuring votre code d’application et le partage de code]). Cela résout également le problème de la nécessité d’un processus de déploiement compliqué entre development mode, où les développeurs codent et déboguent, et production mode, suffisamment sécurisé pour la version publique de l’application. La structure Meteor offre un moyen de lier étroitement code client et code serveur, ainsi que développement et production. C’est probablement le moyen le plus simple pour les développeurs côté client de commencer à travailler sur du code côté serveur!

Pour voir cela en action, vous pouvez consulter l’introduction video sur le site Web de Meteor.

Meteor.js vous permet de développer des projets tels qu’un site Web (application Web), un navigateur Web basé sur HTML5 (à l’aide d’AppCache) ou une application mobile (via l’intégration à PhoneGap). Tout ce dont vous avez besoin est la connaissance de Javascript et HTML. Meteor prend en charge MongoDB (une base de données NoSQL). Atmosphere héberge des packages qui peuvent fournir des blocs de construction complets pour votre application afin d’accélérer encore plus le développement.

  • A la fin de ce tutoriel, nous aurons: *

  • Meteor.js installé

  • Création d’un package de déploiement contenant une application Meteor complète dans un format prêt pour la production (moins un serveur Web et une base de données)

  • Installé Nginx en tant que serveur Web pour transmettre les requêtes HTTP à Meteor

  • MongoDB installé comme moteur de base de données

  • Géré notre application avec Upstart

  • Sauvegardes quotidiennes configurées de la base de données Meteor

Tout au long de ce didacticiel, si vous ne disposez pas encore de votre propre application Meteor, vous pouvez utiliser l’application exemple «Todo List» du site Meteor.

Avant que tu commences

Tu aurais dû:

  • Une application Meteor existante sur un ordinateur de développement distinct (vous pouvez voir l’exemple de l’application «Todo List» here; des instructions sont fournies plus tard dans le didacticiel).

  • Un nouveau serveur * Ubuntu 14.04 *; les installations Meteor existantes devraient fonctionner dans la plupart des cas

  • * root * accès au serveur pour exécuter des commandes

  • Mise à jour des listes de paquets. Exécuter: + apt-get update

  • Remplacez-le par le nom de domaine que vous utilisez réellement (ou laissez-le si vous n’avez pas de domaine et utilisez plutôt une adresse IP)

  • Remplacez (sans .net) par le nom de votre application

Étape 1 - Configuration d’un serveur Web Nginx

Nous allons installer et configurer Nginx car il nous permet de chiffrer le trafic Web avec SSL, une fonctionnalité que le serveur Web intégré de Meteor ne fournit pas. Nginx nous laissera également servir d’autres sites Web sur le même serveur, filtrer et journaliser le trafic.

Dans notre configuration, nous allons sécuriser notre site avec un certificat SSL et rediriger tout le trafic de HTTP vers HTTPS. Nous allons également utiliser quelques nouvelles pratiques de sécurité pour améliorer la sécurité de la connexion SSL.

Pour installer Nginx, nous exécutons:

apt-get install nginx

Créez un fichier de configuration d’hôte virtuel dans + / etc / nginx / sites-available +.

Vous trouverez ci-dessous un fichier de configuration annoté que nous pouvons créer sous la forme «+ / etc / nginx / sites-available / +» avec le contenu suivant. Les explications pour tous les paramètres de configuration sont incluses dans les commentaires dans le fichier:

server_tokens off; # for security-by-obscurity: stop displaying nginx version

# this section is needed to proxy web-socket connections
map $http_upgrade $connection_upgrade {
   default upgrade;
   ''      close;
}

# HTTP
server {
   listen 80 default_server; # if this is not a default server, remove "default_server"
   listen [::]:80 default_server ipv6only=on;

   root /usr/share/nginx/html; # root is irrelevant
   index index.html index.htm; # this is also irrelevant

   server_name ; # the domain on which we want to host the application. Since we set "default_server" previously, nginx will answer all hosts anyway.

   # redirect non-SSL to SSL
   location / {
       rewrite     ^ https://$server_name$request_uri? permanent;
   }
}

# HTTPS server
server {
   listen 443 ssl spdy; # we enable SPDY here
   server_name ; # this domain must match Common Name (CN) in the SSL certificate

   root html; # irrelevant
   index index.html; # irrelevant

   ssl_certificate /etc/nginx/ssl/; # full path to SSL certificate and CA certificate concatenated together
   ssl_certificate_key /etc/nginx/ssl/; # full path to SSL key

   # performance enhancement for SSL
   ssl_stapling on;
   ssl_session_cache shared:SSL:10m;
   ssl_session_timeout 5m;

   # safety enhancement to SSL: make sure we actually use a safe cipher
   ssl_prefer_server_ciphers on;
   ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
   ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:ECDHE-RSA-RC4-SHA:ECDHE-ECDSA-RC4-SHA:RC4-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!3DES:!MD5:!PSK';

   # config to enable HSTS(HTTP Strict Transport Security) https://developer.mozilla.org/en-US/docs/Security/HTTP_Strict_Transport_Security
   # to avoid ssl stripping https://en.wikipedia.org/wiki/SSL_stripping#SSL_stripping
   add_header Strict-Transport-Security "max-age=31536000;";

   # If your application is not compatible with IE <= 10, this will redirect visitors to a page advising a browser update
   # This works because IE 11 does not present itself as MSIE anymore
   if ($http_user_agent ~ "MSIE" ) {
       return 303 https://browser-update.org/update.html;
   }

   # pass all requests to Meteor
   location / {
       proxy_pass http://127.0.0.1:8080;
       proxy_http_version 1.1;
       proxy_set_header Upgrade $http_upgrade; # allow websockets
       proxy_set_header Connection $connection_upgrade;
       proxy_set_header X-Forwarded-For $remote_addr; # preserve client IP

       # this setting allows the browser to cache the application in a way compatible with Meteor
       # on every applicaiton update the name of CSS and JS file is different, so they can be cache infinitely (here: 30 days)
       # the root path (/) MUST NOT be cached
       if ($uri != '/') {
           expires 30d;
       }
   }
}

Si vous souhaitez adapter le fichier de configuration à vos besoins et pour plus d’explications, consultez ce didacticiel à l’adresse https://www.digitalocean.com/community/tutorials/how-to-set-up-nginx- server-blocks-virtual-hosts-on-ubuntu-14-04-lts [hôtes virtuels Nginx].

Comme indiqué dans le fichier de configuration de l’hôte virtuel, Nginx attend un certificat SSL valide et une clé dans + / etc / nginx / ssl +. Nous devons créer ce répertoire et le sécuriser:

mkdir /etc/nginx/ssl
chmod 0700 /etc/nginx/ssl

Ensuite, nous pouvons créer les fichiers contenant le certificat (et le certificat de chaîne si nécessaire) et la clé aux emplacements définis dans la configuration ci-dessus:

  • certificat: + / etc / nginx / ssl / +

  • clé: + / etc / nginx / ssl / +

Si vous ne possédez pas déjà de certificat SSL et de clé, vous devez maintenant créer un certificat auto-signé à l’aide de ce https://www.digitalocean.com/community/tutorials/how-to-create-a-ssl-certificate-on -nginx-for-ubuntu-12-04 [tutoriel sur la création de certificats SSL auto-signés pour Nginx]. N’oubliez pas que vous souhaiterez utiliser les mêmes noms du fichier de configuration, tels que * todos.key * comme nom de clé et * todos.pem * comme nom de certificat. Même si un certificat auto-signé convient aux tests, il est recommandé d’utiliser un certificat commercial et signé pour la production. Un certificat auto-signé provoquera des avertissements Nginx connectés à ssl_stapling et un avertissement de sécurité dans le navigateur Web.

Lorsque vous avez terminé de créer ou d’obtenir votre certificat, assurez-vous de disposer des fichiers + todos.pem + et + todos.key + mentionnés ci-dessus.

Ensuite, nous devrions désactiver le vhost par défaut:

rm /etc/nginx/sites-enabled/default

Et activez notre météore vhost:

ln -s /etc/nginx/sites-available/ /etc/nginx/sites-enabled/

Vérifiez que la configuration de vhost est exempte d’erreur (vous verrez une erreur liée à ssl_stapling si vous avez un certificat auto-signé; c’est correct):

nginx -t

Si tout se présente bien, nous pouvons appliquer les modifications à Nginx:

nginx -s reload

À ce stade, vous pouvez utiliser votre navigateur Web pour visiter https: // (ou votre adresse IP). Il nous montrera * 502 Bad Gateway *. C’est bien, parce que Meteor n’est pas encore en marche!

Deuxième étape - Configurer une base de données MongoDB

Nous installerons MongoDB à partir du référentiel Ubuntu habituel. La configuration standard devrait bien se passer. Aucune authentification n’est requise pour se connecter à la base de données, mais les connexions ne sont possibles qu’à partir de localhost. Cela signifie qu’aucune connexion externe n’est possible et que la base de données est donc sécurisée, tant que nous n’avons pas d’utilisateurs non fiables disposant d’un accès SSH au système.

Installez le package du serveur MongoDB:

apt-get install mongodb-server

C’est tout ce dont nous avons besoin pour que MongoDB fonctionne. Pour être sûr que l’accès depuis des hôtes externes n’est pas possible, exécutez la procédure suivante pour nous assurer que MongoDB est lié à * 127.0.0.1 *. Vérifiez avec cette commande:

netstat -ln | grep -E '27017|28017'

Production attendue:

tcp        0      0 127.0.0.1:27017         0.0.0.0:*               LISTEN
tcp        0      0 127.0.0.1:28017         0.0.0.0:*               LISTEN
unix  2      [ ACC ]     STREAM     LISTENING     6091441  /tmp/mongodb-27017.sock

Afin de disposer de sauvegardes quotidiennes en cas de problème, nous pouvons * éventuellement * installer une commande simple en tant que tâche journalière. Créez un fichier + / etc / cron.d / mongodb-backup +:

@daily root mkdir -p /var/backups/mongodb; mongodump --db  --out /var/backups/mongodb/$(date +'\%Y-\%m-\%d')

Étape 3 - Installation de l’application Meteor

Premièrement, nous devons installer Node.js. Puisque Meteor nécessite généralement une version de Node.js plus récente que celle disponible dans le référentiel standard, nous utiliserons un PPA personnalisé (au moment de la rédaction, Ubuntu 14.04 fournit nodejs = 0.10.25 ~ dfsg2-2ubuntu1, tandis que Meteor 0.8.3 requiert Node.js 0.10.29 ou une version plus récente) _.

Exécutez les opérations suivantes pour ajouter un fichier PPA avec Node.js, puis confirmez en appuyant sur Entrée:

add-apt-repository ppa:chris-lea/node.js

Sortie:

Evented I/O for V8 javascript. Node's goal is to provide an easy way to build scalable network programs
More info: https://launchpad.net/~chris-lea/+archive/ubuntu/node.js
Press [ENTER] to continue or ctrl-c to cancel adding it

gpg: keyring `/tmp/tmphsbizg3u/secring.gpg' created
gpg: keyring `/tmp/tmphsbizg3u/pubring.gpg' created
gpg: requesting key C7917B12 from hkp server keyserver.ubuntu.com
gpg: /tmp/tmphsbizg3u/trustdb.gpg: trustdb created
gpg: key C7917B12: public key "Launchpad chrislea" imported
gpg: Total number processed: 1
gpg:               imported: 1  (RSA: 1)
OK

Nous devons maintenant actualiser le cache du référentiel, puis installer Node.js et npm (gestionnaire de paquets Node.js):

apt-get update
apt-get install nodejs

Il est recommandé d’exécuter notre application Meteor en tant qu’utilisateur régulier. Par conséquent, nous allons créer un nouvel utilisateur système spécifiquement à cette fin:

adduser --disabled-login

Sortie:

Adding user `todos' ...
Adding new group `todos' (1001) ...
Adding new user `todos' (1001) with group `todos' ...
Creating home directory `/home/todos' ...
Copying files from `/etc/skel' ...
Changing the user information for todos
Enter the new value, or press ENTER for the default
       Full Name []:
       Room Number []:
       Work Phone []:
       Home Phone []:
       Other []:
Is the information correct? [Y/n]

Quatrième étape - Configurer Upstart

Nous sommes maintenant prêts à créer le service Upstart à gérer notre application Meteor. Upstart démarrera automatiquement l’application au démarrage et relancera Meteor en cas de décès. Pour en savoir plus sur la création de fichiers de service Upstart, consultez la page https://www.digitalocean.com/community/tutorials/the-upstart-event-system-what-it-it-is-and-how-to-use-it ].

Créez le fichier + / etc / init / .conf +. Encore une fois, il est annoté en ligne:

# upstart service file at /etc/init/
description "Meteor.js (NodeJS) application"
author "Daniel Speichert <[email protected]>"

# When to start the service
start on started mongodb and runlevel [2345]

# When to stop the service
stop on shutdown

# Automatically restart process if crashed
respawn
respawn limit 10 5

# we don't use buil-in log because we use a script below
# console log

# drop root proviliges and switch to mymetorapp user
setuid
setgid

script
   export PATH=/opt/local/bin:/opt/local/sbin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
   export NODE_PATH=/usr/lib/nodejs:/usr/lib/node_modules:/usr/share/javascript
   # set to home directory of the user Meteor will be running as
   export PWD=/home/
   export HOME=/home/
   # leave as 127.0.0.1 for security
   export BIND_IP=127.0.0.1
   # the port nginx is proxying requests to
   export PORT=8080
   # this allows Meteor to figure out correct IP address of visitors
   export HTTP_FORWARDED_COUNT=1
   # MongoDB connection string using  as database name
   export MONGO_URL=mongodb://localhost:27017/
   # The domain name as configured previously as server_name in nginx
   export ROOT_URL=https://
   # optional JSON config - the contents of file specified by passing "--settings" parameter to meteor command in development mode
   export METEOR_SETTINGS='{ "somesetting": "someval", "public": { "othersetting": "anothervalue" } }'
   # this is optional: http://docs.meteor.com/#email
   # commented out will default to no email being sent
   # you must register with MailGun to have a username and password there
   # export MAIL_URL=smtp://[email protected]:[email protected]
   # alternatively install "apt-get install default-mta" and uncomment:
   # export MAIL_URL=smtp://localhost
   exec node /home//bundle/main.js >> /home//.log
end script

Une chose à noter dans ce fichier de configuration est le paramètre + METEOR_SETTINGS +. Si vous utilisez + meteor --settings config.json + lors du lancement du mode de développement de Meteor, vous devez alors coller le contenu de + config.json + en tant que variable dans + METEOR_SETTINGS +.

+ MAIL_URL + doit être une URL SMTP valide * uniquement * si vous prévoyez d’utiliser le paquet Email de Meteor. Vous pouvez utiliser MailGun (selon les recommandations de Meteor), un serveur de messagerie local, etc.

Comme nous pouvons le voir dans le fichier, le journal sera sauvegardé dans + / home //. Log. +. Ce fichier ne tournera pas et * SERA CROISSANT * au fil du temps. C’est une bonne idée de garder un œil dessus. Idéalement, il ne devrait pas y avoir beaucoup de contenu (erreurs). Vous pouvez éventuellement configurer log rotation ou remplacez + >> + par +> + à la fin des scripts Upstart afin d’écraser l’ensemble du fichier au lieu d’ajouter à la fin.

Ne démarrez pas encore ce service car nous n’avons pas encore les fichiers de l’application Meteor en place!

Cinquième étape - Déploiement de l’application Meteor

  • Facultatif: Si vous n’avez pas encore de projet Meteor *

Si vous n’avez pas encore de projet Meteor et que vous souhaitez utiliser une application de démonstration, ce n’est pas un problème!

  • Procédez à l’étape suivante sur votre ordinateur personnel ou sur un serveur Linux de développement. * Les commandes peuvent varier en fonction de votre système d’exploitation. Déplacer vers votre dossier personnel:

cd ~

Tout d’abord, installez la version de développement de Meteor:

curl https://install.meteor.com | /bin/sh

Créez ensuite une application à partir d’un exemple, appelé Todo List:

meteor create --example todos

Maintenant, entrez le répertoire de votre application et vous êtes prêt à continuer:

cd todos
  • Tous les projets Meteor *

Il est temps de créer un ensemble de version de production à partir de notre application Meteor. Les commandes suivantes doivent être exécutées sur votre * ordinateur personnel ou votre serveur Linux de développement *, quel que soit le lieu d’installation de votre application Meteor. Allez dans le répertoire de votre projet:

cd

Et exécuter:

meteor build .

Cela créera un fichier d’archive du type + todos.tar.gz + dans le répertoire ++. Copiez ce fichier dans votre répertoire + ~ + sur votre Droplet.

scp .tar.gz root@:~
  • Retournez maintenant dans votre Droplet. * Créez un répertoire de projet et déplacez-y le fichier de projet d’archive. Notez qu’il s’agit du dossier de base de l’utilisateur du projet créé précédemment, not votre dossier de départ root:

mkdir /home/
mv .tar.gz /home/

Déplacez-vous dans le répertoire du projet et décompressez-le:

cd /home/
tar -zxf .tar.gz

Jetez un coup d’œil au projet LISEZMOI:

cat /home//bundle/README

Le paquet comprend un fichier + README + avec le contenu:

This is a Meteor application bundle. It has only one external dependency:
Node.js 0.10.29 or newer. To run the application:

 $ (cd programs/server && npm install)
 $ export MONGO_URL='mongodb://user:password@host:port/databasename'
 $ export ROOT_URL='http://example.com'
 $ export MAIL_URL='smtp://user:password@mailhost:port/'
 $ node main.js

Use the PORT environment variable to set the port where the
application will listen. The default is 80, but that will require
root on most systems.

Find out more about Meteor at meteor.com.

Cette recette est reflétée dans notre fichier + / etc / init / .conf +. Nous devons encore faire quelque chose dans le fichier README.

Nous devons maintenant installer certains modules npm requis. Pour pouvoir en construire certaines, nous devons également installer g ++ et faire:

apt-get install g++ make
cd /home//bundle/programs/server
npm install

Vous devriez voir la sortie comme ceci:

npm WARN package.json [email protected] No description
npm WARN package.json [email protected] No repository field.
npm WARN package.json [email protected] No README data

> [email protected] install /home/todos/bundle/programs/server/node_modules/fibers
> node ./build.js

`linux-x64-v8-3.14` exists; testing
Binary is fine; exiting
[email protected] node_modules/underscore

[email protected] node_modules/semver

[email protected] node_modules/source-map-support
└── [email protected] ([email protected])

[email protected] node_modules/fibers

Cela s’explique par le fait que notre groupe d’applications ne contient pas de modules et de bibliothèques dépendants de la plate-forme.

Nous sommes presque prêts à exécuter l’application, mais comme nous avons utilisé des fichiers en tant que root et qu’ils doivent appartenir à l’utilisateur ++, nous devons mettre à jour la propriété du répertoire du projet:

chown : /home/ -R

Sixième étape - Showtime

À ce stade, nous avons tout ce dont nous avons besoin pour exécuter notre application Meteor:

  • Environnement Node.js installé

  • Application installée dans son répertoire de projet

  • Service Upstart configuré pour exécuter l’application

  • Base de données MongoDB

  • Le serveur proxy Nginx en face de notre application Meteor pour fournir un cryptage SSL

Pour démarrer notre application, exécutons cette commande à partir du répertoire du projet:

start

Vous devriez maintenant pouvoir visualiser votre application dans le navigateur à l’adresse https: //.

Re-déployer l’application

Lorsque vous apportez des modifications en mode de développement (et vous le ferez, nous sommes des développeurs après tout!), Vous pouvez simplement répéter l’étape 5 (à partir de + météore build +) et suivre la plupart des étapes jusqu’à ce que + + + redémarre + commande, qui rechargera votre application via Upstart.

De cette façon, vous pouvez pousser une nouvelle version sans temps d’arrêt. Les clients (visiteurs de votre site Web) extrairont automatiquement la nouvelle version du code et actualiseront leur page - c’est la magie de Meteor!

Si vous souhaitez tester cela, vous pouvez apporter une simple modification au texte de la page + todos / client / todos.html + de votre copie de développement de l’application sur votre ordinateur personnel ou votre serveur de développement.

  • Serveur de développement: *

Construire:

meteor build

Télécharger:

scp .tar.gz root@:/home/
  • Serveur de production: *

Développer:

tar -zxf /home//.tar.gz

Déplacez-vous dans le dossier du projet:

cd /home//bundle/programs/server

Mettez à jour les modules npm (vous pouvez voir quelques avertissements):

npm install

Redémarrez l’application:

restart

Dépannage

Si quelque chose ne va pas, voici quelques astuces sur les problèmes à résoudre:

  • Vérifiez + / home //. Log + si votre application démarre et meurt; il devrait émettre un message d’erreur approprié (par exemple en cas d’erreur de programmation).

  • Vérifiez + / var / log / nginx / error.log + si vous voyez une erreur HTTP à la place de votre application.

  • Vérifiez + / var / log / mongodb / mongod.log si vous pensez qu’il pourrait y avoir un problème avec la base de données.

Enfin, vérifiez si tous les services sont en cours d’exécution:

status
service nginx status
status mongodb