Aller au contenu

TP : Conteneurisation de votre application Node.js et intégration dans GitLab CI

Ce TP a pour objectif de vous faire pratiquer la création d'images Docker pour une application Node.js et l'automatisation de sa construction dans GitLab CI

Objectifs du TP

  • Rédiger un Dockerfile pour une application Node.js
  • Optimiser une image Docker avec le multi-stage build
  • Comprendre et utiliser le Docker-in-Docker (DinD) ou Kaniko dans GitLab CI
  • Automatiser la création de l'image Docker dans le pipeline CI

Étape 1 : Création du Dockerfile basique

Nous allons créer une image Docker pour l'application Node.js développée au TP précédent

  1. À la racine de votre projet, créez un fichier nommé Dockerfile
  2. Utilisez l'image de base node:20-alpine (plus légère que l'image node standard)
  3. Définissez le répertoire de travail dans le conteneur avec WORKDIR (par exemple /usr/src/app)
  4. Copiez les fichiers package.json et package-lock.json ou yarn.lock
  5. Exécutez la commande d'installation des dépendances avec RUN npm ci
  6. Copiez le reste de votre code source dans le conteneur
  7. Exposez le port 3000 utilisé par votre application avec EXPOSE
  8. Définissez la commande de démarrage de votre application avec CMD
  9. N'oubliez pas d'ajouter un fichier .dockerignore contenant node_modules et .git pour ne pas alourdir le contexte de build

Étape 2 : Test de l'image localement (Optionnel)

Si vous disposez de Docker sur votre machine, vous pouvez vérifier que l'image se construit correctement avant de l'envoyer sur GitLab

  1. Construisez votre image en lui donnant un nom avec la commande docker build -t mon-app-node .
  2. Lancez un conteneur à partir de cette image avec docker run -p 3000:3000 mon-app-node
  3. Vérifiez dans votre navigateur que l'application répond sur http://localhost:3000

Étape 3 : Optimisation avec le Multi-stage Build

Pour avoir une image de production la plus légère possible, nous allons séparer l'étape de build de l'étape d'exécution

  1. Modifiez votre Dockerfile pour introduire une première étape nommée builder (ex: FROM node:20-alpine as builder)
  2. Dans cette étape builder, installez toutes les dépendances et générez les fichiers nécessaires au bon fonctionnement de votre application
  3. Créez une seconde étape en utilisant à nouveau node:20-alpine
  4. Définissez la variable d'environnement NODE_ENV à production
  5. Utilisez l'instruction COPY --from=builder pour ne récupérer que le code compilé et les dossiers nécessaires depuis l'étape précédente
  6. Observez la réduction de taille de l'image finale si vous la buildez localement

Étape 4 : Automatisation de la construction de l'image sur GitLab CI

Maintenant que le Dockerfile est prêt, nous allons demander à GitLab CI de construire notre image Docker à chaque modification du code

Nous utiliserons la méthode Kaniko qui est plus sécurisée et recommandée pour les environnements Kubernetes

  1. Dans votre fichier .gitlab-ci.yml, ajoutez une étape build_image (ou similaire) à vos stages existants
  2. Créez un job build_docker_image rattaché à cette nouvelle étape
  3. Utilisez l'image gcr.io/kaniko-project/executor:debug pour ce job avec l'entrypoint vide [""]
  4. Dans la section script, ajoutez la commande pour configurer l'authentification au registre GitLab via un echo vers /kaniko/.docker/config.json
  5. Lancez l'exécutable Kaniko pour construire l'image en lui fournissant le chemin du Dockerfile ($CI_PROJECT_DIR/Dockerfile), le contexte ($CI_PROJECT_DIR) et la destination (par exemple $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA)
  6. Commitez vos changements et vérifiez dans l'interface GitLab que le pipeline réussit et que l'image est bien poussée dans le Container Registry de votre projet

Étape 5 : Bonus - Utilisation de Docker-in-Docker (DinD)

Pour comprendre les différentes approches, vous pouvez essayer de configurer un autre job qui utilise DinD plutôt que Kaniko

  1. Créez un job build_dind dans .gitlab-ci.yml
  2. Utilisez l'image docker:latest et déclarez le service docker:dind
  3. Définissez la variable DOCKER_HOST à tcp://docker:2375
  4. Dans le script, connectez-vous au registre GitLab avec la commande docker login (utilisez les variables $CI_REGISTRY, $CI_REGISTRY_USER, $CI_REGISTRY_PASSWORD)
  5. Utilisez docker build et docker push de manière classique
  6. Comparez l'exécution de ce job avec celui utilisant Kaniko dans l'interface de GitLab CI

☕️ Si tu souhaites soutenir mon travail, tu peux m'offrir un café ici.