Article original : How to Deploy a React App to Production Using Docker and NGINX with API Proxies
Cet article vous aidera à apprendre comment déployer vos applications React en production. Nous allons utiliser Docker et NGINX pour sécuriser les clés API et proxyfier les requêtes afin de prévenir les violations de partage de ressources cross-origin (CORS).
Vous pouvez trouver le code et la vidéo dans le résumé à la fin.
Ce que vous allez apprendre dans cet article
Dans chaque cycle de vie de projet, vient le moment de le publier, et ce n'est pas toujours évident de savoir comment faire. L'environnement de production est différent de celui de développement, et les utilisateurs ne prendront pas de mesures supplémentaires pour l'exécuter. La plupart des applications web consomment une sorte d'API, et souvent, elles sont hébergées sur un serveur différent.
Dans ce cas, en tant que développeur, nous devons résoudre les problèmes de partage de ressources cross-origin (CORS). Trop souvent, nous finissons par construire un backend même si ce n'est pas nécessaire. Je crois que les développeurs devraient garder leurs applications simples et supprimer toutes les pièces redondantes.
Dans cet article, j'aimerais vous montrer comment je prépare mes applications React pour les déployer en production.
Je pourrais construire une application React triviale, mais ce ne serait pas très utile. J'ai donc décidé de connecter mon application à une API réelle fournie par la FED de St. Louis. L'API nécessite une clé d'accès pour récupérer les données, et les endpoints sont protégés contre les requêtes cross-domain - aucune application web externe ne pourra consommer directement les données.
À noter : Si votre application repose sur le rendering côté serveur, ce n'est pas la bonne stratégie de déploiement. Vous pouvez vous en inspirer, mais vous aurez toujours besoin d'une sorte de backend.
Prérequis
Il est crucial d'avoir quelques connaissances de base sur la construction d'applications React. Vous devriez également connaître quelques fondamentaux de Docker avant de suivre les instructions de cet article.
Si vous avez manqué quelque chose, ne vous inquiétez pas ! Consultez simplement cet article et ce tutoriel YouTube sur FreeCodeCamp :
- Une introduction conviviale pour les débutants aux conteneurs, aux VM et à Docker par @iam_preethi
- Cours accéléré sur Create React App
Comment construire une application React d'exemple
J'ai démarré une application web simple en utilisant create-react-app. Le seul travail de l'application est d'afficher un graphique linéaire avec une représentation du PIB des États-Unis.

L'application récupère les données uniquement à partir de l'API suivante :
https://api.stlouisfed.org/fred/series/observations?series_id=GDPCA&frequency=a&observation_start=1999-04-15&observation_end=2021-01-01&file_type=json&api_key=abcdefghijklmnopqrstuvwxyz123456
Voici les paramètres :
series_id- L'identifiant d'une série. LeGDPCAreprésente le "PIB réel".frequency- L'agrégation des données. Leareprésente annuel.observation_start- Le début de la période d'observation.observation_end- La fin de la période d'observation.file_type- Le format des données. Par défaut, c'estxml.api_key- La clé d'accès requise pour récupérer des données de cette API. Vous pouvez en demander une ici.
Vous pouvez trouver plus de détails dans la documentation.
La vie n'est pas toujours parfaite, et la conception de l'API n'est pas idéale. Elle nécessite que le développeur passe la clé d'accès et le format de sortie attendu des données en tant que paramètres d'URL.
Passer le format de sortie en tant que paramètre n'est pas un problème pour nous car cela n'ajoute que du bruit - mais la fuite de la clé API l'est. Imaginez si quelqu'un les intercepte et abuse de l'API pour effectuer une action interdite. Nous ne voulons pas prendre ce risque.
Supposons un instant que les clés API ne posent pas de problème. Pourtant, il n'est pas possible de tirer parti de cette API. L'API FRED est protégée contre les requêtes cross-domain, de sorte que nous obtiendrons les erreurs suivantes si nous essayons de l'appeler depuis un domaine externe :

De nombreux développeurs suggéreraient de construire un middleware (un backend) pour proxyfier les requêtes vers l'API et filtrer les données sensibles. Ils diraient qu'ils pourraient avoir besoin d'ajouter de nouvelles fonctionnalités à l'avenir, et dans une certaine mesure, c'est une approche équitable.
Mais je préfère construire mes applications de manière plus YAGNI (You Ain't Gonna Need It). Ainsi, je vais éviter de construire le backend jusqu'à ce que ce soit nécessaire - dans notre cas, je ne le construirai pas du tout.
Utilisons NGINX !
Je suis un grand fan de NGINX car il apporte de la simplicité. NGINX a tout ce dont vous avez besoin pour préparer un serveur web de qualité production, comme HTTP2, la compression, TLS, et bien d'autres fonctionnalités.
Le plus important est que nous pouvons réaliser tout cela en définissant quelques lignes de configuration. Jetez un coup d'œil au snippet ci-dessous :
...
http {
...
server {
...
location /api {
set $args $args&&file_type=json&api_key=abcdefghijklmnopqrstuvwxyz123456;
proxy_pass https://api.stlouisfed.org/fred/series;
}
}
}
Ces 4 lignes sont tout ce dont j'avais besoin pour cacher notre clé API et supprimer les erreurs CORS. Littéralement ! À partir de maintenant, toutes les requêtes HTTP vers /api seront proxyfiées vers l'API FRED, et seules nos applications pourront consommer l'API. Toutes les requêtes externes seront confrontées à des erreurs CORS.
Pour éviter l'encombrement, j'ai remplacé tout le contenu par défaut du fichier par
...(trois points). Vous pouvez trouver la version complète sur mon GitHub ou dans la vidéo (liens ci-dessous).
Et voici à quoi ressemble notre endpoint :
/api/observations?series_id=GDPCA&frequency=a&observation_start=1999-04-15&observation_end=2021-01-01
Nous n'avons pas besoin de passer les paramètres api_key ni file_type pour récupérer les données. Et personne ne peut lire la clé d'accès depuis l'URL, donc c'est sécurisé.

Docker aime NGINX
La manière la plus pratique de faire tourner NGINX dans le cloud est d'utiliser Docker. Pour cette partie, je suppose que vous savez ce qu'est Docker (mais si ce n'est pas le cas, veuillez lire l'article lié dans les prérequis).
Nous devons simplement créer un Dockerfile avec le contenu suivant :
FROM nginx
COPY container /
COPY build /usr/share/nginx/html
Et maintenant, seulement trois étapes supplémentaires sont nécessaires pour exécuter l'application FRED :
- Construire l'application React. Ce processus génère le répertoire
build/contenant les fichiers statiques. - Construire l'image Docker. Cela créera une image Docker exécutable.
- Publier l'image Docker dans un dépôt ou l'exécuter sur la machine locale.
Pour l'instant, essayons de l'exécuter sur notre machine.
$ yarn install
$ yarn build
$ docker build -t msokola/fred-app:latest .
$ docker run -p 8081:80 -it msokola/fred-app:latest
Le 8081 est un port sur votre machine. Cela signifie que l'application sera disponible sous l'URL suivante : http://localhost:8081.
Après avoir ouvert cette URL dans le navigateur, vous devriez voir des logs comme ceci dans votre terminal :
0.0.0.1 - - [11/Mar/2021:18:57:50 +0000] "GET / HTTP/1.1" 200 1556 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 11_2_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.192 Safari/537.36" "-"
...
0.0.0.1 - - [11/Mar/2021:18:57:51 +0000] "GET /api/observations?series_id=GDPCA&frequency=a&observation_start=1999-04-15&observation_end=2021-01-01 HTTP/1.1" 200 404 "http://localhost:8081/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 11_2_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.192 Safari/537.36" "-"
Faites attention à ces 200 car ils représentent le statut HTTP OK. Si vous voyez un 400 à côté de la requête API, cela signifie qu'il y a un problème avec votre clé API. Le 304 est également correct (cela signifie que les données ont été mises en cache).
Comment déployer le conteneur sur AWS
Le conteneur fonctionne, nous pouvons donc le déployer. Dans cette partie de l'article, je vais vous montrer comment exécuter votre application dans Amazon Web Services (AWS).
AWS est l'une des plateformes cloud les plus populaires. Si vous souhaitez utiliser Microsoft Azure ou une autre plateforme, les étapes seront similaires mais la syntaxe des commandes sera différente.
À noter : J'ai enregistré une vidéo YouTube afin que vous puissiez me regarder parcourir le processus de déploiement complet. Si vous êtes bloqué ou rencontrez des problèmes, vous pouvez vérifier si nous avons les mêmes résultats à chaque étape. Si vous souhaitez regarder la vidéo, cliquez ici ou vous pouvez la trouver intégrée dans le Résumé ci-dessous.
1. Installer les outils AWS CLI
Avant de commencer, vous devrez installer les outils AWS CLI, afin de pouvoir invoquer des commandes sur votre cloud.
AWS propose des assistants d'installation pour tous les systèmes d'exploitation, je vais donc sauter cette section. Après une installation réussie, vous devez vous connecter en tapant la commande suivante :
$ aws configure
AWS Access Key ID [None]: AKIAIOSFODNN7EXAMPLE
AWS Secret Access Key [None]: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
Default region name [None]: us-east-2
Default output format [None]: json
Pour générer des clés d'accès, vous devez vous connecter à votre console AWS. Là, cliquez sur votre nom d'utilisateur, et sélectionnez "My Security Credentials".

2. Créer un nouveau Elastic Container Registry (ECR)
Une fois les outils CLI configurés, nous devrons créer un espace où nous pourrons stocker les exécutables de notre application. Nous utilisons Docker, donc nos exécutables seront des images Docker que nous exécuterons sur des machines virtuelles.
AWS offre un service dédié pour stocker les images appelé Elastic Container Registry. La commande suivante va en créer un pour nous :
aws ecr create-repository --repository-name react-to-aws --region us-east-2
Voici les paramètres :
ecr- L'acronyme de "Elastic Container Registry".repository-name- Le nom de notre registre. Gardez à l'esprit que nous ferons référence à ce nom plus tard.region- Le code de la région. Vous pouvez trouver une région proche de votre emplacement pour réduire la latence. Voici une liste de toutes les régions.
Vous pouvez trouver plus de détails dans la documentation.
Et voici la sortie attendue :
{
"repository": {
"repositoryArn": "arn:aws:ecr:us-east-2:1234567890:repository/react-to-aws2",
"registryId": "1234567890",
"repositoryName": "react-to-aws",
"repositoryUri": "1234567890.dkr.ecr.us-east-2.amazonaws.com/react-to-aws2",
"createdAt": "2021-03-16T22:50:23+04:00",
"imageTagMutability": "MUTABLE",
"imageScanningConfiguration": {
"scanOnPush": false
},
"encryptionConfiguration": {
"encryptionType": "AES256"
}
}
}
3. Pousser les images Docker dans le cloud
Dans cette étape, nous allons pousser nos images Docker dans le cloud. Nous pouvons le faire en copiant les commandes de poussée depuis notre console AWS.
Ouvrons la Console AWS dans le navigateur, et cliquons sur Elastic Container Registry dans la liste "All Services - Containers". Si vous n'avez pas changé votre région, vous pouvez simplement cliquer ici. Vous allez voir la liste complète de vos dépôts :

Maintenant, vous devez sélectionner le dépôt react-to-aws, puis "View push commands" dans le menu (marqué avec des cercles rouges dans l'image ci-dessus). Vous allez voir la fenêtre suivante :

Vous devez copier toutes les commandes de la modale dans votre terminal. Ne copiez pas les commandes du snippet ci-dessous car cela ne fonctionnera pas.
$ aws ecr get-login-password --region us-east-2 | docker login --username AWS --password-stdin 123456789.dkr.ecr.us-east-2.amazonaws.com
Login Succeeded
$ docker build -t react-to-aws .
[+] Building 0.6s (8/8) FINISHED
...
$ docker tag react-to-aws:latest 123465789.dkr.ecr.us-east-2.amazonaws.com/react-to-aws:latest
$ docker push 123456789.dkr.ecr.us-east-2.amazonaws.com/react-to-aws:latest
The push refers to repository [123456789.dkr.ecr.us-east-2.amazonaws.com/react-to-aws:latest]
...
latest: digest: sha256:3921262a91fd85d2fccab1d7dbe7adcff84f405a3dd9c0e510a20d744e6c3f74 size: 1988
Maintenant, vous pouvez fermer la modale et cliquer sur le nom du dépôt (react-to-aws) pour parcourir la liste des images disponibles. Vous devriez voir l'écran suivant :

Votre application est dans le dépôt, prête pour le déploiement ! Maintenant, cliquez sur "Copy URI" et gardez le contenu de votre presse-papiers (collez-le dans un bloc-notes ou un fichier texte), car nous en aurons besoin pour l'exécuter !
4. Configurer l'application
Notre image est disponible dans le cloud, nous devons donc maintenant la configurer.
Les machines virtuelles ne savent pas comment exécuter votre image pour s'assurer qu'elle fonctionne bien. Nous devons définir certaines instructions telles que les ports ouverts, les variables d'environnement, etc. AWS appelle cela la définition de tâche.
Ouvrez la Console AWS, et cliquez sur Elastic Container Service (ECS) dans la liste "All Services - Containers". Si vous n'avez pas changé votre région, vous pouvez cliquer ici.
Maintenant, sélectionnez Task Definitions, et cliquez sur "Create new Task Definition" comme indiqué dans l'image ci-dessous :

Nous avons deux options pour exécuter notre tâche : FARGATE et EC2. Choisissez FARGATE, et cliquez sur "Next step".

Dans l'étape suivante, vous devez remplir le formulaire avec les valeurs suivantes :
- Task Definition Name -
react-to-aws-task. - Task Role -
none. - Task memory (GB) -
0.5GB(le plus petit). - Task CPU (vCPU) -
0.25 vCPU(le plus petit).
Une fois que vous avez atteint la section "Container Definitions", cliquez sur "Add container" :

Remplissez le formulaire avec les valeurs suivantes :
- Container Name -
react-to-aws. - Image - L'URI de l'étape 4. Vous l'avez collé quelque part.
- Memory Limits (MiB)-
Soft limit128. - Port mappings -
80- le port HTTP.
Les autres options ne sont pas pertinentes pour nous. Maintenant, cliquez sur le bouton "Add" pour ajouter un conteneur, et terminez la définition de la tâche en cliquant sur Create. Vous devriez voir l'écran suivant, et cliquez sur "View task definition".

5. Exécutons-le !
Enfin, nous pouvons créer un cluster, afin de pouvoir exécuter notre application dans le cloud. Vous devez sélectionner "Clusters" dans le menu de gauche, et "Create Cluster". Comme montré dans l'image ci-dessous :

Maintenant, nous avons trois options : Networking only, EC2 Linux + Networking, et EC2 Windows + Networking. Choisissez la première - Networking only, et cliquez sur "Next step". Vous devriez voir l'écran suivant :

Entrez le nom du cluster react-to-aws, et cliquez sur le bouton "Create". Vous devriez voir un statut de lancement réussi. Cela ressemble à l'écran que nous avons obtenu une fois notre définition de tâche créée. Maintenant, cliquez sur "View Cluster".

Maintenant, vous devez cliquer sur l'onglet "Tasks", et cliquer sur "Run new Task". Félicitations ! Vous avez atteint le tout dernier formulaire à remplir :)

Remplissez le formulaire avec les valeurs suivantes :
- Launch type -
FARGATE. - Cluster VPC - Le premier.
- Subnet - Le premier.
Gardez les autres valeurs telles quelles, et cliquez sur le bouton "Run task". Vous devriez voir l'écran suivant :

Nous devrons attendre environ une minute jusqu'à ce que le "Last status" passe à RUNNING. Veuillez noter que vous devez cliquer sur le bouton "Refresh" pour actualiser la liste. Une fois que le statut de la tâche est en cours d'exécution, cliquez sur le nom de la tâche.

Dans la section "Network", vous trouverez l'IP publique de votre conteneur. Vous pouvez l'ouvrir dans votre navigateur, et vous verrez votre application.
Résumé
Si vous êtes au début de votre carrière, vous n'avez peut-être jamais déployé une application vous-même. Mais il est bon d'apprendre cette compétence, car un jour vous en aurez besoin.
Chaque projet doit faire face aux utilisateurs, sinon il n'aura aucune chance de réussir et ne se rentabilisera jamais.
"Un navire dans le port est en sécurité — mais ce n'est pas pour cela que les navires sont construits." — John A. Shedd
Le processus de configuration est un peu fastidieux, mais la bonne nouvelle est que vous n'avez besoin de le faire qu'une seule fois.
Après avoir tout configuré, vos prochains déploiements seront plus simples. Vous n'avez besoin que de pousser la nouvelle image et de redémarrer la tâche pour déployer une nouvelle version de votre application.
Si vous êtes intéressé à approfondir AWS, FreeCodeCamp offre un tutoriel gratuit (~5 heures).
Vous pouvez trouver un screencast de ce tutoriel (17 minutes) sur ma chaîne YouTube. Je suis au tout début de mon parcours YouTube - au moins une fois par semaine, je télécharge une vidéo sur la programmation. Cela signifierait beaucoup pour moi si vous regardiez mon screencast, vous abonniez et cliquiez sur le bouton like :)
Vous pouvez trouver tout le code dans ce dépôt GitHub : https://github.com/mateuszsokola/react-to-aws
Vous pouvez m'envoyer un message direct sur Twitter : @msokola
C'est tout pour aujourd'hui ! J'espère que vous avez aimé et que vous passez une excellente journée :)
_Photo par [Unsplash](https://unsplash.com/@vidarnm?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Vidar Nordli-Mathisen sur <a href="https://www.freecodecamp.org/news/s/photos/ship-storm?utm_source=unsplash&utm_medium=referral&utmcontent=creditCopyText)