Retour aux articles

Automatisation du déploiement continu d'une application Spring Boot/Angular avec GitLab CI/CD et Docker

Automatisation du déploiement continu d'une application Spring Boot/Angular avec GitLab CI/CD et Docker | Laty Gueye Samba - Développeur Full Stack Dakar Sénégal, Expert Java Spring Boot Angular

Automatisation du déploiement continu d'une application Spring Boot/Angular avec GitLab CI/CD et Docker

Ce billet technique présente une approche pragmatique pour automatiser le build, la containerisation et le déploiement d'une application composée d'un backend Spring Boot et d'un frontend Angular. L'objectif est d'exposer une pipeline GitLab CI/CD robuste, sécurisée et reproductible, prête à pousser des images vers le registre GitLab et à déployer vers un environnement de production (hôte Docker ou Kubernetes).

Architecture et principes

L'architecture adoptée sépare clairement les responsabilités : compilation et tests pour chaque application (backend et frontend), production d'artefacts, construction d'images Docker optimisées et déploiement automatisé. La pipeline suit des étapes classiques : build, test, dockerize et deploy. Les secrets et credentials sont gérés via les variables CI/CD de GitLab.

Prérequis

Avant d'implémenter la pipeline, vérifier les éléments suivants :

- Un repository GitLab hébergeant les sources backend et frontend.
- GitLab Runner configuré (executor Docker recommandé) avec service docker:dind si la pipeline construit des images Docker.
- Variables CI/CD définies : CI_REGISTRY, CI_REGISTRY_USER, CI_REGISTRY_PASSWORD (ou utilisation de $CI_JOB_TOKEN), clés SSH pour déploiement via SSH ou credentials Kubernetes.

Exemples de Dockerfile

Dockerfile multi-stage pour Spring Boot (optimisé pour construire l'artefact et produire une image d'exécution minimaliste) :

FROM maven:3.8.6-openjdk-11 as builder WORKDIR /app COPY pom.xml . COPY src ./src RUN mvn -B -DskipTests package FROM openjdk:11-jre-slim ARG JAR_FILE=/app/target/*.jar COPY --from=builder /app/target/app.jar /opt/app/app.jar EXPOSE 8080 ENTRYPOINT ["java","-jar","/opt/app/app.jar"]

Dockerfile multi-stage pour Angular (build avec Node puis service statique via Nginx) :

FROM node:16-alpine as build WORKDIR /usr/src/app COPY package*.json ./ RUN npm ci COPY . . RUN npm run build -- --prod FROM nginx:alpine COPY --from=build /usr/src/app/dist/your-app-name /usr/share/nginx/html EXPOSE 80 CMD ["nginx","-g","daemon off;"]

Fichier .gitlab-ci.yml recommandé

Exemple de pipeline qui compile, archive, construit des images et pousse vers le registre GitLab. Le pipeline utilise le service docker:dind pour la phase de création d'images.

stages: - build - test - dockerize - deploy build_backend: image: maven:3.8.6-openjdk-11 stage: build script: - mvn -B -DskipTests package artifacts: paths: - backend/target/*.jar expire_in: 1 hour build_frontend: image: node:16-alpine stage: build script: - cd frontend - npm ci - npm run build -- --prod artifacts: paths: - frontend/dist expire_in: 1 hour docker_build: image: docker:24 services: - docker:24-dind stage: dockerize variables: DOCKER_TLS_CERTDIR: "" before_script: - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" "$CI_REGISTRY" script: - docker build -t "$CI_REGISTRY_IMAGE/backend:$CI_COMMIT_SHORT_SHA" -f backend/Dockerfile ./backend - docker build -t "$CI_REGISTRY_IMAGE/frontend:$CI_COMMIT_SHORT_SHA" -f frontend/Dockerfile ./frontend - docker push "$CI_REGISTRY_IMAGE/backend:$CI_COMMIT_SHORT_SHA" - docker push "$CI_REGISTRY_IMAGE/frontend:$CI_COMMIT_SHORT_SHA" only: - main - master deploy_production: image: bitnami/kubectl:1.27 stage: deploy script: - kubectl config set-cluster production --server="$K8S_API_URL" - kubectl config set-credentials gitlab --token="$K8S_TOKEN" - kubectl config set-context production --cluster=production --user=gitlab - kubectl config use-context production - kubectl set image deployment/backend backend="$CI_REGISTRY_IMAGE/backend:$CI_COMMIT_SHORT_SHA" --namespace=prod - kubectl set image deployment/frontend frontend="$CI_REGISTRY_IMAGE/frontend:$CI_COMMIT_SHORT_SHA" --namespace=prod only: - tags

Remarque : pour un déploiement sur un hôte Docker classique, remplacer la section deploy par un job utilisant SSH (clé privée stockée en variable protégée) et exécuter des commandes docker pull, docker-compose up -d ou des instructions d'update.

Meilleures pratiques et recommandations

- Utiliser des builds multi-stage pour réduire la taille des images et séparer les phases de compilation et d'exécution.
- Stocker les secrets dans les variables protégées GitLab CI/CD et limiter l'accès aux branches protégées.
- Employer des tags d'images immuables ($CI_COMMIT_SHORT_SHA) pour permettre le roll-back.
- Activer le scanning d'images et les scans de dépendances (SAST, DAST) proposés par GitLab pour améliorer la sécurité.
- Cacher les répertoires Maven et npm entre jobs si besoin pour accélérer les builds.

Validation et rollbacks

Inclure des jobs de tests unitaires et d'intégration dans les étapes de build réduit les risques. Pour le déploiement, une stratégie de mise à jour progressive (blue/green ou rolling update via Kubernetes) permet de minimiser les interruptions. L'utilisation de tags d'image immuables facilite le rollback en déployant une image antérieure connue.

Conclusion

La combinaison Spring Boot, Angular, Docker et GitLab CI/CD permet de construire une chaîne d'automatisation fiable et reproductible. En suivant des pratiques de containerisation optimisée, en gérant correctement les secrets et en définissant des pipelines modulaires, le développeur obtient un flux d'intégration et de déploiement continu sécurisé et maintenable.

À propos de l'auteur

Laty Gueye Samba est développeur Full Stack basé à Dakar, Sénégal. Spécialiste des écosystèmes Java / Spring Boot et Angular.

Contact : latygueyesamba@gmail.com  |  Dakar, Sénégal