Maximize Page
Tech & DevOps HubEspace Tech & DevOps: Explorez le monde du Dev, du Cloud et des outils DevOps à travers nos articles et discussions Explore the world of development, the cloud and DevOps tools

Jenkins on Ubuntu using Vagrant, VirtualBox and Ansible

Date de l'article:22-03-2026
Ansible Vagrant VirtualBox
Ce projet permet de déployer un serveur Jenkins sur Ubuntu 20.04 LTS (ubuntu/focal64) à l'aide de Vagrant, VirtualBox et Ansible.
Mise en place d'une infrastructure reproductible avec Vagrant, Ansible et Jenkins

Dans cet article, je présente une approche simple et reproductible pour déployer Jenkins à l'aide des principes de l'Infrastructure as Code

Infos projet :
Introduction

La mise en place d'un environnement CI/CD fiable est souvent plus complexe qu'il n'y paraît.
Les installations manuelles finissent souvent par générer des écarts de configuration, des environnements difficiles à reproduire et des déploiements plus fragiles.

L'objectif n'est pas seulement d'installer Jenkins, mais également de poser la première brique d'une stack CI/CD complète, pensée pour évoluer ensuite vers une intégration GitLab (ou autre) et un pipeline applicatif


Vision élargie: une stack CI/CD modulaire
Plutôt que de dépendre d'un seul outil, l'idée est de construire progressivement un écosystème cohérent, modulaire et facile à faire évoluer:
  • GitLab → gestion du code source et du registre d'images
  • Jenkins → orchestration des pipelines CI/CD
  • Docker → exécution et encapsulation des applications
  • Vagrant & VirtualBox → environnements isolés et reproductibles en local

À terme, cette base servira à valider un cas concret avec le micro-service Java Spring Boot Flashcards, qui permettra de tester les différentes étapes du pipeline.
Le choix des outils

Chaque outil a été retenu pour répondre à un besoin précis dans le cycle de vie CI/CD.

Vagrant
Vagrant permet de définir et de provisionner une machine virtuelle de manière déclarative. Cela apporte :
  • une infrastructure reproductible,
  • une mise en place rapide pour les nouveaux environnements,
  • une configuration cohérente entre les postes de travail.
VirtualBox

VirtualBox joue ici le rôle d'hyperviseur simple et gratuit, parfaitement adapté à un usage local de développement et de test.

Veiller à utiliser des versions compatibles de Vagrant et VirtualBox.

Vagrant et Docker Desktop :
Dans certains contextes, Docker Desktop pouvait entrer en conflit avec VirtualBox, car les deux solutions pouvaient chercher à utiliser les mêmes mécanismes de virtualisation. L'usage du backend WSL 2 a réduit ce type de problème.
Ansible
Ansible apporte la gestion de configuration à l'ensemble :
  • une infrastructure déclarative,
  • des exécutions idempotentes,
  • des playbooks lisibles et faciles à maintenir.
Docker
Jenkins est exécuté dans un conteneur Docker
  • L'environnement d'exécution est encapsulé,
  • Les mises à jour sont simplifiées,
  • La machine hôte reste plus propre.

Architecture

La configuration actuelle est volontairement simple, mais conçue pour évoluer. Une adresse IP privée statique est attribuée à la machine virtuelle afin de faciliter, par la suite, la communication avec d'autres services et d'autres VM.

Exécution du Vagrantfile

Une fois le script lancé, Vagrant crée la VM, applique la configuration réseau, lance le provisionnement Ansible et installe Jenkins dans un conteneur Docker.

La chaîne de provisionnement
  [ Machine du développeur ]
        ↓
  Machine virtuelle Vagrant
        ↓
  Provisionnement Ansible
        ↓
  Moteur Docker
        ↓
  Conteneur Jenkins

Vagrantfile
# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure("2") do |config|
  config.vm.box = "ubuntu/focal64"

  config.vm.hostname = "jenkins-vm"
  config.vm.network "private_network", ip: "192.168.56.10"
  config.vm.synced_folder ".", "/vagrant"

						   
  config.vm.provision "ansible_local" do |ansible|
    ansible.playbook = "/vagrant/ansible/install_jenkins.yml"
  end

  config.vm.provider "virtualbox" do |vb|
    vb.memory = "2048"
    vb.cpus = 2
  end
end
Détails de mise en œuvre
Configuration de Vagrant
La machine virtuelle repose sur Ubuntu 20.04 et dispose de :
  • un nom d'hôte fixe : jenkins-vm,
  • une adresse IP privée : 192.168.56.10,
  • un dossier synchronisé pour les fichiers du projet,
  • un provisionnement local via Ansible.

Allocation des ressources
  • 2 cœurs CPU,
  • 2 Go de RAM.

Le choix de ansible_local évite d'avoir à installer Ansible sur la machine hôte.

Décomposition du playbook Ansible
Le provisionnement est défini dans un seul playbook, découpé en étapes simples et lisibles.
- hosts: all
  become: yes

  tasks:
    - name: Update apt cache
      apt:
        update_cache: yes

    - name: Install prerequisites
      apt:
        name:
          - apt-transport-https
          - ca-certificates
          - curl
          - software-properties-common
          - python3-pip
        state: present

    - name: Install docker SDK for python
      pip:
        name: docker

    - name: Add Docker GPG key
      apt_key:
        url: https://download.docker.com/linux/ubuntu/gpg
        state: present

    - name: Update apt cache after adding Docker repo
      apt:
        update_cache: yes

    - name: Add Docker repository
      apt_repository:
        repo: deb https://download.docker.com/linux/ubuntu focal stable
        state: present

    - name: Install Docker
      apt:
        name: docker-ce
        state: present
        update_cache: yes

    - name: Add vagrant user to docker group
      user:
        name: vagrant
        groups: docker
        append: yes

    - name: Ensure Docker service is running
      service:
        name: docker
        state: started
        enabled: yes

    - name: Pull Jenkins LTS image
      docker_image:
        name: jenkins/jenkins
        tag: lts
        source: pull

    - name: Ensure /var/jenkins_home exists
      file:
        path: /var/jenkins_home
        state: directory
        owner: 1000
        group: 1000
        mode: '0755'

    - name: Run Jenkins container
      docker_container:
        name: jenkins
        image: jenkins/jenkins:lts
        state: started
        restart_policy: unless-stopped
        ports:
          - "8080:8080"
          - "50000:50000"
        volumes:
          - /var/jenkins_home:/var/jenkins_home

- hosts: all
  become: yes
Le playbook cible tous les hôtes de l'inventaire, avec des privilèges élevés
Les tasks
Préparation du système
- name: Update apt cache
  Mise à jour du cache des paquets
- name: Install prerequisites
  Installation des dépendances nécessaires:
  outils réseau, certificats et support Python
Garantit que le système est prêt pour la suite du déploiement
Installation de Docker
- name: Install docker SDK for python
- name: Add Docker GPG key
  Ajout de la clé officielle Docker.
- name: Add Docker repository
  Ajout du dépôt officiel Docker.
- name: Install Docker
  Installation de docker-ce.
L'installation de docker-ce permet d'éviter les paquets trop anciens fournis par la distribution
Gestion des droits
- name: Add vagrant user to docker group

L'utilisateur vagrant est ajouté au groupe Docker afin d'éviter l'usage systématique de sudo pour les commandes Docker.


Gestion du service Docker
- name: Ensure Docker service is running
  Le service est démarré et activé au boot.

Déploiement de Jenkins
- name: Pull Jenkins LTS image
L'image officielle Jenkins est utilisée avec les ports:
  • 8080 pour l'interface web,
  • 50000 pour la communication avec les agents.
- name: Ensure /var/jenkins_home exists
  Volume persistant: /var/jenkins_home.
Point clé : Cette persistance est essentielle pour conserver les configurations, les identifiants et les tâches Jenkins entre les redémarrages du conteneur.
- name: Run Jenkins container
  Le conteneur démarre et Jenkins devient disponible
  pour la configuration initiale.

Exécution de l'environnement
Depuis le dépôt GitHub:
git clone https://github.com/val7304/vagrant-jenkins.git
cd vagrant-jenkins
vagrant up
Une fois la machine virtuelle prête:
vagrant ssh
sudo docker exec jenkins cat /var/jenkins_home/secrets/initialAdminPassword

Jenkins est alors accessible à l'adresse http://192.168.56.10:8080.

À ce stade, j'obtiens :
un déploiement Jenkins automatisé
un environnement reproductible
une infrastructure décrite sous forme de code
une séparation entre l'hôte et l'environnement d'exécution

Ce premier socle représente déjà une nette amélioration nette, par rapport à une configuration manuelle.

Limites actuelles

Cette première version reste volontairement minimaliste. Elle pose les bases, mais plusieurs éléments restent à ajouter pour aller vers un environnement plus complet :

pas de HTTPS,
pas de proxy inverse,
pas de durcissement de l'authentification au-delà de la configuration Jenkins par défaut,
pas encore d'intégration entre Jenkins et le dépôt Git,
pas de pipeline applicatif défini pour le moment

Ces choix sont volontaires: ils permettent de garder cette première brique simple, lisible et facile à faire évoluer.

Cette base, accompagnée d'autres VMs servira ensuite à construire un environement complet


Prochaines étapes
Intégration de GitLab (SaaS)

Le code source sera hébergé sur GitLab.com, avec une configuration de webhooks pour déclencher Jenkins automatiquement.

Le tableau de suivi & mise à jour peut être consulté
       pour savoir ce qui est en cours ou prévu prochainement
L'architecture pourra ensuite évoluer vers Kubernetes ou d'autres solutions CI/CD managées selon les besoins du projet
Pipeline applicatif
À partir du projet Flashcards Spring Boot, qui contient déja de nombreux check, le pipeline pourra inclure :
  • le build Maven
  • les tests unitaires et d'intégration et l'analyse de qualité de code
  • le déploiement des dépendances sous forme de conteneurs,
  • la création de l'image Docker et le push vers la registry Gitlab
  • le déploiement final de l'application

Conclusions

Ce projet ne se limite pas au déploiement de Jenkins: il constitue une première brique vers une infrastructure reproductible, automatisée et évolutive.
En combinant Vagrant, Ansible et Docker, on obtient une base cohérente, portable et facile à maintenir.

L'étape suivante consistera à relier cette fondation à GitLab puis à intégrer une application réelle dans un pipeline complet, afin de transformer cette infrastructure en véritable support de livraison


Laissez-moi un commentaire

En postant un commentaire anonyme, vous adhérez automatiquement aux conditions d'utilisation du site.