Ceci est une ancienne révision du document !


Script de mise à jour des projets Docker Compose

<code python> #!/bin/python3

#Appel des dépendances import subprocess import os from typing import Dict, List, Tuple, Optional

# Fonction qui affiche le message d'accueil def display_welcome_message():

  """
  Affiche un message d'accueil stylisé pour le script de mise à jour Docker Compose.
  """
  # Couleurs ANSI (fonctionnent dans la plupart des terminaux Linux)
  RESET = "\033[0m"
  GREEN = "\033[92m"
  BOLD = "\033[1m"
  # Message d'accueil personnalisé
  welcome_message = f"""
  {BOLD}{GREEN}🚀 Bienvenue dans le script de mise à jour de projets Docker Compose ! 🚀
  ℹ️  Mode d'emploi :
  
      1️⃣ Le paquet docker-compose-plugin doit être installé. La version legacy de docker-compose n'est pas compatible ❌
  
      2️⃣ Le service Docker doit être démarré normalement
      3️⃣ Les projets Docker Compose doivent être stockés dans le répertoire d'un des utilisateurs du système (/home/xxxx)
          Autrement, le chemin racine des projets peut être modifié à la ligne 179 de ce script (replacez le "/home")
      
      4️⃣ Le tag 'latest' doit également être mentionné dans la configuration des images à mettre à jour{RESET}
  """
  # Afficher le message
  print(welcome_message)

# Fonction pour récupérer les projets docker compose actif et le chemin de la configuration def find_docker_compose_projects(root_dir: str = “/”) → Dict[str, str]:

  """
  Cherche les fichiers docker-compose.yml dans les répertoires et vérifie les projets actifs.
  Retourne un dictionnaire {nom_projet: chemin_du_repertoire}.
  """
  projects = {}
  for dirpath, _, filenames in os.walk(root_dir):
      if "docker-compose.yml" in filenames:
          try:
              # Vérifier si le projet est en cours d'exécution
              result = subprocess.run(
                  ["docker", "compose", "-f", os.path.join(dirpath, "docker-compose.yml"), "ps", "--services", "--filter", "status=running"],
                  capture_output=True,
                  text=True,
              )
              services = result.stdout.strip().split("\n")
              if services and services[0]:
                  project_name = os.path.basename(dirpath)
                  projects[project_name] = dirpath
          except Exception as e:
              print(f"Erreur pour {dirpath}: {e}")
  return projects

# Fonction qui affiche les projets docker compose numérotés def display_project_menu(projects: Dict[str, str]) → None:

  """
  Affiche un menu numéroté des projets Docker Compose actifs.
  Args:
      projects: Dictionnaire {nom_projet: chemin_du_repertoire} retourné par `find_docker_compose_projects`.
  """
  if not projects:
      print("Aucun projet Docker Compose actif trouvé.")
      return
  print("\nProjets Docker Compose actifs :")
  for index, (project_name, project_path) in enumerate(projects.items(), start=1):
      print(f"{index}. {project_name} ({project_path})")

# Fonction qui demande à l'utilisateur de choisir un projet à mettre à jour et lancer la maj si OK def select_and_confirm_project(projects: Dict[str, str]) → Optional[Tuple[str, str]]:

  """
  Demande à l'utilisateur de sélectionner un projet Docker Compose par son numéro,
  vérifie la validité du choix, et demande confirmation.
  Args:
      projects: Dictionnaire {nom_projet: chemin_du_repertoire} des projets actifs.
  Returns:
      Un tuple (nom_projet, chemin) si la sélection est confirmée, sinon None.
  """
  if not projects:
      print("Aucun projet disponible.")
      return None
  try:
      # Afficher le menu
      display_project_menu(projects)
      # Demander la sélection
      selection = input("\nEntrez le numéro du projet à mettre à jour (ou 'q' pour quitter) : ")
      if selection.lower() == 'q':
          return None
      selected_index = int(selection) - 1
      project_list = list(projects.items())
      if selected_index < 0 or selected_index >= len(project_list):
          print("Numéro invalide.")
          return None
      selected_project = project_list[selected_index]
      # Demander confirmation
      confirm = input(f"\nVous avez sélectionné : {selected_project[0]} ({selected_project[1]})\nConfirmez-vous cette sélection ? (o/n) : ")
      if confirm.lower() == 'o':
          return selected_project
      else:
          print("Sélection annulée.")
          return None
  except ValueError:
      print("Veuillez entrer un numéro valide.")
      return None

# Fonction de mise à jour def update_docker_compose_project(project_name: str, project_path: str) → bool:

  """
  Met à jour un projet Docker Compose en exécutant `docker-compose pull` et `docker-compose up -d`.
  Args:
      project_name: Nom du projet (pour les logs).
      project_path: Chemin du répertoire contenant le fichier docker-compose.yml.
  Returns:
      bool: True si la mise à jour a réussi, False sinon.
  """
  try:
      print(f"\nMise à jour du projet {project_name} dans {project_path}...")
      # 1. Se déplacer dans le répertoire du projet
      os.chdir(project_path)
      # 2. Exécuter `docker-compose pull` pour récupérer les dernières images
      print("Récupération des dernières images...")
      pull_result = subprocess.run(
          ["docker", "compose", "pull"],
          capture_output=True,
          text=True,
          check=True
      )
      print(pull_result.stdout)
      # 3. Exécuter `docker-compose up -d` pour redémarrer les conteneurs
      print("Redémarrage des conteneurs...")
      up_result = subprocess.run(
          ["docker", "compose", "up", "-d"],
          capture_output=True,
          text=True,
          check=True
      )
      print(up_result.stdout)
      print(f"\nLe projet {project_name} a été mis à jour avec succès !")
      return True
  except subprocess.CalledProcessError as e:
      print(f"\n❌ Erreur lors de la mise à jour du projet {project_name} :")
      print(f"Commande échouée : {e.cmd}")
      print(f"Code de retour : {e.returncode}")
      print(f"Erreur : {e.stderr}")
      return False
  except Exception as e:
      print(f"\n❌ Erreur inattendue lors de la mise à jour du projet {project_name} : {e}")
      return False

# Fonction principale def main():

  display_welcome_message() # Message d'accueil
  projects = find_docker_compose_projects("/home")  # Remplacer "/home" par le chemin racine des projets Docker Compose
  if not projects:
      print("Aucun projet Docker Compose actif trouvé.")
      return
  selected = select_and_confirm_project(projects)
  if selected:
      project_name, project_path = selected
      success = update_docker_compose_project(project_name, project_path) # Executer la mise à jour

# Executer la fonction main() if name == “main”:

  main()

<code>