Nginx, l'aiguilleur

Dans le cadre de mon nouvel emploi, je démarre un projet (enfin) en NodeJS pour le backend et AngularJS pour le front. Nous avons démarré le projet front avec le générateur angular de Yeoman qui propose un serveur qui génère à la volée les fichiers nécéssaires au fonctionnement de l'app. Et quand on a ajouté le serveur de backend en tant que sous projet, il a fallu trouver un moyen de faire tourner les deux services sur le même port sans perdre de temps à modifier la config grunt du projet angular. Nous avons donc utilisé Nginx.

Proxy Pass

Donc voici la problématique : notre machine de développement propose deux serveurs qui doivent tourner en parallèle, l'un pour servir les fichiers "statiques" et l'autre pour servir l'API RESTful. Cependant, ces deux serveurs doivent être accessibles via le même domaine et port sur le navigateur client. En production, nous aurons la même problématique avec une facilité : les fichiers statiques seront alors servis directement par le serveur web.

Nous allons donc utiliser un proxy pass pour permettre à notre serveur web de rediriger les requetes pointant sur /api/ vers le serveur NodeJS du backend, et les autres requêtes vers le serveur Grunt du projet Angular. En prod, nous aurons la même chose sauf que les requêtes vers Angular seront directement servies par le serveur web.

Nginx

Nginx est un serveur web, tellement puissant et simple à configurer que je me demande pourquoi on continue à utiliser Apache. Cependant, vous pourrez adapter la configuration suivante avec n'importe quel autre serveur.

Configuration

Nous partons du postulat que le serveur de votre projet Angular écoute le port 9000 et le serveur du backend écoute le port 9001, les deux doivent se limiter à 127.0.0.1 par soucis de sécurité.

Après avoir installé Nginx d'un coup de :

sudo apt-get install nginx

Vous allez ensuite créer un fichier de config pour votre projet dans /etc/nginx/sites-enabled/ :

sudo vi /etc/nginx/sites-enabled/monprojet

Et vous y placerez la config suivante :

server {
    listen 80;
    server_name monprojet.local;

    location /api/ {
        proxy_pass  http://localhost:9001; # api
        proxy_redirect     off;
        proxy_set_header   Host             $host;
        proxy_set_header   X-Real-IP        $remote_addr;
        proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
    }
    location / {
        proxy_pass  http://localhost:9000; # client
        proxy_redirect     off;
        proxy_set_header   Host             $host;
        proxy_set_header   X-Real-IP        $remote_addr;
        proxy_set_header   X-Forwarded-For    $proxy_add_x_forwarded_for;
    }
}

Il ne reste plus qu'à démarrer Nginx si ce n'est fait :

sudo service nginx start

ou à le recharger s'il tournait déjà :

sudo service nginx reload

Vous pouvez alors vous rendre avec votre browser sur http://monprojet.local qui vous affichera alors… une erreur. Et oui ! Vous avez oublié de lancer les serveurs Grunt et Node ! Lancez les via deux instances de GNU Screen ou en tant que daemon avec forever et rechargez votre page.

Pensez aussi à modifier votre /etc/hosts pour qu'il sache que monprojet.local pointe sur l'IP de votre VM.

Hadrien

Hi, I'm a french Javascript Lead Developer, Web Architect from Toulouse, France. I've worked for 12 years for many projects with YUI, AngularJS, Aurelia.io and now React and React native.

Toulouse, France https://hadrien.eu