LAB : Livraison continue d’image Docker sur Harbor avec Jenkins#
Présentation#
Objectifs:#
- Livraison continue d'une application flask-app avec Harbor et Jenkins
- Mise en place pipeline de livraison continue pour une applicartion flask(build, test, push, run)
Prérequis#
- Connaissance de Docker et GIT
- Instance docker fonctionnel
- Editeur de code
- Utilitaire installé sur la machine: git
- Avoir un proxy nginx fonctionnel (voir lab deploy reverse proxy sur la section 03-conteneurisation)
- Avoir un jenkins de fonctionnel voir lab du stage 6
Jenkins sur Docker - Avoir Slack de fonctionnel et pret à accueillir des notifications depuis jenkins (voir lab du stage 6
Integration Jenkins & slack) - Avoir ngrok d'activé pour pouvoir déclencher des pipelines via webhook Github, voir lab du stage 6
Jenkins Webhook - Avoir un harbor fonctionnel, voir lab précèdent dans ce meme stage
- Avoir un sonarqube de fonctionnel, voir labs stage 07
Déroulement du Lab#
Etape 1 : Création d'un repo Github privé pour hébergement de l'application flask-app#
Dans cette étape, nous allons créer un nouveau repo github privé pour héberger notre code flask-app qu'on va récupèrer depuis le repo habituel des labs de lecloudfacile
- Créer un nouveau repo Github privé nommé
flask-app
(voir Etape 1 de ce lab pour créer un nouveau repo github privé --> https://devopstraining.lecloudfacile.com/stage06/03-pipeline-multibranch/)
- Récupèration du code source
Depuis votre terminal, récupèrer le code source de flask-app
git clone https://github.com/wingufactory/lecloudfacile-devops-labs.git
- Se rendre dans le dossier flask-app-deployment
cd lecloudfacile-devops-labs/flask-app-deployment
- Pousser le contenu dans le repo Github privé créé
git init
git add .
git commit -m "first commit"
git branch -M main
git remote add origin https://github.com/<nom utilisateur>/flask-app.git
git push -u origin main
- Créer une branche dev et la pousser sur Github
git branch dev
git push origin dev
- Se rendre sur Github et vérifier que les fichiers sont bien présents et que les deux branches (
mainetdev) sont bien présentes


Etape 2 : Configuration coté Harbor#
Dans cette étape on va créer un projet (comme fait sur le lab précèdent) afin d'héberger de façon privé nos images docker flask-app
- Se rendre sur l'interface Harbor -->
http://registry.lcf.io - Créer un projet avec comme nom
flask-app

- Activer le scan automatique avec trivy sur l'ensemble du projet

Etape 3 : Création d'un nouveau agent Docker Jenkins#
Dans cette étape on va créer un nouveau Agent Jenkins Cloud de type Docker en partant d'une nouvelle image Docker qui va intégrer tous les pré-requis nécessaires (tels que python, trivy, ...) pour pouvoir builder, tester et faire tourner notre application flask-app
- Tout d'abord, builder la nouvelle image Docker pour ce nouvel agent Jenkins et le pousser sur DockerHub
Créer un nouveau fichier Dockerfile (dans un autre répertoire autre que celui contenant votre code flask-app) et y mettre ce contenu :
# Base officielle Jenkins inbound agent avec JDK 21
FROM jenkins/inbound-agent:latest-jdk21
USER root
# Installer Docker CLI, Git, Curl, etc.
RUN apt-get update && apt-get install -y --no-install-recommends \
python3 python3-pip \
git \
curl \
docker.io \
unzip \
jq \
ca-certificates \
lsb-release \
gnupg \
&& rm -rf /var/lib/apt/lists/*
# Installer les outils Python
RUN pip3 install --no-cache-dir --upgrade pip --break-system-packages && \
pip3 install --break-system-packages pytest coverage
# Installer Trivy (scanner de vulnérabilités)
ENV TRIVY_VERSION=0.50.0
RUN curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin v${TRIVY_VERSION}
# Revenir à l'utilisateur Jenkins pour les jobs
USER jenkins
# Dossier de travail par défaut
WORKDIR /home/jenkins
Ensuite, toujours en ligne de terminal, se connecter à Dockerhub avec son nom d'utilisateur et Token
echo "<token dockerhub>" |docker login -u <utilisateur-dockerhub> --password-stdin
Lancer le build de l'image Docker
docker build -t <utilisateur-dockerhub>/jenkins-agent-python:1.0.0 .
docker push <utilisateur-dockerhub>/jenkins-agent-python:1.0.0 .
- Ensuite créer le nouvel agent cloud Docker sur Jenkins
On va faire les memes manipulations que lors de l'étape 7 de ce lab --> https://devopstraining.lecloudfacile.com/stage06/01-jenkins-on-docker/
Les seules différences se situent ci-dessous :
--> Nom de l'agent cloud : Docker-in-Docker-flask

--> dans Docker Agent templates
--> Au niveau de label et nom renseigner : python-agent
--> Dans Docker Image, renseigner l'image poussée précèdemment sur Dockerhub : <utilisateur-dockerhub>/jenkins-agent-python:1.0.0


--> Dans container settings, renseigner frontend dans le champ Network pour mettre à nos conteneurs de s'intégrer dans le reseau docker où se trouve notre proxy nginx

Etape 4 : Création du pipeline de livraison continue sur Jenkins#
Dans cette étape on va créer deux jobs Jenkins de type pipeline pour accomplir la livraison continue de notre application flask-app :
-> Un pipeline de dev qui servira de build, test, push de notre image vers Harbor et run sur la dev. Ce pipeline se basera sur le fichier Jenkinsfile-dev présent dans notre repo Github
-> Un pipeline de prod qui se basera sur le fichier Jenkinsfile-prod pour lancer les étapes de déploiement de notre conteneur flask-app en production
- Pour une meilleure organisation de nos pipelines, on va d'abord créer un dossier Jenkins
Sur Jenkins, cliquer sur New item pour créer un nouveau job de type Folder avec comme nom flask-app

Ensuite dans Display Name, renseigner flask-app, mettre une description et cliquer sur Save

- Depuis le dossier flask-app, créer deux nouveaux jobs de type pipeline (un pour la dev et un autre pour la prod)
Cliquer sur New item et créer un un job avec le nom flask-app-dev

Dans la section pipeline, choisir Pipeline script from SCM, puis choisir Git. Ensuite renseigner l'url de votre repo Github hébergeant votre application flask-app et choisir le credential de connexion à Github comme fait lors des labs précèdents

Renseigner dev dans la partie Branches to Build et enfin dans Script Path renseigner le nom donné à notre fichier jenkins de dev : Jenkinsfile-dev

Enfin cliquer sur Save
On va procèder maintenant à la création du pipeline de prod dans le meme dossier flask-app en suivant le meme procèdé que la dev hormis quelques petites adaptations en plus. Ce pipeline va nous permettre de déclencher manuellement le déploiement en production en lui renseignant le numéro de la release à déployer
Créer un nouveau job de type pipeline avec le nom flask-app-prod
Dans la configuration du job, Cocher l'option This project is parameterized (Si vous etes en version française Ce job a des paramètres de build)

Ensuite cliquer sur Add Parameter --> String Parameter

--> dans le champ Name, renseigner RELEASE_TAG
--> dans le champ Default value, renseigner v1.0.0
--> dans la description, renseigner Version de la release à deployer en production

Ensuite comme avec le pipeline jenkins de dev, renseigner l'url de GIT, ensuite renseigner main dans la partie Branches to Build et enfin dans Script Path, renseigner : Jenkinsfile-prod


Etape 5 : Execution du pipeline de DEV#
Maintenant on va lancer notre pipeline pour l'environnement dev
-
Retourner au niveau du dossier
flask-appdans Jenkins, choisir le pipelineflask-app-devand lancer un nouveau build -
Vérifications
Vérifier que le job s'est terminé avec succès, que l'image Docker flaskapp-image avec le tag dev-snapshot est bien poussé sur harbor et que en local un conteneur du nom de flask-app-dev est bien lancé



Vérifier également que le résultat des analyses avec SonarQube sont bien présentes en se rendant sur quality.lcf.io

Enfin vérifier qu'on a bien reçu des notifications sur Slack
Etape 6 : Execution du pipeline de PROD#
Une fois que notre DEV est bien buildé, testé, déployé et validé, on va maintenant procèder au déploiement de notre application sur la PROD
- Pour cela, on va d'abord poser un tag sur Github pour spécifier qu'on a une version de notre application (une release) prete à etre déployée en production
Se rendre sur notre projet Github. S'assurer qu'on est bien sur la branche main et créer un tag en cliquant sur Tags

Ensuite cliquer sur Create a new release

Ensuite cliquer sur Choose a tag , et renseigner v1.0.0

Ensuite renseigner les informations ci-dessous et cliquer sur Publish release
--> Release title : v1.0.0
--> Description : Version 1.0.0 de mon application flask-app

Vérifier que la release a bien été créée

- Maintenant Lancer le pipeline de prod
flask-app-proddepuis le dossierflask-appsur Jenkins
Cliquer sur Build with Parameters

Renseigner le nom de la release qu'on a créé sur Github, ici v1.0.0 puis lancer le build

- Vérifications
Vérifier que le job s'est terminé avec succès, que l'image Docker flaskapp-image avec le tag v1.0.0 est bien poussé sur harbor et que en local un conteneur du nom de flask-app-prod est bien lancé



Vérifier également que les notifications arrivent bien sur Slack

Etape 7 : Mise à jour de la configuration du proxy#
Dans cette partie, on va mettre à jour la conf proxy pour accèder à notre application via des urls bien définies comme fait avec les labs précèdents.
Le répertoire lecloudfacile-devops-labs/nginx-proxy/conf.d/harbor contient un exemple de configuration du proxy pour la gestion des requêtes entrantes en ce qui concerne l'application flask-app. Nous pourrons la copier dans le répertoire lecloudfacile-devops-labs/nginx-proxy/conf.d avec la bonne extension .conf
cd lecloudfacile-devops-labs/nginx-proxy/
cp conf.d/flask-app/flask-app-dev.scratch.conf.template conf.d/flask-app-dev.conf
cp conf.d/flask-app/flask-app-prod.scratch.conf.template conf.d/flask-app-prod.conf
N.B : Vous pourrez faire un git pull pour récupèrer les dernières mises à jour du repo github si tel n'est pas déjà le cas
Il faudra ensuite recharger la configuration du proxy pour prendre en compte les modifications apportées.
docker exec -ti proxy nginx -s reload
Enfin, modifier le fichier /etc/hosts pour rajouter nos urls d'accès à flask-app
flask-app.dev.lcf.io pour accèder à flask-app de dev
flask-app.lcf.io pour accèder à falsk-app de prod
127.0.0.1 flask-app.lcf.io flask-app.dev.lcf.io registry.lcf.io quality.lcf.io jenkins.lcf.io localhost app.moodboard.xyz adminer.moodboard.xyz api.moodboard.xyz
Etape 8 : Accès aux urls flask-app#
- Accèder à la DEV via l'url -->
flask-app.dev.lcf.io

- Accèder à la PROD via l'url -->
flask-app.lcf.io
