Essayez Demo fr
  • en
  • fr
  • de
  • Produit
    • Plateforme
      • Aperçu de la plateformeFonctionnalités principales
      • Pourquoi eXoPrincipaux différenciateurs
      • InternationalisationConçue pour des environnements multilingues
      • MobileUtilisez votre plateforme sur appareils mobiles
    • Technologie
      • No codePersonnalisez facilement votre plateforme
      • ArchitectureAperçu de l’architecture de la plateforme
      • IntégrationsComment eXo s’intègre avec vos outils et systèmes
      • SécuritéComment eXo garantit la sécurité de vos données
      • Open sourceAperçu de notre plateforme open-source
  • Solutions
    • Communication
      • Intranet moderneConstruisez votre culture d’entreprise avec eXo
      • Gestion des connaissancesCentraliser et partager les connaissances de l’entreprise
      • Gestion des communautésGérez vos communautés
      • ExtranetImpliquez vos clients et partenaires
    • Collaboration
      • Réseau socialConnectez vos collaborateurs
      • Plateforme collaborativeRenforcer vos équipes
      • Portail collaborateurRenforcez vos équipes avec eXo
      • Engagement collaborateurStimulez l’engagement de vos collaborateurs
    • Pour
      • Secteur public
      • Réseaux
      • Education
      • Entreprises
  • Tarifs
  • Ressources
    • Centre de ressources
      • Etudes de cas
      • Fiches produit
      • Livres blancs
      • Vidéos
    • Guide de migration
      • Alternative à Microsoft 365
      • Alternative à Sharepoint
      • Alternative à Workplace from Meta
    • Blog
      • eXo Platform 6.5 est disponible !
      • eXo Platform lance sa communauté en ligne “la Tribe eXo”
      • eXo Platform et Schiever lauréats des cas d’or de la collaboration agile 2022
  • Communauté
    • CommunautéRejoignez notre communauté en ligne
    • TéléchargementLancer la plateforme eXo dans votre infrastructure
    • Code sourceCode source sur Github
    • FAQsQuestions sur les offres, logiciel et la communauté
    • API REST & DocumentationToutes les API REST disponibles dans eXo Platform
  • Entreprise
    • Clients
    • Partenaires
    • Services
    • A propos d’eXo
    • Contactez-nous
    • Actualités
  • Menu mobile
    • Tarifs
    • A propos d’eXo
    • Carrières
    • Centre de ressources
    • Blog
    • Contactez-nous
    • Essayez eXo
Plateforme
  • Aperçu de la plateforme Fonctionnalités principales
  • Pourquoi eXo Principaux différenciateurs
  • Internationalisation Conçue pour des environnements multilingues
  • Mobile Utilisez votre plateforme sur appareils mobiles
Technologie
  • No code Personnalisez facilement votre plateforme
  • Architecture Aperçu de l’architecture de la plateforme
  • Intégrations Comment eXo s’intègre avec vos outils et systèmes
  • Sécurité Comment eXo garantit la sécurité de vos données
  • Open source Aperçu de notre plateforme open-source
Communication
  • Intranet moderne Construisez votre culture d’entreprise avec eXo
  • Gestion des connaissances Centraliser et partager les connaissances de l’entreprise
  • Gestion des communautés Gérez vos communautés
  • Extranet Impliquez vos clients et partenaires
Collaboration
  • Réseau social Connectez vos collaborateurs
  • Plateforme collaborative Renforcer vos équipes
  • Portail collaborateur Renforcez vos équipes avec eXo
  • Engagement collaborateur Stimulez l’engagement de vos collaborateurs
Pour
  • Secteur public
  • Réseaux
  • Education
  • Entreprises
Centre de ressources
  • Etudes de cas
  • Fiches produit
  • Livres blancs
  • Vidéos
Guide de migration
  • Alternative à Microsoft 365
  • Alternative à Sharepoint
  • Alternative à Workplace from Meta
Blog
  • eXo Platform 6.5 est disponible !
  • eXo Platform lance sa communauté en ligne “la Tribe eXo”
  • eXo Platform et Schiever lauréats des cas d’or de la collaboration agile 2022
Communauté Rejoignez notre communauté en ligne
Téléchargement Lancer la plateforme eXo dans votre infrastructure
Code source Code source sur Github
FAQs Questions sur les offres, logiciel et la communauté
API REST & Documentation Toutes les API REST disponibles dans eXo Platform
Clients
Partenaires
Services
A propos d'eXo
Contactez-nous
Actualités
Tarifs
A propos d'eXo
Carrières
Centre de ressources
Blog
Contactez-nous
Essayez eXo
  1. Accueil
  2. Comment nous avons migré plus de 350 jobs Maven en Pipeline as code avec Jenkins 2 et Docker !

Comment nous avons migré plus de 350 jobs Maven en Pipeline as code avec Jenkins 2 et Docker !

Part1: Créer ses propres images Docker pour Jenkins

 

Il y a un an, chez eXo, nous avons pris la décision de construire tous nos projets dans des conteneurs Docker.

Dans cette série d’articles, nous vous expliquerons pourquoi et comment nous avons migré plus de 350 jobs Maven “standards” de Jenkins vers du Pipeline as code sur nos serveurs d’Intégration Continue avec Jenkins 2 et Docker.

C’est l’occasion de revenir sur les problèmes que nous avons rencontrés ainsi que les solutions apportées, et sur certaines bonnes pratiques autour des builds Maven / Gradle / Android dans des conteneurs Docker, le tout géré par du Pipeline as Code de Jenkins.

Comme toute migration technique importante, nous l’avons réalisée étape par étape. Les 3 grandes étapes ont été les suivantes:

  • Créer nos propres images CI Docker
  • Utiliser les plugins Jenkins Pipeline & Pipeline Docker
  • Générer tous les jobs Pipeline avec le Job DSL plugin

Le diagramme suivant représente le flux de travail lorsque toutes ces étapes sont effectuées:

Diagramme flux de travail avec étapes effectuéesDans cet article, nous détaillerons le contexte (pourquoi nous l’avons fait) et la première étape de cette migration sur la création de vos propres images CI Docker.

Qu’avions-nous à construire ?

eXo Platform est bâtie sur l’open-source et les standards ouverts. La plateforme est compatible avec la pile Java EE et s’appuie sur de nombreuses bibliothèques et composants open-source.

Mobile 1Mobile 2Desktop

Pour différentes raisons que nous allons vous expliquer, nous avons à gérer un grand nombre de builds sur nos serveurs d’Intégration Continue .

Composants d’eXo Platform et Add-ons

La première raison est que nous avons des dépôts git pour chacun des composants requis dans les livrables des distributions d’eXo Platform:

  • 25+ composants à construire
    • projets pour la plateforme (cf. diagramme ci-dessous)
    • projets Juzu…
  • De nombreux Add-ons
    • 15+ Add-ons supportés
    • 100+ Add-ons communautaires
  • Projets natifs pour le mobile
    • application Android
    • application iOS

Composants d’eXo Platform et Add-onsGit Workflow

Nous utilisons un workflow git basé sur un modèle de branches que tous les projets eXo doivent suivre:

  • develop : branche qui contient les derniers développements validés
  • feature/xxx : branches dédiées aux nouvelles fonctionnalités majeures (de nombreux commits), “xxx” correspond au nom de la fonctionnalité.
  • stable/xxx : branches utilisées pour faire des releases et pour corriger des problèmes sur des versions stables. “xxx” correspond au numéro de version stabilisée (e.g 1.0.x).
  • fix/xxx : branches dédiées aux correctifs qui doivent être ensuite intégrés dans la branche develop. Dans certains cas, ces corrections peuvent être aussi appliquées sur la branche stable.
  • integration/xxx : branches dédiées aux processus automatiques (exemple: processus de traductions…).
  • poc/xxx : branches dédiées à la réalisation de Proof of Concept (PoC)

Workflow git, modèle de branches pour suivre les projets eXoClients et versions d’eXo Platform

Depuis près de 15 ans maintenant, eXo a publié de nombreuses versions d’eXo Platform. Avec eXo Platform 5 en cours de développement et les versions que nous devons maintenir pour nos clients (eXo Platform 4.x: 4.0, 4.1, 4.2, 4.3, 4.4), nous avons ainsi plusieurs versions de nos environnements de build à gérer.
Actuellement, nous devons être en mesure de construire des projets avec les versions JDK6, JDK7 ou JDK8 et Maven 3.0, Maven 3.2 ou Maven 3.3. L’application Android native est construite par Gradle.

Vous vous souvenez comment créer un job Maven dans l’interface Jenkins ?

Même si Jenkins 2 a fait de nombreux efforts pour l’améliorer, il est toujours contraignant de créer de nouveaux jobs Maven via l’interface utilisateur, comme vous pouvez le voir ci-dessous:

comment créer un job Maven dans l’interface Jenkins

“Jenkins DSL et jobs Pipeline dans Docker à la rescousse !”

Pour ces différentes raisons, nous devions gérer beaucoup de jobs Maven à partir de l’interface utilisateur de Jenkins et maintenir nombre d’outils dans plusieurs versions (Maven, JDK …) sur les agents Jenkins ainsi que sur les postes de développeurs. Ce travail n’étant ni intéressant ni efficace, nous avons décidé de trouver une solution pour l’automatiser et le gérer différemment.

La technologie basée sur les conteneurs (Docker), combinée  à l’émergence d’outils d’automatisation dans Jenkins avec Pipeline et l’efficacité du DSL Job plugin, nous a alors semblé être la meilleure solution dans le contexte eXo.

1ere étape: Créer ses propres images Docker

Il est important de respecter les bonnes pratiques générales lorsque l’on créé nos propres images Docker, mais également quelques spécificités propres aux environnements de build.

Création de nos propres images DockerChoisir une image de base pour la distribution

Tous nos serveurs qui font office d’agents Jenkins sont gérés à partir de Puppet et sont basés sur la distribution Ubuntu. Nous avons donc décidé d’utiliser une image Docker plus légère basée sur cette distribution nommée baseimage-docker.

C’était un bon compromis entre une image très légère comme Alpine qui avait des problèmes liés à l’installation de JDK et l’image Docker officielle d’Ubuntu trop volumineuse.

FROM  phusion/baseimage:0.9.21
LABEL MAINTAINER “eXo Platform <docker@exoplatform.com>”

Définir la locale

Qui n’a jamais eu de tests en échec en raison de problèmes d’encodage ? Les tests passent  sur mon poste Linux, mais ils échouent sur le portable de mon collègue sous Windows !

Il est très fortement recommandé de définir une locale pour s’assurer que tous les développeurs auront le même comportement quel que soit leur environnement et que ce comportement sera conforme à la configuration du serveur d’Intégration Continue.

# Set the locale
RUN locale-gen en_US.UTF-8
ENV LANG en_US.UTF-8
ENV LANGUAGE en_US:en
ENV LC_ALL en_US.UTF-8

Créer un utilisateur CI dédié

“…take care of running your processes inside the containers as non-privileged users (i.e., non-root).” est l’une des recommandations les plus importantes du guide de sécurité Docker.

Dans le contexte de Jenkins, il est important de créer un utilisateur de CI dédié qui correspond à l’uid:gid de l’utilisateur utilisé par Jenkins sur vos agents.

# eXo CI User
ARG EXO_CI_USER_UID=13000
ENV EXO_CI_USER ciagent
ENV EXO_GROUP ciagent
...
# Create user and group with specific ids
RUN useradd --create-home --user-group -u ${EXO_CI_USER_UID} --shell /bin/bash ${EXO_CI_USER}

En effet, lorsque Jenkins exécute un job Pipeline avec Docker, il partage l’espace de travail du job ainsi que d’autres dossiers requis dans le conteneur Docker.

Par exemple, Jenkins exécute la commande suivante sur l’agent:

$ docker run -t -d -u 13000:13000
-v m2-cache-ecms-develop-ci:/home/ciagent/.m2/repository
-v /srv/ciagent/workspace/ecms-develop-ci:/srv/ciagent/workspace/ecms-develop-ci:rw
-v /srv/ciagent/workspace/ecms-develop-ci@tmp:/srv/ciagent/workspace/ecms-develop-ci@tmp:rw
...  -e ******** --entrypoint cat exoplatform/ci:jdk8-maven33

La création d’un utilisateur CI dédié vous évite ainsi les problèmes d’autorisations avec les volumes Docker.

Vous pouvez constater que nous définissons la variable EXO_CI_USER_UID avec l’instruction Docker ARG, elle aura son importance pour aider le développeur dans son environnement de de développement local et nous expliquerons pourquoi plus loin dans cette série d’articles.

ENTRYPOINT et CMD

Dans un Dockerfile, l’instruction ENTRYPOINT est une définition facultative pour la première partie de la commande à exécuter. Ainsi, les instructions ENTRYPOINT ou CMD, spécifiées dans votre Dockerfile, identifient l’exécutable par défaut pour l’image Docker. Mais la meilleure solution est de combiner ces deux instructions en utilisant CMD pour fournir des arguments par défaut pour le ENTRYPOINT.

Dans les versions antérieures du plugin Jenkins Docker Pipeline, Jenkins n’utilisait pas l’option –entrypoint lors du démarrage des conteneurs, la commande exécutée était alors:

$ docker run ... -e ******** exoplatform/ci:jdk8-maven33 cat

 

Dans ce cas, si votre image Docker utilisait l’instruction ENTRYPOINT pour déclarer une commande à exécuter, Jenkins ne pouvait pas utiliser votre image.

C’est pourquoi nous avons ajouté un script personnalisé dans nos images Docker, comme solution de contournement, afin de pouvoir exécuter Maven comme commande au démarrage du conteneur, mais également la commande cat et d’autres commandes à partir du moment où elles sont appelées via un chemin absolu:

Dockerfile

COPY docker-entrypoint.sh /usr/bin/docker-entrypoint
# Workaround to be able to execute others command than "mvn" as entrypoint
ENTRYPOINT ["/usr/bin/docker-entrypoint"]

CMD ["mvn", "--help"]

docker-entrypoint.sh

# Hack for Jenkins Pipeline: authorize cat without absolute path
if [[ "$1" == "/"* ]] || [[ "$1" == "cat" ]]; then
exec "$@"
fi

exec mvn "$@"

Depuis plusieurs versions du plugin Jenkins Docker Pipeline, ce problème a été corrigé pour utiliser l’option –entrypoint afin que l’instruction ENTRYPOINT soit toujours surchargée:

$ docker run ... -e ******** --entrypoint cat exoplatform/ci:jdk8-maven33

Utiliser l’héritage pour éviter la duplication de code

Nous avons créé et continuons à créer des images Docker pour couvrir toutes nos environnements de build, aujourd’hui cette liste contient notamment :

  • exoplatform/ci:jdk6-maven30
  • exoplatform/ci:jdk7-maven30
  • exoplatform/ci:jdk7-maven32
  • exoplatform/ci:jdk8-maven32
  • exoplatform/ci:jdk8-maven33
  • exoplatform/ci:jdk8-gradle2
  • …

Comme vous pouvez l’imaginer, il n’y a pas beaucoup de différences entre toutes ces images. Nous avons donc créé des images de base CI à plusieurs niveaux afin d’éviter autant que possible la duplication du code.

Le schéma ci-dessous montre comment ces images sont organisées :

Image de base CI sur docker avec héritage pour éviter la duplication de codeCi-dessous, il s’agit d’un extrait du Dockerfile pour l’image exoplatform/ci:jdk8-maven33 et vous pouvez voir qu’il n’y a que des instructions Docker liées à l’installation Maven car toutes les autres configurations ont été effectuées dans les images héritées (définir les paramètres régionaux, créer un utilisateur CI …).

FROM exoplatform/ci:jdk8

# CI Tools version
ENV MAVEN_VERSION 3.3.9
# Install Maven
RUN mkdir -p /usr/share/maven \
&& curl -fsSL http://archive.apache.org/dist/maven/maven-3/$MAVEN_VERSION/binaries/apache-maven-$MAVEN_VERSION-bin.tar.gz \
| tar xzf - -C /usr/share/maven --strip-components=1  \
&& ln -s /usr/share/maven/bin/mvn /usr/bin/mvn

…

# Custom configuration for Maven
ENV M2_HOME=/usr/share/maven
ENV MAVEN_OPTS="-Dmaven.repo.local=${HOME}/.m2/repository -XX:+UseConcMarkSweepGC -Xms1G -Xmx2G -XX:MaxMetaspaceSize=1G -Dcom.sun.media.jai.disableMediaLib=true -Djava.io.tmpdir=${EXO_CI_TMP_DIR} -Dmaven.artifact.threads=10 -Djava.awt.headless=true"
ENV PATH=$JAVA_HOME/bin:$M2_HOME/bin:$PATH

...

# Workaround to be able to execute others command than "mvn" as entrypoint
ENTRYPOINT ["/usr/bin/docker-entrypoint"]

CMD ["mvn", "--help"]

Comme expliqué précédemment dans cet article, nous avons combiné les instructions Docker ENTRYPOINT et CMD pour pouvoir exécuter toutes les commandes Maven dans ce conteneur facilement:

docker run ... -e ******** exoplatform/ci:jdk8-maven33 clean package

Et nous ajoutons également un script personnalisé, pour pouvoir exécuter la commande cat et d’autres commandes que Maven en donnant le chemin d’accès absolu à la commande:

docker run exoplatform/ci:jdk8-maven33 /bin/echo hello

Enfin, vous avez peut-être remarqué que nous avons déclaré les variables d’environnement M2_REPO et MAVEN_OPTS sous forme d’instructions Docker ENV avec des valeurs par défaut pour tous les paramètres importants. Elles peuvent être surchargées via l’option -e dans la commande de démarrage de docker.

Tester ses Images Docker

Comme pour tout autre type de code source, il est possible de créer des suites de tests pour ses images Docker et Dockerfiles. Pour les images Docker eXo CI, nous utilisons Goss à travers son wrapper dgoss.

  • Goss est un outil, basé sur YAML, pour valider la configuration d’un serveur
  • dgoss est une enveloppe autour de Goss qui vise à apporter la simplicité de Goss aux conteneurs Docker.

La première étape consiste à créer un fichier YAML pour décrire ce que vous souhaitez tester dans votre conteneur Docker. Il existe des exemples en ligne qui peuvent aider à créer ce fichier de configuration, mais cela peut également être généré par la ligne de commande de goss.

Par exemple, nous voulons vérifier que certains fichiers de configuration Maven existent dans le conteneur. Nous voulons également être sûr que la commande mvn –version est conforme aux versions Maven et JDK installées dans le container.

goss.yaml

file:
/home/ciagent/.m2/repository:
title: Validating the presence Maven repository folder
exists: true
/home/ciagent/.m2/settings.xml:
title: Validating the absence of eXo USER settings file
exists: false
/usr/share/maven/conf/settings.xml:
title: Validating the presence of eXo GLOBAL settings file
exists: true
package:
git:
installed: true
title: Check that git is installed
command:
mvn --version:
exit-status: 0
stdout:
- 3.3.9
- 1.8.0
- "Default locale: en_US, platform encoding: UTF-8"
stderr: []
timeout: 0

Ensuite, pour exécuter ces tests, il suffit simplement d’exécuter une ligne de commande via  dgoss:

dgoss run -it exoplatform/ci:jdk8-maven33 cat

 

CodeConclusion

Si vous êtes intéressés pour tester ou utiliser ces images Docker:

  • tous les Dockerfiles sont disponibles dans le projet GitHub dédié exo-docker/exo-ci
  • les images Docker peuvent être téléchargées à partir de l’organisation eXo sur le DockerHub

N’hésitez pas à nous faire part de vos commentaires ou à proposer vos idées.

Prochaine étape

Maintenant que nous avons créé nos propres Images Docker pour toutes nos environnements de build de l’intégration continue, nous vous expliquerons dans le prochain article (Partie 2), comment utiliser ces images dans un environnement de développement local quel que soit votre système d’exploitation.
Découvrez comment eXo Platform peut vous aider à transformer votre entreprise!

Maxime Greau

Je suis Software Factory Manager chez eXo. Je suis responsable des composants de la forge logicielle eXo (Jenkins CI, GitHub, Nexus, Sonar...) et du processus automatisé de Releases. J'aide les développeurs à utiliser au quotidien des processus de développement le plus simple et automatisé possible. Passioné par l'IT et l'Open Source, je contribue de différentes façons à des projets Open Source (participation à des conférences, écriture d'articles techniques...). J'ai également écrit un livre sur Apache Maven 3.

Une digital workplace tout-en-un centrée sur l'utilisateur pour des collaborateurs connectés et engagés

  • Fonctions
    • Communication Interne
    • Ressources humaines
    • Direction informatique
  • Produit
    • La Plateforme
    • Communiquer
    • Collaborer
    • Connaissances
    • Productivité
    • Open source
    • Integrations
    • Sécurité
  • Usages
    • Digital workplace
    • Logiciel collaboratif
    • Logiciel intranet
    • Gestion des connaissances
    • Plateforme d’engagement collaborateur
    • Réseau social d’entreprise
  • Guides
    • Qu’est ce q’un intranet ?
    • Plateforme collaborative
    • Guide Digital Workplace
    • La collaboration
    • Le travail collaboratif
    • Engagement collaborateur
    • Espace numérique de travail
  • Ressources
    • FAQs
    • Offres produit
    • Offres services
    • Centre de ressources
    • Clients
    • Partenaires
    • A propos de nous
  • Conditions Générales
  • Confidentialité
  • Mentions légales
  • Accessibilité
  • Plan du site
  • Contact
  • Facebook
  • Twitter
  • LinkedIn
wpDiscuz