React est une bibliothèque JavaScript populaire pour la construction d'interfaces utilisateur. Il permet de créer des applications web complexes et performantes avec une grande facilité. Cependant, pour déployer une application React en production, il est souvent nécessaire de la "dockeriser".
Docker est une plateforme qui permet de conteneuriser des applications, c'est-à-dire de les empaqueter avec toutes leurs dépendances dans un conteneur isolé qui peut être exécuté sur n'importe quel système d'exploitation supportant Docker.
Pour illustrer une application Node.js, prenons l'exemple disponible sur ce lien.
Un Dockerfile est un fichier texte sans format qui contient toutes les instructions commandées par l'utilisateur pour créer une image Docker. En d'autres termes, les Dockerfiles sont comme des scripts shell automatisés qui contiennent des commandes pour assembler une image Docker qui peut ensuite être utilisée pour créer des conteneurs Docker.
Les Dockerfiles commencent généralement par définir une image de base à partir de laquelle ils construisent. Cela est généralement une image de système d'exploitation qui est ensuite modifiée pour inclure des dépendances supplémentaires et des configurations nécessaires pour l'application que vous essayez de contenir.
Par exemple, si vous avez une application React, votre Dockerfile commencera probablement par une image de base qui a Node.js installé, car React est une bibliothèque JavaScript et nécessite Node.js pour le processus de construction et de déploiement.
En production, il est courant d'utiliser un serveur web pour servir les fichiers statiques générés par une application React. Nginx est un serveur web populaire pour cette tâche en raison de sa performance et de sa flexibilité. Dans le contexte d'une image Docker pour une application React, Nginx est généralement utilisé dans une étape distincte de l'image Docker appelée 'stage de production'. Après que l'application React a été construite dans une étape précédente, l'étape de production copie les fichiers statiques générés dans un répertoire servi par Nginx. L'image de base pour cette étape est une image Nginx, qui contient le serveur web Nginx préinstallé. La configuration de Nginx peut être personnalisée pour répondre aux besoins spécifiques de l'application, par exemple pour rediriger toutes les requêtes vers le fichier index.html pour prendre en charge le routage côté client de React
Les Dockerfiles utilisent une série de commandes pour définir et créer l'image Docker. Certaines des commandes les plus courantes incluent :
FROM
: Définit l'image de base à partir de laquelle vous construisezRUN
: Exécute une commande, utile pour installer des packages sur l'imageCOPY
et ADD
: Copie des fichiers de votre système de fichiers local dans l'image DockerWORKDIR
: Définit le répertoire de travail pour les instructions suivantesCMD
: Fournit des valeurs par défaut qui peuvent être exécutées lors de l'exécution de l'image DockerVoici un exemple de Dockerfile optimisé pour une application React :
# Définir des variables d'argument pour spécifier les versions de React, Node et Nginx à utiliser
ARG REACT_VERSION=17.0.2
ARG NODE_VERSION=12.2.0
ARG NGINX_VERSION=1.13.12-alpine
# Utiliser l'image Node spécifiée par la variable d'argument
FROM node:$NODE_VERSION as build-stage
# Définir une variable d'argument et une variable d'environnement pour l'URL de l'API React à utiliser.
ARG REACT_APP_API_URL
ENV REACT_APP_API_URL $REACT_APP_API_URL
# Stage 1: Installation des dépendances
# Créer et définir un répertoire pour l'application
WORKDIR /app
# Copier le package.json
COPY package*.json ./
# Installer les dépendances
RUN npm install
# Stage 2: Créer des ressources statiques
# Installer éventuellement une version de Reactjs au lieu d'utiliser la version par défaut
# Nous pouvons installer et mettre à jour le projet pour utiliser la version spécifique de Reactjs en fonction du Build Arg
RUN npm install react@${REACT_VERSION}
# Copier le reste du code de l'application
COPY . .
# Construire l'application
RUN npm run build
# Stage 3: Construire l'image finale
# Avoir Nginx pour servir les ressources statiques générés par l'étape précédente
FROM nginx:$NGINX_VERSION as production-stage
# Créer des répertoires dans le conteneur
RUN mkdir -p /usr/share/nginx/html
RUN mkdir -p /usr/share/nginx/html/acme
# Copier les dépendances et le code construit depuis l'image build-stage
COPY --from=build-stage /app/build /usr/share/nginx/html
# Copier les fichiers de configuration de Nginx dans le conteneur
COPY vhost.conf /etc/nginx/conf.d/
COPY mime.types /etc/nginx/mime.types
# Supprimer la configuration par défaut de Nginx
RUN rm /etc/nginx/conf.d/default.conf
# Configurer le fuseau horaire du conteneur
RUN rm /etc/localtime
RUN ln -s /usr/share/zoneinfo/Europe/Paris /etc/localtime
# Crée un fichier pour le challenge ACME (utilisé pour la validation de certificats SSL/TLS)
RUN echo "acme-test" > /usr/share/nginx/html/acme/index.html
# Exposer le port sur lequel l'application va s'exécuter
EXPOSE 80
# Définir la commande pour démarrer l'application
CMD ["nginx", "-g", "daemon off;"]
# Définit un point d'entrée vide, ce qui signifie que les commandes CMD seront exécutées directement
ENTRYPOINT [""]