Partie 3 : Déploiement d'applications web
Comment déployer une application sur le web ?
Types de service
Il existe énormément de possibilités pour déployer une application web.
Pour certains, comme des administrateurs réseaux ou des responsables de l'infrastructure informatique, il s'agit d'un métier à part entière.
Mais de plus en plus, avec l'avancée des services sur le cloud, les développeurs prennent un rôle important dans le déploiement des applications.
Voici un diagramme qui exprime bien les différentes façons de déployer une applications :

Sur ce diagramme, tout à gauche, nous sommes entièrement responsable de la mise à disposition de l'infrastructure. Il faut donc d'énormes connaissances réseaux, au niveau OS, afin de mettre à disposition des serveurs, les sécuriser,...
Lorsqu'on va vers la droite du diagramme, on passe vers la dématérialisation des services, vers le cloud, qui offre principalement trois types de services :
- IaaS ou Infrastructure as a Service : nous recevons toute l'infrastructure, nous devons encore nous occuper du reste, la gestion d'un OS (Linux, Windows...), les bases de données, les applications et leurs données ; Amazon Web Services, Microsoft Azure, Google Cloud, OVHcloud offrent ce genre de services...
- PaaS ou Platform as a Service : nous recevons tout ce qu'il faut pour simplement développer des applications ; heroku, Amazon Web Services, Microsoft Azure, Google Cloud, OVHcloud offrent ce genre de services...
- SaaS ou Software as a Service : nous recevons des applications prêtes à être utilisées ; Office 365 est un exemple, Github en est un autre.
Recette générale pour déployer
Lorsque nous allons déployer nos RESTful API, nous allons donc très souvent utiliser un PaaS. En effet, voici les étapes principales pour le déploiement :
- création et configuration de l'application que nous allons déployer avec les outils offerts par le provider ; pour ce cours, nous indiquerons que nous souhaitons développer une application Node.js ;
- création d'un git repository pour chaque projet et faire un push des sources de notre application via les outils offerts par le provider ;
- build et déploiement automatique de l'application seront faits en utilisant les outils du provider, via un service accessible par une URL de développement offerte par le provider.
Chaque provider va fournir une** recette de cuisine** pour pouvoir déployer une application. Il est donc important de trouver la bonne documentation décrivant toutes les étapes.
Déploiement d'un frontend
Pour déployer le frontend d'une SPA, les étapes principales sont similaires au déploiement d'une RESTful API. Néanmoins, il existe des outils qui permettent de faciliter le déploiement du frontend d'une SPA car ce sont juste des assets à partager sur le web, il n'y a pas d'intelligence à fournir côté serveur pour générer du contenu.
Du coup, on peut utiliser des CDN (Content Delivery Network), des groupes de serveur qui travaillent ensemble pour fournir nos assets de manière extra rapide sur Internet.
Comme Github offre ce service via Github Pages, que c'est gratuit si vous acceptez que votre code source soit publique, c'est un service idéal pour notre frontend.
Il faut juste faire attention que notre frontend n'utilise pas de proxy pour contacter notre RESTful API, il doit le faire directement. L'API devra donc gérer les CORS pour autoriser l'URL associée à notre frontend !
Déploiement d'une API
Pour déployer nos RESTful API, le facteur principal que nous souhaitons mettre en avant dans ce cours, c'est de bénéficier d'un service gratuit. Comme nous étudions le JS, nous considérons que nous n'avons pas encore besoin d'un hébergement offrant de grandes performances. Nous souhaitons juste quelque chose qui nous permette de tester sur le web nos applications et de les partager avec quelques dizaines de personnes. Pour le frontend, via Github Pages, nous avons trouvé un service de qualité, partageable avec des milliers de personnes. Par contre, pour héberger une API, les services gratuits tendent à disparaître.
Avant l'automne 2022, Heroku fournissait un service gratuit qui était parfait pour nos API. Mais ce service a disparu. Il est maintenant possible, dans le GithHub Student Developer Pack, de bénéficier de Heroku gratuitement pendant une année uniquement...
Du coup, pour construire une API, il semblerait qu'il ne reste plus que des services qui soient que temporairement gratuits. Le souci avec ce genre de services, c'est que même si c'est gratuit, on vous demande souvent votre carte de crédit, afin de "vérifier que vous n'êtes pas un robot" 🤖 !
Nous avons donc tenté de sélectionner un service gratuit, temporaire, qui ne demande pas de carte de crédit.
Déploiement du frontend sur GitHub Pages
Informations générales
Si vous n'utilisez pas de proxy dans votre frontend mais que vous faites des requêtes vers votre RESTful API en utilisant directement son nom de domaine, il est possible d'utiliser Github Pages.
Votre RESTful API doit donc elle aussi être déployée et vous devez utiliser son URL pour tous les fetch que vous faites.
Vous trouverez une recette de cuisine pour déployer un frontend sur GitHub Pages. Néanmoins, cette recette est très minimaliste et ne donne pas d'explication sur toutes les choses qu'il y a à faire pour déployer une SPA qui contient un router.
Déploiment d'un frontend basé sur Webpack sur GitHub Pages
Comme ça n'est pas quelque chose de si simple, nous vous offrons la recette de cuisine pour déployer un frontend qui suit l'architecture proposée dans ce cours.
1. Création d'un web repo
- Dans un premier temps, vous devez décider si vous souhaitez déployer votre page en tant que :
- user ou organization site : votre nom de repo doit être votre username ou le nom de votre organisation sur GitHub. L'URL de votre frontend sur GitHub Pages sera : "
https://[username ou orgnanization-name].github.io
". Dans ce cas-là, vous ne pouvez avoir qu'un seul site déployé sur ce nom de domaine. - project site : vous pouvez donner le nom que vous souhaitez à votre repo (autre que votre username ou le nom de votre organisation). L'URL de votre frontend sera : "
https://[username ou orgnanization-name].github.io/repo-name-for-your-frontend
".
- user ou organization site : votre nom de repo doit être votre username ou le nom de votre organisation sur GitHub. L'URL de votre frontend sur GitHub Pages sera : "
- Créez un nouveau web repo vide et publique sur GitHub Pages en lui donnant le nom que vous avez choisi.
⚡ Attention à ne pas créer de fichierREADME
à la création de votre web repo !
2. Création de votre repo local pour votre frontend
- Votre frontend doit avoir été initialisé sur base du boilerplate js-frontend-boilerplate ou js-phaser-boilerplate. Attention à ne pas mettre votre frontend au sein d'un repo git existant. N'hésitez pas à créer une copie de votre frontend à un autre endroit si celui-ci est déjà contenu dans un web repo.
- Effacez le répertoire
.git
si vous avez clôné le boilerplate. - Tapez ces commandes pour initialiser votre repo local et le synchroniser avec votre web repo :
shellgit initgit add .git commit -m "init"git remote add origin https://url-to-your-web-repo.gitgit branch -M maingit push -u origin main
3. Configuration du préfixe en cas de project site
- Si vous avez choisi de créer un user ou un organization site, vous pouvez passer au point suivant, à la configuration de l'URL de l'API.
- Si vous avez choisi de créer un project site sur GitHub (plutôt qu'un user ou organization site), vous devez configurer le préfixe qui sera à prendre en compte lors du déploiement du frontend. Par exemple, si votre web repo se nomme "my-super-frontend", vous devez indiquer ce préfixe au sein de
webpack.config
:
jsconst PRODUCTION_PATH_PREFIX = '/my-super-frontend/';
- NB : Après cette configuration, tous les appels à votre site déployé sur le cloud seront fonctionnels, le router fera le travail d'offrir la bonne page. Ainsi, même si l'utilisateur accède à
https://[username].github.io/my-super-frontend/login
, le router ira chercher la route correspondant au chemin/login
et non pas à la route/my-super-frontend/login
(qui n'existe pas et ne devrait pas être configurée ; en effet il devrait y avoir une route pour/login
dans/src/Components/Router/routes.js
) !
4. Configuration de l'URL de base vers votre API et utilisation de cette URL
- Cette partie n'est pas directement liée à GitHub Pages. Néanmoins, elle doit être réalisée si l'on souhaite que le frontend puisse consommer les opérations d'une RESTful API développée par nos soins.
- Dans
webpack.config
, veuillez configurer l'URL de votre API en fonction du build mode :DEVELOPMENT_API_BASE_URL
pour un build de développement : laissez '/api' si vous souhaitez utiliser le proxy pour appeler votre api ou http://localhost:3000 si vous préférez appeler directement l'API. Dans ce dernier cas, vous devez avoir autorisé l'origine de votre frontend (http://localhost:8080) via les CORS.PRODUCTION_API_BASE_URL
pour un build de production : donnez l'URL où votre application sera déployée, comme par exemple : 'https://your-app-name.azurewebsites.net'.
- Lors du build de votre application par Webpack, en fonction des valeurs que vous avez données à
DEVELOPMENT_API_BASE_URL
etPRODUCTION_API_BASE_URL
,process.env.API_BASE_URL
sera remplacée par l'URL de base vers votre API grâce au code du boilerplate ! - Ainsi, pour faire vos appels vers vos API, utilisez la variable globale
process.env.API_BASE_URL
au sein de vosfetch
. Par exemple :jsfetch(`${process.env.API_BASE_URL}/auths/login`, options); - NB : Lorsque vous lancerez la commande
npm start
, c'estDEVELOPMENT_API_BASE_URL
qui sera utilisée pour appeler votre API grâce à la variable globaleprocess.env.API_BASE_URL
.
Lorsque vous lancerez la commande npm run deploy, c'estDEVELOPMENT_API_BASE_URL
qui sera utilisée pour appeler votre API grâce à la variable globaleprocess.env.API_BASE_URL
.
5. Déploiement du frontend sur GitHub Pages
- Une fois que tout est configuré au niveau de votre repo local (et donc du code de votre frontend), il ne reste plus qu'à lancer le build de production du frontend et le déploiement. Tout cela est offert par le boilerplate en tapant la commande :
shellnpm run deploy
- La librairie
gh-pages
permet de faire unpush
d'un snapshot du contenu du build de production (se trouvant dans/dist/
) vers la branchegh-pages
de votre web repo. - Si GitHub Pages est configuré correctement au niveau de votre web repo, quelques secondes ou minutes après que "Published" ait été affiché dans votre terminal, votre frontend sera disponible sur le cloud via l'URL :
https://[username].github.io
ouhttps://[username].github.io/repo-name-for-your-frontend
.
6. Configuration de GitHub Pages sur votre web repo
- Accédez à l'URL de votre web repo sur
https://github.com/
. - Cliquez sur
Settings
, puis surPages
. - Assurez-vous que :
- la
Source
soit :Deploy from a branch
. - la
Branch
soit :gh-pages
.
- la
- Via
Settings
, puisPages
, vous avez l'URL de votre frontend qui vous est donnée et vous pouvez cliquer surVisit site
(pour accéder à votre site). - A la racine de votre web repo, vous pouvez visualiser tous les builds qui ont été tentés sur GitHub Pages ; à droite de la page, il y à une section
Environments
et un liengithub-pages
: cliquez sur ce lien et vous verrez l'historique des déploiements de votre frontend sur GitHub Pages.
🍬 Que se passe-t-il en cas de refresh d'une page offerte par GitHub Pages ?
Il est intéressant de comprendre un peu mieux comment GitHub Pages fonctionne lorsqu'on lui demande une page qui n'existe pas :
- Imaginez que l'utilisateur fasse un refresh à l'URL
https://[username].github.io/my-super-frontend/login
. GitHub Pages est juste un CDN, un serveur de fichiers statiques. Il n'y a pas de fichier qui corresponde à cette URL ! Dès lors, sans le boilerplate du cours, vous recevriez une erreur 404 😨 ! - Lors du build, le boilerplate du cours (js-frontend-boilerplate ou js-phaser-boilerplate) crée un fichier
404.html
qui est identique àindex.html
. Ainsi, lorsqu'une ressource n'existe pas au niveau du CDN, GitHub Page renverra le contenu de404.html
, et notre SPA sera entièrement fonctionnelle, même en cas de refresh forçant au serveur de nous renvoyer une page 😅 !
Car dans le cadre d'une SPA, c'est le JS, via le router, qui permet d'afficher la page associée à/login
, une fois que tout le frontend a été chargé suite à l'appel d'index.html
. Il n'y a pas de pageLogin.html
qui existe au niveau du serveur !
Déploiement d'une API sur Azure
Informations générales
Azure App Service offre un PaaS. Il est aisé d'y déployer une application Node.js.
Voici la documentation pour créer une app : Create a Node.js web app in Azure.
Vous aurez le droit à 60 minutes de processing gratuites par jour, après quoi votre app renvoie un status code 403. Même si votre app n'est pas toujours active, il n'est pas évident d'estimer si vous tiendrez toute une journée sans erreur 403.
Actuellement, si vous êtes étudiant, vous pouvez bénéficier de 100$ de crédit par an et vous n'avez pas besoin de carte de crédit ! En suivant le tutoriel proposé par Microsoft, vous vous rendrez sur free with Azure for Student et utiliserez par la suite Azure App Service.
Si vous n'êtes plus étudiant, vous pouvez bénéficier de services gratuits, certains toujours gratuits, d'autres pendant 12 mois, avec 200$ de crédit pendant 30 jours. Malheureusement il faut une carte de crédit pour vous faire autoriser...
N'hésitez pas à consulter la documentation d'App Service et de jeter un oeil aux formules tarifaires : App Service pricing.
En résumé pour déployer votre API via VS Code
- N'oubliez pas que votre API va se trouver sur un serveur externe accessible via une URL. Votre frontend lui se trouvera sur une autre URL, probablement sur GitHub Pages pour obtenir un très bon service gratuit. Dans ce cas-ci, pour que votre Frontend puisse dialoguer avec votre API, comme GitHub Pages n'offre pas de proxy, il vous faudra autoriser des origines au niveau de votre API. Comme vu à la partie 2 de ce cours sur l'Autorisation d'origines & les CORS, pensez donc à utiliser le middleware
cors
au niveau de votre API et autoriser au moins deux origines :- l'URL de votre frontend lors du développement. Par exemple :
http://localhost:8080
; - l'URL de votre frontend lors de sa mise en production, son URL sur le cloud. Par exemple si votre frontend est déployé sur GitHub Pages : https://[username ou orgnanization-name].github.io (pour un user ou organization site) ou "
https://[username ou orgnanization-name].github.io/repo-name-for-your-frontend
" (pour un project site).
- l'URL de votre frontend lors du développement. Par exemple :
- Il est important d'ouvrir VS Code sur la racine du projet que vous souhaitez déployer :
File
,Open Folder...
et de sélectionner le dossier racine de votre API (le dossier contenant le fichierpackage.json
). - Après avoir s électionné
Azure
dans VS Code (clic sur le logo d'Azure), clic droit surApp Services
,Create New Web App...
. - Attention de choisir la formule gratuite lorsque vous suivrez la procédure, en indiquant le tarif
F1
. - Choisissez une version de Node qui soit LTS (comme Node 16 LTS par exemple).
- Donnez un nom qui n'existe pas encore à votre API.
- Pour déployer votre API : clic droit sur l'app qui a été créée et qui porte le nom que vous lui avez donné :
Deploy to Web App...
, sélection du folder à déployer (par défaut c'est OK si vous avez bien ouvert VS Code à la racine du code de votre API), puis clic surDeploy
- Acceptez la question
Always deploy the workspace "nom-du-folder-de-votre-api" to "nom-de-votre-app-pour-votre-api" : Yes
. - Une fois déployé, pour accéder à votre API via le browser : clic droit sur le nom de votre app dans VS Code (en dessous de App Services),
Browse Website
. - L'URL de votre API est :
https://[nom-de-votre-app-pour-votre-api].azurewebsites.net
🍬 Déploiement d'une API sur d'autres providers gratuits
Quelques providers d'API temporairement gratuits
Voici une liste d'autres providers qui pourraient être intéressants pour vos déploiements :
- platform.sh : service gratuit pendant 30 jours, pas besoin de carte de crédit.
- Google Cloud : service offrant 300$ de crédit, pendant 90 jours, il faut une carte de crédit 😨, mais pas de charges sauf si upgrade manuel vers un compte payant.
Déploiement d'une API sur Heroku
Introduction
Dès le 28 novembre 2022, les "free Heroku Dynos" ne sont plus disponibles.
Il est maintenant possible, dans le GithHub Student Developer Pack, de bénéficier de Heroku gratuitement pendant une année.
Procédure "maison"
Sur le site d'Heroku, il existe beaucoup de documentation pour apprendre à déployer à l'aide de leurs outils.
Comme il n'est pas si facile de s'y retrouver, voici ci-dessous un résumé des étapes importantes via une procédure "maison".
Préparation de votre application
- Utilisez les bonnes variables d'environnement dans Node.js en vérifiant que
process.env.PORT
est bien écrit dans/bin/www
.
La variable d'environnementPORT
, accessible sous Node viaprocess.env.PORT
, est alloué par Heroku lors du démarrage de l'application. PourHOST
, le plus simple est de ne pas en avoir : votre serveur écoute sur toutes les IP. C'est ce qui est fait par défaut lorsqu'une application Express est générée. - Vérifiez
package.json
: Le script "start" sera ce que heroku lance en 1er.
Il n'y a normalement rien à faire,package.json
doit contenir pour "start" :
json"scripts": {"start": "node ./bin/www" },
- Créez un nouvelle app sur Heroku en vous rendant sur HEROKU,
Sign up
puis via le "Heroku dashboard" :New
,Create
,New app
.
Donnez un nom à votre Heroku app qui soit associé à votre API. - Installez le heroku buildpack pour node ; via le "Heroku dashboard",
Settings
,Add buildpacks
,nodejs
.
L'URL générée pour le buildpack est "heroku/nodejs". - Configurez vos variables d'environnement au sein d'Heroku.
Si vous n'avez pas de secrets au niveau de votre API, pas de base de données ou autres services, vous n'avez rien à faire à cette étape-ci. Sinon, voici la documentation : Configuration and Config Vars.
Push de votre application sur Heroku à l'aide de votre git local
- Allez dans le repo de votre application
- Ajoutez une remote vers le repo de votre Heroku app :
- Option a) avec heroku CLI :
bashnpm install -g herokuheroku loginheroku git:remote -a [your_app_name]
- Option b) sans heroku CLI, directement avec Git :
bashgit remote add heroku https://git.heroku.com/[your_app_name].git
- Faites un push de la branche en cours vers le master sur Heroku :
bashgit push heroku master
Si votre branche en cours n'est pas le master :
bashgit push heroku [branche_en_cours]:master [-f]
-f si la branche locale est fort différente du contenu sur Heroku.
Accès à votre API via le browser
Soit Open app
via "Heroku dashboard", soit vous pouvez directement taper dans le browser : [your_app_name.herokuapp.com
.
Système de fichiers
⚡ Sur Heroku, si vous utilisez des fichiers .json
pour assurer une certaine "persistance" des ressources associées à vos API, ces fichiers seront probablement réinitialisés environ une fois par jour.
En effet, Heroku utilise un système de fichiers éphémères, à chaque fois qu'une dyno est redémarrée, elle utilise une copie du déploiement le plus récent, c'est-à-dire les fichiers qui ont été "push" sur heroku pour lancer le build.
Si vous souhaitez faire persister de l'information sur Heroku pendant plus longtemps qu'une journée, il faudra donc passer soit par une base de données, soit par des API offrant des opérations sur des fichiers (comme Amazon S3 par exemple).
🍬 Déploiement d'une base de données
Bases de données relationnelles
Si vous souhaitez utiliser une base de données relationnelle, n'hésitez pas à utiliser un serveur Postgres.
https://www.elephantsql.com/ offre un service OK pour une base de données gratuite sur le cloud.
Bases de données NoSQL
Si vous souhaitez faire du NoSQL, MongoDB Atlas fournit un service gratuit très intéressant sur le cloud : https://www.mongodb.com/, offrant 500 MB de stockage.
Il existe un site extrêmement bien fait, Full Stack open, qui vous explique comment utilser ce serveur : Fullstack Part 3.
⚡ Attention, si vous avez des données qui sont fort connectées, faire le lien entre des entités est moins évident qu'avec du SQL (voir la notion d'Aggregate sous Mongodb).
🍬 Protection de ses secrets
Si vous utilisez une base de données, vous devriez protéger vos secrets. De même, si vous faites appel à une API tierce qui demande un secret (par exemple une clé pour vous faire autoriser), vous devriez faire en sorte de ne jamais afficher ce secret sur votre web repo.
Nous vous recommandons d'utiliser la librairie dotenv
pour protéger vos secrets.
Pour comprendre comment utiliser cette librairie, vous pouvez lire la documentation du package : https://www.npmjs.com/package/dotenv.
Voici en résumé comment fonctionne dotenv
:
- Vous "cachez" vos secrets dans un fichier
.env
à la racine de votre projet, sous forme de paires de clé/valeur ; chaque paire clé/valeur représente une variable d'environnement qui sera utilisée par votre API pour accéder à vos secrets. - Votre fichier
.env
doit être ignoré par Git ; il doit donc être inscrit dans.gitignore
. - Les développeurs doivent donc avoir leur propre fichier local
.env
; le public n'a pas accès à ce fichier sur le web repo. - Lors du développement uniquement : la librairie
dotenv
est utilisée** dans votre API pour charger toutes les paires clé/valeur se trouvant dans.env
comme variable d'environnements ; - Les variables d'environnement sont utilisée dans le code de votre API quand vous devez accéder aux secrets ;
- Lorsque votre application est déployée sur le cloud, pour un build de production :
dotenv
n'est pas utilisé !- Vous devez charger les variables d'environnement via les outils offerts par votre provider. Il existe souvent une interface web pour introduire des paires de clé/valeur. Il est aussi possible de créer des scripts pour automatiser le chargement des secrets.
Si vous souhaitez plus d'explications avec un exemple concret, nous vous recommandons le site de Fulls Stack open : Saving data to MongoDB.
Projet 3.1 : déploiement de votre frontend & de votre backend
Objectif
Veuillez déployer tant le frontend de votre projet que son API.
Veuillez utiliser GitHub Pages pour le frontend et Azure App Service pour l'API.
Il est fort possible qu'à ce stade-ci, votre SPA soit loin d'être terminée. Néanmoins, il est important de déployer son application le plus tôt possible lors d'un projet.
💭 Pourquoi ?
- Il y a beaucoup de choses que l'on réalise lors du déploiement que l'on ne peut voir quand on exécute son application localement.
Par exemple, si vous développer un jeu vidéo, il est si tentant d'ajouter de magnifiques images, sons... Si vous avez finalement un frontend qui fait plusieurs centaines de MBytes... Et bien lorsque l'application tournera sur le cloud, vous allez vous rendre compte que le temps de chargement devient impossible... Et qu'il faut passer à l'optimisation de vos assets (diminution de leurs tailles, lazy loading...). - On conseille toujours de tester son application, dès qu'on a un squelette complet de celle-ci, dans son environnement final.
Il y a déjà assez de difficultés à gérer pour que le déploiement d'un squelette d'application soit un succès. Si l'on attend la fin du projet pour déployer, et qu'un client attend des résultats, on prend le risque de ne rien pouvoir livrer...
Mise en place du projet
Veuillez repartir du code de Projet 2.20.
Le code doit se trouver dans votre repository local et votre web repository (normalement appelé web2
) dans le répertoire nommé /project/3.1
.
Quand un prototype du frontend est finalisé pour déploiement sur GitHub Pages, veuillez faire un commit
de votre code avec comme message : 3.1.1 : frontend deployment
.
Quand un prototype de votre API est finalisé pour déploiement sur Azure, veuillez faire un commit
de votre code avec comme message : 3.1.2 : api deployment
.
🤝 Tips
- Suivez bien les procédures offertes dans ce cours.
- N'oubliez pas que pour le déploiement sur GitHub Pages, il est important d'avoir un repo spécifique au frontend. Ainsi, vous allez devoir créer un nouveau repo juste pour gérer le déploiement de votre frontend car on ne peut pas avoir de git dans le git...
- Avec MS Azure, il n'est pas obligé de créer un nouveau repo pour déployer l'API. En effet, il est possible de déployer n'importe qu'elle dossier sur une application de Azure App Service.