Déploiement d'une application avec Now.sh (v2)

Pour un side project que je développe sur mon temps personnel, j'avais besoin de déployer une application Create-React-App (CRA) ainsi que quelques Web Services. J'ai choisi une architecture Serverless pour ne pas avoir à m'occuper des serveurs moi-même.

J'ai choisi de faire mes déploiements avec l'outil Now, que je vais vous présenter.

Présentation de l'outil de déploiement Now.sh

Présentation issue du site now.sh

Now est un outil de déploiement dans le cloud développé par Zeit qui a pour mission de rendre le cloud computing accessible pour tout le monde.

L'outil Now a donc pour but de rendre aussi simple que possible le déploiement de site web dans le cloud. Le site officiel est ici https://zeit.co/now. La présentation suivante se base sur la version actuelle (v2).

Le cli est disponible sous la forme d'un package npm. npm install -g now

L'outil gère pour vous la configuration SSL. Le contenu de vos déploiements est automatiquement géré par des serveurs de cache et vous pouvez gérer les régions dans lesquelles sera déployée votre application. Plus d'info ici https://zeit.co/smart-cdn

Le scaling de votre application est automatique depuis la version 2, et ça c'est génial.

Usages possibles

  • Déployer la documentation d'une librairie open source (équivalent de Netlify, Github Pages, etc) grâce à l'intégration Github.
  • Déployer un site web statique (React, Angular, etc)
  • Créer des Web Services à l'aide des fonctions Serverless (Node.js, Go, Python, Ruby)
  • Mélangez un statique et des web services et vous avez votre appli web ! Le tout déployé en une commande now.

Combien cela va t-il me coûter ?

Now propose un plan gratuit largement suffisant pour débuter de petits projets.

Le pricing proposé par Now

Free plan !

Le plan gratuit est parfait si vous n'avez pas de function serverless et que souhaitez déployer uniquement un site web statique. Autrement vous serez limités à 1000 invocations serverless par jour.

Paid plan

Une calculatrice est à votre disposition ici https://zeit.co/pricing/calculator pour faire une estimation du coût potentiel.

Notez qu'actuellement chaque function serverless est exécutée avec 3Gb de RAM. Donc si votre function dure 1 seconde, cela vous reviendra à 0.000102$ par appel. Il est prévu par la team de Now que l'allocation mémoire soit configurable prochainement.

Un point sur le serverless

Définition de Serverless

Serverless != Serverfree, il y a bien évidemment des serveurs quelques part, seulement la création/gestion/maintenance de ces serveurs ne sera pas dans notre liste de tâches à faire. Nous nous contenterons uniquement des développements et d'être capable de fournir un package de notre application. Le reste sera géré par une plateforme basée sur le Cloud.

Le fait de reporter ces tâches à une plateforme induit un coût, qui dépend de la plateforme et du mode de facturation. Un mode de facturation assez répandu est celui où l'on paye uniquement en fonction des ressources que l'on consomme.

  • Bande passante consommée
  • CPU utilisés
  • RAM
  • etc

Fonction Serverless

Une fonction serverless est un morceau de code destiné à être exécuté par un serveur avec une entrée et une sortie. Voyez cela comme une méthode de votre code dans votre langage préféré qui sera rendue disponible par Web Services ou autre selon la plateforme choisie.

Plus de lecture ci-dessous selon les plateformes, un synonyme de function couramment utilisé est lambda. https://azure.microsoft.com/fr-fr/services/functions/ https://cloud.google.com/functions/ https://fnproject.io/ https://aws.amazon.com/fr/lambda/

Un petit exemple d'une fonction serverless en Node.js

module.exports = (req, res) => {
  res.json({
    body: req.body,
    query: req.query,
    cookies: req.cookies
  })
}

Ici on exporte une fonction Node.js avec 2 paramètres, req et res. req correspond à l'objet Request de Node et res à Response. Dans cet exemple la fonction retourne un JSON avec le contenu de la requête.

Configuration de Now (v2)

Déploiement sans configuration

Il est possible depuis peu de déployer automatiquement certains frameworks sans configuration, voir https://zeit.co/docs/v2/build-step/

Il est même possible de mettre ses functions serverless dans un dossier /api de votre projet. Now les déploiera automatiquement.

Pour plus d'informations à ce sujet, ils ont publié un article de blog ici : https://zeit.co/blog/zero-config

Déploiement avec configuration

Now permet de configurer ses déploiements à l'aide d'un fichier now.json.

Voici un exemple de configuration pour un monorepo (ie: repository contenant plusieurs applications) avec deux parties.

  • web (qui contient une application Create-React-App)
  • lambda (qui contient des functions serverless)
{
  "version": 2, // Version de Now
  "name": "My application", // Nom de l'application
  "builds": [
    {
      "src": "web/package.json", // Le package.json de l'application statique
      "use": "@now/static-build", // Le type de builder à utiliser
      "config": {
        "distDir": "build" // Permet de définir le dossier qui sera déployé
      }
    },
    {
      "src": "lambda/*.js", // Les sources à transformer en Web Services
      "use": "@now/node" // Le type de builder à utiliser
    }
  ],
  "alias": "mysuperwebsite.com", // Le nom de domaine lors d'un déploiement en production (nécessite de posséder le domaine évidemment ainsi que l'avoir configuré sur votre compte Now)
  "regions": ["cdg1"], // Les régions dans lesquelles déployer
  "routes": [] // Ici il faut configurer les routes, j'explique plus bas
}

Explications

Now fonctionne avec un système de builder, une application peut contenir plusieurs builders. Ici un builder de site web statique et un builder de function serverless basé sur Node.js.

Pour travailler en local en utilisant les fonctionnalités serverless, il suffit d'éxecuter now dev. A noter que pour le site web statique il faut préciser comment le lancer avec now-dev dans le package.json

Exemple : "now-dev": "react-scripts start"

Lorsque que vous allez déployer votre application, now va uploader les fichiers de votre projet et exécutera les builds ensuite. C'est pourquoi on précise "distDir": "build" dans le premier builder.

A la manière d'un .gitignore vous pouvez configurer ce qu'il ne faut pas uploader dans un fichier .nowignore à la racine de votre projet. Par défaut les nodes_modules ne sont pas uploadés.

Configuration des routes

Lorsqu'une requête va arriver sur votre domaine, il faut qu'elle soit "routée" vers le bon fichier de votre application. Pour cela on utilise la propriété routes du fichier de configuration. Encore une fois pour les frameworks classiques et si vous n'avez qu'un builder de site web statique vous n'aurez pas à le faire.

{
  "src": "/lambda/(.*)",
  "dest": "/lambda/$1"
}

Ici je configure toutes les requêtes de mysuperwebsite.com/lambda/* vers les fichiers de lambda déployés dans now dans le sous dossier lambda.

Il est possible de configurer les headers retournés aux clients de cette manière.

{
  "src": "/service-worker.js",
  "headers": {
    "cache-control": "s-maxage=0"
  },
  "dest": "/web/service-worker.js"
}

Secrets d'environnement et de builds

Now intègre une gestion des secrets global que vous pouvez gérer à l'aide de la commande now secrets

Il n'y pas pour le moment moyen de créer un secret avec des valeurs différentes en fonction de l'environnement. Je recommande donc de préfixer le nom de votre secret par le nom de l'environnement. Exemple: staging-facebook-client-id

Gestion d'environnement multiples

Actuellement la gestion de divers environnements de déploiement (recette, production) n'est pas forcément intuitive alors comme je suis gentil et que j'ai passé pas mal de temps à le mettre en place sur mon projet perso voici comment il faut faire. A savoir aussi que les développeurs de l'outil prévoient d'améliorer le fonctionnement sur ce point.

Environnement de déploiement:

  • Utilite votre fichier now.json
  • Se lance avec now dev
  • Mettre les variables d'environnement dans un fichier .env
  • Mettre les variables d'environnement pour les builds dans un fichier .env.build
  • Les variables dites secrets ne fonctionne pas avec now dev pour le moment c'est pourquoi il faut ces 2 fichiers

Environnment de recette:

  • Créer un fichier now.staging.json qui sera une copie de now.json
  • Modifier l'alias par un sous domaine de votre domaine, par exemple staging.project.com
  • Modifier les propriétés env et build env dans votre fichier now.staging.json si besoin (vous pouvez créer des secrets en les préfixant par staging par exemple)
  • Déployer avec la commande suivante now --target production --local-config now.staging.json

C'est ici que le fonctionnement peut porter à confusion car nous déployons avec la propriété production dans un environnement de recette.

Environnement de production:

  • On utilise le fichier now.json et on renseigne l'alias project.com
  • On déploie comme ceci now --target production

Dans cette configuration j'utilise le même fichier now.json pour l'environnement de développement et de production. Si besoin de différencier les deux, il est possible de créer un fichier now.production.json. Il suffira d'ajouter le paramètre --local-config now.production.json lors du déploiement.

Commandes utiles

Les différentes lignes de commande de Now

Conclusion

Si vous êtes développeur front et souhaitez déployer vos applications sans avoir à configurer de serveur, c'est la solution parfaite pour vous ! Le plan gratuit est vraiment top pour démarrer et pourra suffire si vous n'avez pas de functions serverless.

Je n'ai pas pu tout aborder dans cet article mais si vous voulez en savoir plus vous trouverez la documentation ici https://zeit.co/docs/.

Si vous avez lu cet article jusqu'au bout, tout d'abord merci ! C'est donc que vous faites de la veille techno, n'hésitez pas à repasser sur le blog bientôt j'aurai quelque chose pour vous :).

Clément Allain