[{"data":1,"prerenderedAt":26663},["ShallowReactive",2],{"articles-by-tag":3},[4,489,1056,2193,2596,2887,3281,3708,5863,6388,7461,8131,9558,10812,12397,12650,14503,14887,15015,16144,17927,19162,20174,20794,22358,24821,25909],{"id":5,"title":6,"author":7,"body":8,"date":472,"description":473,"extension":474,"image":475,"meta":476,"navigation":477,"path":478,"readingTime":479,"seo":480,"stem":481,"tags":482,"updatedAt":472,"__hash__":488},"posts/posts/maitriser-remote-desktop-viewer-guide-complet-pour-les-administrateurs-systeme.md","Maîtriser Remote Desktop Viewer : Guide complet pour les administrateurs système","RivoLink",{"type":9,"value":10,"toc":441},"minimark",[11,16,25,29,32,48,52,57,60,74,78,93,97,101,112,116,119,145,149,153,156,167,171,226,230,247,251,255,258,272,276,279,290,294,297,308,312,316,321,332,336,340,351,355,359,370,374,377,403,407,413,416,420,431,437],[12,13,15],"h2",{"id":14},"introduction","Introduction",[17,18,19,20,24],"p",{},"Remote Desktop Viewer est un outil essentiel pour les administrateurs système qui doivent gérer des serveurs et des postes de travail à distance. Dans ce guide complet sur ",[21,22,23],"strong",{},"Learn'in",", nous allons explorer toutes les fonctionnalités de cet outil et vous montrer comment l'utiliser efficacement et en toute sécurité.",[12,26,28],{"id":27},"quest-ce-que-remote-desktop-viewer","Qu'est-ce que Remote Desktop Viewer ?",[17,30,31],{},"Remote Desktop Viewer est une application qui permet de se connecter à un ordinateur distant et de le contrôler comme si vous étiez physiquement devant. C'est un outil indispensable pour :",[33,34,35,39,42,45],"ul",{},[36,37,38],"li",{},"La maintenance de serveurs",[36,40,41],{},"Le support technique à distance",[36,43,44],{},"La gestion de parcs informatiques",[36,46,47],{},"Le télétravail sécurisé",[12,49,51],{"id":50},"installation-et-configuration","Installation et configuration",[53,54,56],"h3",{"id":55},"prérequis-système","Prérequis système",[17,58,59],{},"Avant d'installer Remote Desktop Viewer, assurez-vous que votre système répond aux exigences suivantes :",[33,61,62,65,68,71],{},[36,63,64],{},"Windows 10 ou version ultérieure (ou équivalent Linux/Mac)",[36,66,67],{},"Connexion réseau stable",[36,69,70],{},"Droits d'administrateur pour l'installation",[36,72,73],{},"Port 3389 ouvert sur le pare-feu (pour RDP)",[53,75,77],{"id":76},"étapes-dinstallation","Étapes d'installation",[79,80,81,84,87,90],"ol",{},[36,82,83],{},"Téléchargez le logiciel depuis le site officiel",[36,85,86],{},"Exécutez le fichier d'installation",[36,88,89],{},"Suivez l'assistant de configuration",[36,91,92],{},"Configurez les paramètres réseau",[12,94,96],{"id":95},"configuration-de-la-connexion","Configuration de la connexion",[53,98,100],{"id":99},"paramètres-de-base","Paramètres de base",[102,103,108],"pre",{"className":104,"code":106,"language":107},[105],"language-text","Adresse du serveur : 192.168.1.100\nPort : 3389\nNom d'utilisateur : administrateur\nDomaine : WORKGROUP (si applicable)\n","text",[109,110,106],"code",{"__ignoreMap":111},"",[53,113,115],{"id":114},"options-de-connexion-avancées","Options de connexion avancées",[17,117,118],{},"Pour optimiser votre expérience, configurez les options suivantes :",[33,120,121,127,133,139],{},[36,122,123,126],{},[21,124,125],{},"Résolution d'écran"," : Adaptez-la à votre écran local",[36,128,129,132],{},[21,130,131],{},"Couleurs"," : 32 bits pour une meilleure qualité",[36,134,135,138],{},[21,136,137],{},"Expérience"," : Sélectionnez la vitesse de connexion",[36,140,141,144],{},[21,142,143],{},"Ressources locales"," : Partage de presse-papiers, imprimantes",[12,146,148],{"id":147},"bonnes-pratiques-de-sécurité","Bonnes pratiques de sécurité",[53,150,152],{"id":151},"authentification-forte","Authentification forte",[17,154,155],{},"Toujours utiliser :",[33,157,158,161,164],{},[36,159,160],{},"Des mots de passe complexes (12 caractères minimum)",[36,162,163],{},"L'authentification à deux facteurs (2FA) si disponible",[36,165,166],{},"Des comptes dédiés pour l'accès distant",[53,168,170],{"id":169},"configuration-du-pare-feu","Configuration du pare-feu",[102,172,176],{"className":173,"code":174,"language":175,"meta":111,"style":111},"language-bash shiki shiki-themes github-light github-dark","# Exemple de règle pare-feu Windows\nnetsh advfirewall firewall add rule name=\"RDP\" dir=in action=allow protocol=TCP localport=3389\n","bash",[109,177,178,187],{"__ignoreMap":111},[179,180,183],"span",{"class":181,"line":182},"line",1,[179,184,186],{"class":185},"sJ8bj","# Exemple de règle pare-feu Windows\n",[179,188,190,194,198,201,204,207,210,213,216,219,222],{"class":181,"line":189},2,[179,191,193],{"class":192},"sScJk","netsh",[179,195,197],{"class":196},"sZZnC"," advfirewall",[179,199,200],{"class":196}," firewall",[179,202,203],{"class":196}," add",[179,205,206],{"class":196}," rule",[179,208,209],{"class":196}," name=\"RDP\"",[179,211,212],{"class":196}," dir=in",[179,214,215],{"class":196}," action=allow",[179,217,218],{"class":196}," protocol=TCP",[179,220,221],{"class":196}," localport=",[179,223,225],{"class":224},"sj4cs","3389\n",[53,227,229],{"id":228},"recommandations-de-sécurité","Recommandations de sécurité",[33,231,232,235,238,241,244],{},[36,233,234],{},"Ne jamais exposer le port RDP directement sur Internet",[36,236,237],{},"Utiliser un VPN pour les connexions externes",[36,239,240],{},"Activer le Network Level Authentication (NLA)",[36,242,243],{},"Limiter les comptes autorisés à se connecter",[36,245,246],{},"Mettre à jour régulièrement le système",[12,248,250],{"id":249},"fonctionnalités-avancées","Fonctionnalités avancées",[53,252,254],{"id":253},"gestion-de-plusieurs-connexions","Gestion de plusieurs connexions",[17,256,257],{},"Remote Desktop Viewer permet de sauvegarder plusieurs profils de connexion :",[79,259,260,263,266,269],{},[36,261,262],{},"Cliquez sur \"Fichier\" > \"Nouvelle connexion\"",[36,264,265],{},"Entrez les paramètres du serveur",[36,267,268],{},"Sauvegardez avec un nom explicite",[36,270,271],{},"Organisez vos connexions par dossiers",[53,273,275],{"id":274},"transfert-de-fichiers","Transfert de fichiers",[17,277,278],{},"Pour transférer des fichiers entre votre poste et le serveur distant :",[33,280,281,284,287],{},[36,282,283],{},"Activez le partage de lecteurs locaux dans les options",[36,285,286],{},"Accédez aux lecteurs via \"Ce PC\" dans la session distante",[36,288,289],{},"Copiez-collez directement les fichiers",[53,291,293],{"id":292},"enregistrement-de-session","Enregistrement de session",[17,295,296],{},"Certaines versions permettent d'enregistrer les sessions pour :",[33,298,299,302,305],{},[36,300,301],{},"La formation des équipes",[36,303,304],{},"L'audit de sécurité",[36,306,307],{},"Le dépannage collaboratif",[12,309,311],{"id":310},"dépannage-courant","Dépannage courant",[53,313,315],{"id":314},"problème-connexion-refusée","Problème : Connexion refusée",[17,317,318],{},[21,319,320],{},"Solutions :",[33,322,323,326,329],{},[36,324,325],{},"Vérifiez que le service Bureau à distance est activé",[36,327,328],{},"Confirmez que le pare-feu autorise le port 3389",[36,330,331],{},"Assurez-vous que l'adresse IP est correcte",[53,333,335],{"id":334},"problème-lenteur-de-la-session","Problème : Lenteur de la session",[17,337,338],{},[21,339,320],{},[33,341,342,345,348],{},[36,343,344],{},"Réduisez la qualité graphique dans les options",[36,346,347],{},"Désactivez les effets visuels",[36,349,350],{},"Vérifiez la bande passante disponible",[53,352,354],{"id":353},"problème-déconnexions-fréquentes","Problème : Déconnexions fréquentes",[17,356,357],{},[21,358,320],{},[33,360,361,364,367],{},[36,362,363],{},"Augmentez le délai d'expiration de session",[36,365,366],{},"Vérifiez la stabilité du réseau",[36,368,369],{},"Mettez à jour les pilotes réseau",[12,371,373],{"id":372},"alternatives-à-remote-desktop-viewer","Alternatives à Remote Desktop Viewer",[17,375,376],{},"Selon vos besoins, d'autres solutions existent :",[33,378,379,385,391,397],{},[36,380,381,384],{},[21,382,383],{},"TeamViewer"," : Solution grand public avec fonctionnalités avancées",[36,386,387,390],{},[21,388,389],{},"AnyDesk"," : Léger et rapide pour les connexions occasionnelles",[36,392,393,396],{},[21,394,395],{},"VNC"," : Solution open-source multiplateforme",[36,398,399,402],{},[21,400,401],{},"SSH avec X11"," : Pour les administrateurs Linux avancés",[12,404,406],{"id":405},"conclusion","Conclusion",[17,408,409,410,412],{},"Remote Desktop Viewer reste un outil incontournable pour l'administration système à distance. En suivant les bonnes pratiques de sécurité présentées dans cet article ",[21,411,23],{},", vous pourrez gérer vos infrastructures efficacement tout en protégeant vos données.",[17,414,415],{},"N'oubliez pas que la sécurité doit toujours être votre priorité lors de la configuration de l'accès distant. Prenez le temps de bien configurer votre environnement avant de mettre en production.",[12,417,419],{"id":418},"ressources-complémentaires","Ressources complémentaires",[33,421,422,425,428],{},[36,423,424],{},"Documentation officielle Microsoft sur RDP",[36,426,427],{},"Guide de sécurisation des accès distants",[36,429,430],{},"Tutoriels vidéo sur la configuration avancée",[17,432,433,434,436],{},"Pour plus de contenus sur l'administration système, explorez les autres articles disponibles sur ",[21,435,23],{},".",[438,439,440],"style",{},"html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":111,"searchDepth":189,"depth":189,"links":442},[443,444,445,450,454,459,464,469,470,471],{"id":14,"depth":189,"text":15},{"id":27,"depth":189,"text":28},{"id":50,"depth":189,"text":51,"children":446},[447,449],{"id":55,"depth":448,"text":56},3,{"id":76,"depth":448,"text":77},{"id":95,"depth":189,"text":96,"children":451},[452,453],{"id":99,"depth":448,"text":100},{"id":114,"depth":448,"text":115},{"id":147,"depth":189,"text":148,"children":455},[456,457,458],{"id":151,"depth":448,"text":152},{"id":169,"depth":448,"text":170},{"id":228,"depth":448,"text":229},{"id":249,"depth":189,"text":250,"children":460},[461,462,463],{"id":253,"depth":448,"text":254},{"id":274,"depth":448,"text":275},{"id":292,"depth":448,"text":293},{"id":310,"depth":189,"text":311,"children":465},[466,467,468],{"id":314,"depth":448,"text":315},{"id":334,"depth":448,"text":335},{"id":353,"depth":448,"text":354},{"id":372,"depth":189,"text":373},{"id":405,"depth":189,"text":406},{"id":418,"depth":189,"text":419},"2026-04-19","Découvrez comment utiliser Remote Desktop Viewer pour gérer vos serveurs à distance. Guide pratique, astuces de sécurité et configuration pour administrateurs.","md","/images/posts/2026/04/maitriser-remote-desktop-viewer-guide-complet-pour-les-administrateurs-systeme.webp",{},true,"/posts/maitriser-remote-desktop-viewer-guide-complet-pour-les-administrateurs-systeme",null,{"title":6,"description":473},"posts/maitriser-remote-desktop-viewer-guide-complet-pour-les-administrateurs-systeme",[483,484,485,486,487],"remote-desktop","administration-systeme","windows-server","reseau","securite","-PhAiTo-_9Eeihebzw-v2uVpMVhCyKhxanOqJB6Hyic",{"id":490,"title":491,"author":492,"body":493,"date":1041,"description":1042,"extension":474,"image":1043,"meta":1044,"navigation":477,"path":1045,"readingTime":479,"seo":1046,"stem":1047,"tags":1048,"updatedAt":1041,"__hash__":1055},"posts/posts/installer-et-configurer-un-environnement-react-native-sur-ubuntu.md","Installer et configurer un environnement React Native sur Ubuntu","Koloina Tetra",{"type":9,"value":494,"toc":1029},[495,497,500,503,507,510,521,525,528,531,580,583,603,607,610,636,643,656,669,701,704,717,721,724,739,779,800,862,864,874,878,881,899,905,909,912,931,938,942,945,956,959,962,977,980,982,1010,1012,1015,1026],[12,496,15],{"id":14},[17,498,499],{},"React Native permet de développer des applications mobiles natives pour iOS et Android en utilisant JavaScript et React. Ce guide vous accompagne pas à pas dans l'installation et la configuration d'un environnement de développement React Native fonctionnel sur Ubuntu.",[17,501,502],{},"À la fin de ce tutoriel, vous serez capable de lancer votre première application React Native sur un émulateur Android ou un appareil physique.",[12,504,506],{"id":505},"prérequis","Prérequis",[17,508,509],{},"Avant de commencer, assurez-vous d'avoir les éléments suivants :",[33,511,512,515,518],{},[36,513,514],{},"Un système Ubuntu (20.04 ou supérieur recommandé)",[36,516,517],{},"Une connexion internet stable",[36,519,520],{},"Des droits d'administration (sudo)",[12,522,524],{"id":523},"étape-1-installation-de-nodejs-et-npm","Étape 1 : Installation de Node.js et npm",[17,526,527],{},"React Native nécessite Node.js. Il est recommandé d'utiliser une version LTS (Long Term Support).",[17,529,530],{},"Ouvrez un terminal et exécutez les commandes suivantes pour installer Node.js via le gestionnaire de paquets :",[102,532,534],{"className":173,"code":533,"language":175,"meta":111,"style":111},"curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash -\nsudo apt-get install -y nodejs\n",[109,535,536,563],{"__ignoreMap":111},[179,537,538,541,544,547,551,554,557,560],{"class":181,"line":182},[179,539,540],{"class":192},"curl",[179,542,543],{"class":224}," -fsSL",[179,545,546],{"class":196}," https://deb.nodesource.com/setup_lts.x",[179,548,550],{"class":549},"szBVR"," |",[179,552,553],{"class":192}," sudo",[179,555,556],{"class":224}," -E",[179,558,559],{"class":196}," bash",[179,561,562],{"class":196}," -\n",[179,564,565,568,571,574,577],{"class":181,"line":189},[179,566,567],{"class":192},"sudo",[179,569,570],{"class":196}," apt-get",[179,572,573],{"class":196}," install",[179,575,576],{"class":224}," -y",[179,578,579],{"class":196}," nodejs\n",[17,581,582],{},"Vérifiez l'installation :",[102,584,586],{"className":173,"code":585,"language":175,"meta":111,"style":111},"node -v\nnpm -v\n",[109,587,588,596],{"__ignoreMap":111},[179,589,590,593],{"class":181,"line":182},[179,591,592],{"class":192},"node",[179,594,595],{"class":224}," -v\n",[179,597,598,601],{"class":181,"line":189},[179,599,600],{"class":192},"npm",[179,602,595],{"class":224},[12,604,606],{"id":605},"étape-2-installation-du-java-development-kit-jdk","Étape 2 : Installation du Java Development Kit (JDK)",[17,608,609],{},"Android nécessite le JDK. La version 17 est recommandée pour les projets récents.",[102,611,613],{"className":173,"code":612,"language":175,"meta":111,"style":111},"sudo apt update\nsudo apt install openjdk-17-jdk\n",[109,614,615,625],{"__ignoreMap":111},[179,616,617,619,622],{"class":181,"line":182},[179,618,567],{"class":192},[179,620,621],{"class":196}," apt",[179,623,624],{"class":196}," update\n",[179,626,627,629,631,633],{"class":181,"line":189},[179,628,567],{"class":192},[179,630,621],{"class":196},[179,632,573],{"class":196},[179,634,635],{"class":196}," openjdk-17-jdk\n",[17,637,638,639,642],{},"Vérifiez l'installation et configurez la variable d'environnement ",[109,640,641],{},"JAVA_HOME"," :",[102,644,646],{"className":173,"code":645,"language":175,"meta":111,"style":111},"java -version\n",[109,647,648],{"__ignoreMap":111},[179,649,650,653],{"class":181,"line":182},[179,651,652],{"class":192},"java",[179,654,655],{"class":224}," -version\n",[17,657,658,659,661,662,665,666,642],{},"Pour définir ",[109,660,641],{}," de manière permanente, ajoutez les lignes suivantes à votre fichier ",[109,663,664],{},"~/.bashrc"," ou ",[109,667,668],{},"~/.zshrc",[102,670,672],{"className":173,"code":671,"language":175,"meta":111,"style":111},"export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64\nexport PATH=$JAVA_HOME/bin:$PATH\n",[109,673,674,689],{"__ignoreMap":111},[179,675,676,679,683,686],{"class":181,"line":182},[179,677,678],{"class":549},"export",[179,680,682],{"class":681},"sVt8B"," JAVA_HOME",[179,684,685],{"class":549},"=",[179,687,688],{"class":681},"/usr/lib/jvm/java-17-openjdk-amd64\n",[179,690,691,693,696,698],{"class":181,"line":189},[179,692,678],{"class":549},[179,694,695],{"class":681}," PATH",[179,697,685],{"class":549},[179,699,700],{"class":681},"$JAVA_HOME/bin:$PATH\n",[17,702,703],{},"Appliquez les changements :",[102,705,707],{"className":173,"code":706,"language":175,"meta":111,"style":111},"source ~/.bashrc\n",[109,708,709],{"__ignoreMap":111},[179,710,711,714],{"class":181,"line":182},[179,712,713],{"class":224},"source",[179,715,716],{"class":196}," ~/.bashrc\n",[12,718,720],{"id":719},"étape-3-installation-dandroid-studio","Étape 3 : Installation d'Android Studio",[17,722,723],{},"Android Studio inclut l'émulateur et les outils de build nécessaires.",[79,725,726,736],{},[36,727,728,729,436],{},"Téléchargez Android Studio depuis le ",[730,731,735],"a",{"href":732,"rel":733},"https://developer.android.com/studio",[734],"nofollow","site officiel",[36,737,738],{},"Extrayez l'archive et lancez l'installation :",[102,740,742],{"className":173,"code":741,"language":175,"meta":111,"style":111},"cd ~/Téléchargements\nunzip android-studio-*.zip\ncd android-studio/bin\n./studio.sh\n",[109,743,744,752,766,773],{"__ignoreMap":111},[179,745,746,749],{"class":181,"line":182},[179,747,748],{"class":224},"cd",[179,750,751],{"class":196}," ~/Téléchargements\n",[179,753,754,757,760,763],{"class":181,"line":189},[179,755,756],{"class":192},"unzip",[179,758,759],{"class":196}," android-studio-",[179,761,762],{"class":224},"*",[179,764,765],{"class":196},".zip\n",[179,767,768,770],{"class":181,"line":448},[179,769,748],{"class":224},[179,771,772],{"class":196}," android-studio/bin\n",[179,774,776],{"class":181,"line":775},4,[179,777,778],{"class":192},"./studio.sh\n",[79,780,781,795],{"start":448},[36,782,783,784],{},"Lors du premier lancement, suivez l'assistant d'installation. Assurez-vous d'installer :",[33,785,786,789,792],{},[36,787,788],{},"Android SDK",[36,790,791],{},"Android SDK Platform",[36,793,794],{},"Android Virtual Device (AVD)",[36,796,797,798,642],{},"Une fois installé, ajoutez les variables d'environnement. Éditez ",[109,799,664],{},[102,801,803],{"className":173,"code":802,"language":175,"meta":111,"style":111},"export ANDROID_HOME=$HOME/Android/Sdk\nexport PATH=$PATH:$ANDROID_HOME/emulator\nexport PATH=$PATH:$ANDROID_HOME/platform-tools\nexport PATH=$PATH:$ANDROID_HOME/tools\nexport PATH=$PATH:$ANDROID_HOME/tools/bin\n",[109,804,805,817,828,839,850],{"__ignoreMap":111},[179,806,807,809,812,814],{"class":181,"line":182},[179,808,678],{"class":549},[179,810,811],{"class":681}," ANDROID_HOME",[179,813,685],{"class":549},[179,815,816],{"class":681},"$HOME/Android/Sdk\n",[179,818,819,821,823,825],{"class":181,"line":189},[179,820,678],{"class":549},[179,822,695],{"class":681},[179,824,685],{"class":549},[179,826,827],{"class":681},"$PATH:$ANDROID_HOME/emulator\n",[179,829,830,832,834,836],{"class":181,"line":448},[179,831,678],{"class":549},[179,833,695],{"class":681},[179,835,685],{"class":549},[179,837,838],{"class":681},"$PATH:$ANDROID_HOME/platform-tools\n",[179,840,841,843,845,847],{"class":181,"line":775},[179,842,678],{"class":549},[179,844,695],{"class":681},[179,846,685],{"class":549},[179,848,849],{"class":681},"$PATH:$ANDROID_HOME/tools\n",[179,851,853,855,857,859],{"class":181,"line":852},5,[179,854,678],{"class":549},[179,856,695],{"class":681},[179,858,685],{"class":549},[179,860,861],{"class":681},"$PATH:$ANDROID_HOME/tools/bin\n",[17,863,703],{},[102,865,866],{"className":173,"code":706,"language":175,"meta":111,"style":111},[109,867,868],{"__ignoreMap":111},[179,869,870,872],{"class":181,"line":182},[179,871,713],{"class":224},[179,873,716],{"class":196},[12,875,877],{"id":876},"étape-4-installation-des-dépendances-supplémentaires","Étape 4 : Installation des dépendances supplémentaires",[17,879,880],{},"React Native CLI nécessite quelques outils supplémentaires pour compiler le code natif :",[102,882,884],{"className":173,"code":883,"language":175,"meta":111,"style":111},"sudo apt install -y watchman\n",[109,885,886],{"__ignoreMap":111},[179,887,888,890,892,894,896],{"class":181,"line":182},[179,889,567],{"class":192},[179,891,621],{"class":196},[179,893,573],{"class":196},[179,895,576],{"class":224},[179,897,898],{"class":196}," watchman\n",[17,900,901],{},[902,903,904],"em",{},"Note : Watchman n'est pas strictement obligatoire mais recommandé pour la surveillance des fichiers.",[12,906,908],{"id":907},"étape-5-création-du-projet-react-native","Étape 5 : Création du projet React Native",[17,910,911],{},"Nous utiliserons l'outil en ligne de commande officiel pour initialiser le projet.",[102,913,915],{"className":173,"code":914,"language":175,"meta":111,"style":111},"npx @react-native-community/cli init MonPremierProjet\n",[109,916,917],{"__ignoreMap":111},[179,918,919,922,925,928],{"class":181,"line":182},[179,920,921],{"class":192},"npx",[179,923,924],{"class":196}," @react-native-community/cli",[179,926,927],{"class":196}," init",[179,929,930],{"class":196}," MonPremierProjet\n",[17,932,933,934,937],{},"Remplacez ",[109,935,936],{},"MonPremierProjet"," par le nom de votre application. Cette commande peut prendre plusieurs minutes car elle télécharge toutes les dépendances.",[12,939,941],{"id":940},"étape-6-lancement-de-lapplication","Étape 6 : Lancement de l'application",[17,943,944],{},"Accédez au dossier du projet :",[102,946,948],{"className":173,"code":947,"language":175,"meta":111,"style":111},"cd MonPremierProjet\n",[109,949,950],{"__ignoreMap":111},[179,951,952,954],{"class":181,"line":182},[179,953,748],{"class":224},[179,955,930],{"class":196},[17,957,958],{},"Avant de lancer l'application, assurez-vous qu'un émulateur Android est démarré ou qu'un appareil physique est connecté en mode débogage USB.",[17,960,961],{},"Pour lancer le serveur de développement et installer l'application sur l'appareil connecté :",[102,963,965],{"className":173,"code":964,"language":175,"meta":111,"style":111},"npx react-native run-android\n",[109,966,967],{"__ignoreMap":111},[179,968,969,971,974],{"class":181,"line":182},[179,970,921],{"class":192},[179,972,973],{"class":196}," react-native",[179,975,976],{"class":196}," run-android\n",[17,978,979],{},"Si tout est correctement configuré, vous verrez votre application se lancer sur l'écran de l'émulateur ou du téléphone.",[12,981,311],{"id":310},[33,983,984,994,1004],{},[36,985,986,989,990,993],{},[21,987,988],{},"Erreur SDK non trouvé"," : Vérifiez que ",[109,991,992],{},"ANDROID_HOME"," est correctement défini et pointe vers le dossier d'installation du SDK.",[36,995,996,999,1000,1003],{},[21,997,998],{},"Échec du build Gradle"," : Essayez de nettoyer le projet avec ",[109,1001,1002],{},"cd android && ./gradlew clean",", puis relancez la commande de run.",[36,1005,1006,1009],{},[21,1007,1008],{},"Problèmes de permissions"," : Assurez-vous d'avoir les droits nécessaires sur le dossier du SDK Android.",[12,1011,406],{"id":405},[17,1013,1014],{},"Vous avez maintenant un environnement React Native entièrement fonctionnel sur Ubuntu. Vous pouvez commencer à développer vos composants, installer des bibliothèques tierces et construire votre application mobile.",[17,1016,1017,1018,1023,1024,436],{},"Pour aller plus loin, consultez la documentation officielle de ",[730,1019,1022],{"href":1020,"rel":1021},"https://reactnative.dev/docs/getting-started",[734],"React Native"," et explorez les fonctionnalités avancées de ",[21,1025,23],{},[438,1027,1028],{},"html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}",{"title":111,"searchDepth":189,"depth":189,"links":1030},[1031,1032,1033,1034,1035,1036,1037,1038,1039,1040],{"id":14,"depth":189,"text":15},{"id":505,"depth":189,"text":506},{"id":523,"depth":189,"text":524},{"id":605,"depth":189,"text":606},{"id":719,"depth":189,"text":720},{"id":876,"depth":189,"text":877},{"id":907,"depth":189,"text":908},{"id":940,"depth":189,"text":941},{"id":310,"depth":189,"text":311},{"id":405,"depth":189,"text":406},"2026-04-04","Guide complet pour installer React Native sur Ubuntu. Configurez Node.js, JDK, Android Studio et lancez votre premier projet mobile sans erreur.","/images/default-image.webp",{},"/posts/installer-et-configurer-un-environnement-react-native-sur-ubuntu",{"title":491,"description":1042},"posts/installer-et-configurer-un-environnement-react-native-sur-ubuntu",[1049,1050,1051,1052,1053,1054],"react-native","ubuntu","mobile","development","android","tutorial","iZFIvdcn42BNmRjTtWwf-dqoAZV2rKJ-Rye8MBuCHAo",{"id":1057,"title":1058,"author":23,"body":1059,"date":2180,"description":2181,"extension":474,"image":2182,"meta":2183,"navigation":477,"path":2184,"readingTime":479,"seo":2185,"stem":2186,"tags":2187,"updatedAt":2180,"__hash__":2192},"posts/posts/comprendre-et-utiliser-le-protocole-ftp-guide-complet-pour-debutants.md","Comprendre et utiliser le protocole FTP : Guide complet pour débutants",{"type":9,"value":1060,"toc":2157},[1061,1065,1072,1075,1079,1082,1096,1100,1106,1112,1116,1119,1249,1253,1257,1270,1273,1285,1289,1876,1880,1883,1887,1901,1908,1912,1923,1927,1931,1934,1954,1958,1964,1970,1974,1987,2076,2080,2118,2120,2123,2129,2131,2154],[12,1062,1064],{"id":1063},"introduction-au-protocole-ftp","Introduction au protocole FTP",[17,1066,1067,1068,1071],{},"Le ",[21,1069,1070],{},"FTP"," (File Transfer Protocol) est un protocole de communication utilisé pour transférer des fichiers entre un client et un serveur sur un réseau. Développé dans les années 1970, il reste largement utilisé aujourd'hui pour l'hébergement web et le partage de fichiers.",[17,1073,1074],{},"Dans cet article, vous apprendrez les bases du FTP, les commandes essentielles et les bonnes pratiques de sécurité.",[12,1076,1078],{"id":1077},"comment-fonctionne-le-ftp","Comment fonctionne le FTP ?",[17,1080,1081],{},"Le FTP utilise une architecture client-serveur avec deux canaux de communication :",[33,1083,1084,1090],{},[36,1085,1086,1089],{},[21,1087,1088],{},"Canal de contrôle"," (port 21) : Gère les commandes et les réponses",[36,1091,1092,1095],{},[21,1093,1094],{},"Canal de données"," (port 20) : Transfère les fichiers proprement dits",[53,1097,1099],{"id":1098},"les-deux-modes-de-connexion","Les deux modes de connexion",[17,1101,1102,1105],{},[21,1103,1104],{},"Mode actif :"," Le serveur initie la connexion de données vers le client. Peut poser des problèmes avec les pare-feux.",[17,1107,1108,1111],{},[21,1109,1110],{},"Mode passif :"," Le client initie les deux connexions. Recommandé pour traverser les pare-feux modernes.",[12,1113,1115],{"id":1114},"commandes-ftp-essentielles","Commandes FTP essentielles",[17,1117,1118],{},"Voici les commandes de base que vous devez connaître :",[1120,1121,1122,1135],"table",{},[1123,1124,1125],"thead",{},[1126,1127,1128,1132],"tr",{},[1129,1130,1131],"th",{},"Commande",[1129,1133,1134],{},"Description",[1136,1137,1138,1149,1159,1169,1179,1189,1199,1209,1219,1229,1239],"tbody",{},[1126,1139,1140,1146],{},[1141,1142,1143],"td",{},[109,1144,1145],{},"USER",[1141,1147,1148],{},"Spécifie l'identifiant utilisateur",[1126,1150,1151,1156],{},[1141,1152,1153],{},[109,1154,1155],{},"PASS",[1141,1157,1158],{},"Spécifie le mot de passe",[1126,1160,1161,1166],{},[1141,1162,1163],{},[109,1164,1165],{},"PWD",[1141,1167,1168],{},"Affiche le répertoire de travail actuel",[1126,1170,1171,1176],{},[1141,1172,1173],{},[109,1174,1175],{},"CWD",[1141,1177,1178],{},"Change le répertoire de travail",[1126,1180,1181,1186],{},[1141,1182,1183],{},[109,1184,1185],{},"LIST",[1141,1187,1188],{},"Liste les fichiers du répertoire",[1126,1190,1191,1196],{},[1141,1192,1193],{},[109,1194,1195],{},"RETR",[1141,1197,1198],{},"Télécharge un fichier (retrieve)",[1126,1200,1201,1206],{},[1141,1202,1203],{},[109,1204,1205],{},"STOR",[1141,1207,1208],{},"Upload un fichier (store)",[1126,1210,1211,1216],{},[1141,1212,1213],{},[109,1214,1215],{},"DELE",[1141,1217,1218],{},"Supprime un fichier",[1126,1220,1221,1226],{},[1141,1222,1223],{},[109,1224,1225],{},"MKD",[1141,1227,1228],{},"Crée un nouveau répertoire",[1126,1230,1231,1236],{},[1141,1232,1233],{},[109,1234,1235],{},"RMD",[1141,1237,1238],{},"Supprime un répertoire",[1126,1240,1241,1246],{},[1141,1242,1243],{},[109,1244,1245],{},"QUIT",[1141,1247,1248],{},"Ferme la connexion",[12,1250,1252],{"id":1251},"utilisation-en-ligne-de-commande","Utilisation en ligne de commande",[53,1254,1256],{"id":1255},"se-connecter-à-un-serveur-ftp","Se connecter à un serveur FTP",[102,1258,1260],{"className":173,"code":1259,"language":175,"meta":111,"style":111},"ftp nom-du-serveur.com\n",[109,1261,1262],{"__ignoreMap":111},[179,1263,1264,1267],{"class":181,"line":182},[179,1265,1266],{"class":192},"ftp",[179,1268,1269],{"class":196}," nom-du-serveur.com\n",[17,1271,1272],{},"Ou avec identifiant :",[102,1274,1276],{"className":173,"code":1275,"language":175,"meta":111,"style":111},"ftp utilisateur@nom-du-serveur.com\n",[109,1277,1278],{"__ignoreMap":111},[179,1279,1280,1282],{"class":181,"line":182},[179,1281,1266],{"class":192},[179,1283,1284],{"class":196}," utilisateur@nom-du-serveur.com\n",[53,1286,1288],{"id":1287},"exemple-de-session-ftp","Exemple de session FTP",[102,1290,1292],{"className":173,"code":1291,"language":175,"meta":111,"style":111},"$ ftp ftp.example.com\nConnected to ftp.example.com.\nName (ftp.example.com:user): monutilisateur\n331 Please specify the password.\nPassword: \n230 Login successful.\nRemote system type is UNIX.\nUsing binary mode to transfer files.\n\nftp> pwd\n257 \"/\" is current directory\n\nftp> ls\n229 Entering Extended Passive Mode (|||50000|)\n150 Here comes the directory listing.\n-rw-r--r--  1 user group  1024 Jan 15 10:30 index.html\n-rw-r--r--  1 user group  2048 Jan 15 10:35 style.css\ndrwxr-xr-x  2 user group  4096 Jan 15 10:40 images\n226 Directory send OK.\n\nftp> get index.html\nlocal: index.html remote: index.html\n229 Entering Extended Passive Mode (|||50001|)\n150 Opening BINARY mode data connection for index.html (1024 bytes).\n100% |************************|  1024    50.00 KiB/s    00:00 ETA\n226 Transfer complete.\n1024 bytes received in 0.02 seconds\n\nftp> put style.css\nlocal: style.css remote: style.css\n229 Entering Extended Passive Mode (|||50002|)\n150 Ok to send data.\n100% |************************|  2048    75.00 KiB/s    00:00 ETA\n226 Transfer complete.\n2048 bytes sent in 0.03 seconds\n\nftp> quit\n221 Goodbye.\n",[109,1293,1294,1305,1316,1324,1341,1349,1361,1379,1399,1405,1416,1433,1438,1448,1481,1501,1531,1555,1581,1596,1601,1613,1627,1651,1684,1707,1718,1739,1744,1756,1768,1792,1807,1825,1834,1852,1857,1867],{"__ignoreMap":111},[179,1295,1296,1299,1302],{"class":181,"line":182},[179,1297,1298],{"class":192},"$",[179,1300,1301],{"class":196}," ftp",[179,1303,1304],{"class":196}," ftp.example.com\n",[179,1306,1307,1310,1313],{"class":181,"line":189},[179,1308,1309],{"class":192},"Connected",[179,1311,1312],{"class":196}," to",[179,1314,1315],{"class":196}," ftp.example.com.\n",[179,1317,1318,1321],{"class":181,"line":448},[179,1319,1320],{"class":192},"Name",[179,1322,1323],{"class":681}," (ftp.example.com:user): monutilisateur\n",[179,1325,1326,1329,1332,1335,1338],{"class":181,"line":775},[179,1327,1328],{"class":192},"331",[179,1330,1331],{"class":196}," Please",[179,1333,1334],{"class":196}," specify",[179,1336,1337],{"class":196}," the",[179,1339,1340],{"class":196}," password.\n",[179,1342,1343,1346],{"class":181,"line":852},[179,1344,1345],{"class":192},"Password:",[179,1347,1348],{"class":681}," \n",[179,1350,1352,1355,1358],{"class":181,"line":1351},6,[179,1353,1354],{"class":192},"230",[179,1356,1357],{"class":196}," Login",[179,1359,1360],{"class":196}," successful.\n",[179,1362,1364,1367,1370,1373,1376],{"class":181,"line":1363},7,[179,1365,1366],{"class":192},"Remote",[179,1368,1369],{"class":196}," system",[179,1371,1372],{"class":196}," type",[179,1374,1375],{"class":196}," is",[179,1377,1378],{"class":196}," UNIX.\n",[179,1380,1382,1385,1388,1391,1393,1396],{"class":181,"line":1381},8,[179,1383,1384],{"class":192},"Using",[179,1386,1387],{"class":196}," binary",[179,1389,1390],{"class":196}," mode",[179,1392,1312],{"class":196},[179,1394,1395],{"class":196}," transfer",[179,1397,1398],{"class":196}," files.\n",[179,1400,1402],{"class":181,"line":1401},9,[179,1403,1404],{"emptyLinePlaceholder":477},"\n",[179,1406,1408,1410,1413],{"class":181,"line":1407},10,[179,1409,1266],{"class":192},[179,1411,1412],{"class":681},"> ",[179,1414,1415],{"class":196},"pwd\n",[179,1417,1419,1422,1425,1427,1430],{"class":181,"line":1418},11,[179,1420,1421],{"class":192},"257",[179,1423,1424],{"class":196}," \"/\"",[179,1426,1375],{"class":196},[179,1428,1429],{"class":196}," current",[179,1431,1432],{"class":196}," directory\n",[179,1434,1436],{"class":181,"line":1435},12,[179,1437,1404],{"emptyLinePlaceholder":477},[179,1439,1441,1443,1445],{"class":181,"line":1440},13,[179,1442,1266],{"class":192},[179,1444,1412],{"class":681},[179,1446,1447],{"class":196},"ls\n",[179,1449,1451,1454,1457,1460,1463,1466,1469,1472,1475,1478],{"class":181,"line":1450},14,[179,1452,1453],{"class":192},"229",[179,1455,1456],{"class":196}," Entering",[179,1458,1459],{"class":196}," Extended",[179,1461,1462],{"class":196}," Passive",[179,1464,1465],{"class":196}," Mode",[179,1467,1468],{"class":681}," (",[179,1470,1471],{"class":549},"|||",[179,1473,1474],{"class":192},"50000",[179,1476,1477],{"class":549},"|",[179,1479,1480],{"class":681},")\n",[179,1482,1484,1487,1490,1493,1495,1498],{"class":181,"line":1483},15,[179,1485,1486],{"class":192},"150",[179,1488,1489],{"class":196}," Here",[179,1491,1492],{"class":196}," comes",[179,1494,1337],{"class":196},[179,1496,1497],{"class":196}," directory",[179,1499,1500],{"class":196}," listing.\n",[179,1502,1504,1507,1510,1513,1516,1519,1522,1525,1528],{"class":181,"line":1503},16,[179,1505,1506],{"class":192},"-rw-r--r--",[179,1508,1509],{"class":224},"  1",[179,1511,1512],{"class":196}," user",[179,1514,1515],{"class":196}," group",[179,1517,1518],{"class":224},"  1024",[179,1520,1521],{"class":196}," Jan",[179,1523,1524],{"class":224}," 15",[179,1526,1527],{"class":196}," 10:30",[179,1529,1530],{"class":196}," index.html\n",[179,1532,1534,1536,1538,1540,1542,1545,1547,1549,1552],{"class":181,"line":1533},17,[179,1535,1506],{"class":192},[179,1537,1509],{"class":224},[179,1539,1512],{"class":196},[179,1541,1515],{"class":196},[179,1543,1544],{"class":224},"  2048",[179,1546,1521],{"class":196},[179,1548,1524],{"class":224},[179,1550,1551],{"class":196}," 10:35",[179,1553,1554],{"class":196}," style.css\n",[179,1556,1558,1561,1564,1566,1568,1571,1573,1575,1578],{"class":181,"line":1557},18,[179,1559,1560],{"class":192},"drwxr-xr-x",[179,1562,1563],{"class":224},"  2",[179,1565,1512],{"class":196},[179,1567,1515],{"class":196},[179,1569,1570],{"class":224},"  4096",[179,1572,1521],{"class":196},[179,1574,1524],{"class":224},[179,1576,1577],{"class":196}," 10:40",[179,1579,1580],{"class":196}," images\n",[179,1582,1584,1587,1590,1593],{"class":181,"line":1583},19,[179,1585,1586],{"class":192},"226",[179,1588,1589],{"class":196}," Directory",[179,1591,1592],{"class":196}," send",[179,1594,1595],{"class":196}," OK.\n",[179,1597,1599],{"class":181,"line":1598},20,[179,1600,1404],{"emptyLinePlaceholder":477},[179,1602,1604,1606,1608,1611],{"class":181,"line":1603},21,[179,1605,1266],{"class":192},[179,1607,1412],{"class":681},[179,1609,1610],{"class":196},"get",[179,1612,1530],{"class":196},[179,1614,1616,1619,1622,1625],{"class":181,"line":1615},22,[179,1617,1618],{"class":192},"local:",[179,1620,1621],{"class":196}," index.html",[179,1623,1624],{"class":196}," remote:",[179,1626,1530],{"class":196},[179,1628,1630,1632,1634,1636,1638,1640,1642,1644,1647,1649],{"class":181,"line":1629},23,[179,1631,1453],{"class":192},[179,1633,1456],{"class":196},[179,1635,1459],{"class":196},[179,1637,1462],{"class":196},[179,1639,1465],{"class":196},[179,1641,1468],{"class":681},[179,1643,1471],{"class":549},[179,1645,1646],{"class":192},"50001",[179,1648,1477],{"class":549},[179,1650,1480],{"class":681},[179,1652,1654,1656,1659,1662,1664,1667,1670,1673,1675,1678,1681],{"class":181,"line":1653},24,[179,1655,1486],{"class":192},[179,1657,1658],{"class":196}," Opening",[179,1660,1661],{"class":196}," BINARY",[179,1663,1390],{"class":196},[179,1665,1666],{"class":196}," data",[179,1668,1669],{"class":196}," connection",[179,1671,1672],{"class":196}," for",[179,1674,1621],{"class":196},[179,1676,1677],{"class":681}," (1024 ",[179,1679,1680],{"class":196},"bytes",[179,1682,1683],{"class":681},").\n",[179,1685,1687,1690,1693,1695,1698,1701,1704],{"class":181,"line":1686},25,[179,1688,1689],{"class":192},"100%",[179,1691,1692],{"class":549}," |************************|",[179,1694,1518],{"class":192},[179,1696,1697],{"class":224},"    50.00",[179,1699,1700],{"class":196}," KiB/s",[179,1702,1703],{"class":196},"    00:00",[179,1705,1706],{"class":196}," ETA\n",[179,1708,1710,1712,1715],{"class":181,"line":1709},26,[179,1711,1586],{"class":192},[179,1713,1714],{"class":196}," Transfer",[179,1716,1717],{"class":196}," complete.\n",[179,1719,1721,1724,1727,1730,1733,1736],{"class":181,"line":1720},27,[179,1722,1723],{"class":192},"1024",[179,1725,1726],{"class":196}," bytes",[179,1728,1729],{"class":196}," received",[179,1731,1732],{"class":196}," in",[179,1734,1735],{"class":224}," 0.02",[179,1737,1738],{"class":196}," seconds\n",[179,1740,1742],{"class":181,"line":1741},28,[179,1743,1404],{"emptyLinePlaceholder":477},[179,1745,1747,1749,1751,1754],{"class":181,"line":1746},29,[179,1748,1266],{"class":192},[179,1750,1412],{"class":681},[179,1752,1753],{"class":196},"put",[179,1755,1554],{"class":196},[179,1757,1759,1761,1764,1766],{"class":181,"line":1758},30,[179,1760,1618],{"class":192},[179,1762,1763],{"class":196}," style.css",[179,1765,1624],{"class":196},[179,1767,1554],{"class":196},[179,1769,1771,1773,1775,1777,1779,1781,1783,1785,1788,1790],{"class":181,"line":1770},31,[179,1772,1453],{"class":192},[179,1774,1456],{"class":196},[179,1776,1459],{"class":196},[179,1778,1462],{"class":196},[179,1780,1465],{"class":196},[179,1782,1468],{"class":681},[179,1784,1471],{"class":549},[179,1786,1787],{"class":192},"50002",[179,1789,1477],{"class":549},[179,1791,1480],{"class":681},[179,1793,1795,1797,1800,1802,1804],{"class":181,"line":1794},32,[179,1796,1486],{"class":192},[179,1798,1799],{"class":196}," Ok",[179,1801,1312],{"class":196},[179,1803,1592],{"class":196},[179,1805,1806],{"class":196}," data.\n",[179,1808,1810,1812,1814,1816,1819,1821,1823],{"class":181,"line":1809},33,[179,1811,1689],{"class":192},[179,1813,1692],{"class":549},[179,1815,1544],{"class":192},[179,1817,1818],{"class":224},"    75.00",[179,1820,1700],{"class":196},[179,1822,1703],{"class":196},[179,1824,1706],{"class":196},[179,1826,1828,1830,1832],{"class":181,"line":1827},34,[179,1829,1586],{"class":192},[179,1831,1714],{"class":196},[179,1833,1717],{"class":196},[179,1835,1837,1840,1842,1845,1847,1850],{"class":181,"line":1836},35,[179,1838,1839],{"class":192},"2048",[179,1841,1726],{"class":196},[179,1843,1844],{"class":196}," sent",[179,1846,1732],{"class":196},[179,1848,1849],{"class":224}," 0.03",[179,1851,1738],{"class":196},[179,1853,1855],{"class":181,"line":1854},36,[179,1856,1404],{"emptyLinePlaceholder":477},[179,1858,1860,1862,1864],{"class":181,"line":1859},37,[179,1861,1266],{"class":192},[179,1863,1412],{"class":681},[179,1865,1866],{"class":196},"quit\n",[179,1868,1870,1873],{"class":181,"line":1869},38,[179,1871,1872],{"class":192},"221",[179,1874,1875],{"class":196}," Goodbye.\n",[12,1877,1879],{"id":1878},"clients-ftp-graphiques","Clients FTP graphiques",[17,1881,1882],{},"Pour une expérience plus conviviale, utilisez des clients graphiques :",[53,1884,1886],{"id":1885},"filezilla-gratuit-et-populaire","FileZilla (gratuit et populaire)",[33,1888,1889,1892,1895,1898],{},[36,1890,1891],{},"Interface intuitive en français",[36,1893,1894],{},"Gestionnaire de sites pour enregistrer vos connexions",[36,1896,1897],{},"Transfert par glisser-déposer",[36,1899,1900],{},"Disponible sur Windows, macOS et Linux",[17,1902,1903],{},[730,1904,1907],{"href":1905,"rel":1906},"https://filezilla-project.org/",[734],"Télécharger FileZilla",[53,1909,1911],{"id":1910},"winscp-windows","WinSCP (Windows)",[33,1913,1914,1917,1920],{},[36,1915,1916],{},"Spécialisé pour Windows",[36,1918,1919],{},"Supporte FTP, SFTP et SCP",[36,1921,1922],{},"Intégration avec PuTTY pour SSH",[12,1924,1926],{"id":1925},"sécurité-et-limitations-du-ftp","Sécurité et limitations du FTP",[53,1928,1930],{"id":1929},"problèmes-de-sécurité-du-ftp-standard","Problèmes de sécurité du FTP standard",[17,1932,1933],{},"Le FTP traditionnel présente plusieurs failles de sécurité :",[33,1935,1936,1942,1948],{},[36,1937,1938,1941],{},[21,1939,1940],{},"Données non chiffrées"," : Les mots de passe et fichiers transitent en clair",[36,1943,1944,1947],{},[21,1945,1946],{},"Vulnérable aux attaques"," : Interception possible des données sur le réseau",[36,1949,1950,1953],{},[21,1951,1952],{},"Pas d'authentification forte"," : Repos sur simple mot de passe",[53,1955,1957],{"id":1956},"alternatives-sécurisées","Alternatives sécurisées",[17,1959,1960,1963],{},[21,1961,1962],{},"SFTP (SSH File Transfer Protocol)"," : Utilise le protocole SSH pour chiffrer toutes les communications. Port 22 par défaut.",[17,1965,1966,1969],{},[21,1967,1968],{},"FTPS (FTP over SSL/TLS)"," : Version sécurisée du FTP avec chiffrement SSL/TLS.",[53,1971,1973],{"id":1972},"exemple-de-connexion-sftp","Exemple de connexion SFTP",[102,1975,1977],{"className":173,"code":1976,"language":175,"meta":111,"style":111},"sftp utilisateur@serveur.com\n",[109,1978,1979],{"__ignoreMap":111},[179,1980,1981,1984],{"class":181,"line":182},[179,1982,1983],{"class":192},"sftp",[179,1985,1986],{"class":196}," utilisateur@serveur.com\n",[102,1988,1990],{"className":173,"code":1989,"language":175,"meta":111,"style":111},"$ sftp monuser@monserveur.com\nmonuser@monserveur.com's password: \nConnected to monserveur.com.\nsftp> pwd\nRemote working directory: /home/monuser\n\nsftp> ls\nindex.html  style.css  images/\n\nsftp> get index.html\nFetching /home/monuser/index.html to index.html\n\nsftp> put nouveau-fichier.html\nUploading nouveau-fichier.html to /home/monuser/nouveau-fichier.html\n\nsftp> exit\n",[109,1991,1992,2002,2010,2015,2020,2025,2029,2034,2039,2043,2048,2053,2057,2062,2067,2071],{"__ignoreMap":111},[179,1993,1994,1996,1999],{"class":181,"line":182},[179,1995,1298],{"class":192},[179,1997,1998],{"class":196}," sftp",[179,2000,2001],{"class":196}," monuser@monserveur.com\n",[179,2003,2004,2007],{"class":181,"line":189},[179,2005,2006],{"class":192},"monuser@monserveur.com",[179,2008,2009],{"class":192},"'s password: \n",[179,2011,2012],{"class":181,"line":448},[179,2013,2014],{"class":192},"Connected to monserveur.com.\n",[179,2016,2017],{"class":181,"line":775},[179,2018,2019],{"class":192},"sftp> pwd\n",[179,2021,2022],{"class":181,"line":852},[179,2023,2024],{"class":192},"Remote working directory: /home/monuser\n",[179,2026,2027],{"class":181,"line":1351},[179,2028,1404],{"emptyLinePlaceholder":477},[179,2030,2031],{"class":181,"line":1363},[179,2032,2033],{"class":192},"sftp> ls\n",[179,2035,2036],{"class":181,"line":1381},[179,2037,2038],{"class":192},"index.html  style.css  images/\n",[179,2040,2041],{"class":181,"line":1401},[179,2042,1404],{"emptyLinePlaceholder":477},[179,2044,2045],{"class":181,"line":1407},[179,2046,2047],{"class":192},"sftp> get index.html\n",[179,2049,2050],{"class":181,"line":1418},[179,2051,2052],{"class":192},"Fetching /home/monuser/index.html to index.html\n",[179,2054,2055],{"class":181,"line":1435},[179,2056,1404],{"emptyLinePlaceholder":477},[179,2058,2059],{"class":181,"line":1440},[179,2060,2061],{"class":192},"sftp> put nouveau-fichier.html\n",[179,2063,2064],{"class":181,"line":1450},[179,2065,2066],{"class":192},"Uploading nouveau-fichier.html to /home/monuser/nouveau-fichier.html\n",[179,2068,2069],{"class":181,"line":1483},[179,2070,1404],{"emptyLinePlaceholder":477},[179,2072,2073],{"class":181,"line":1503},[179,2074,2075],{"class":192},"sftp> exit\n",[12,2077,2079],{"id":2078},"bonnes-pratiques-ftp","Bonnes pratiques FTP",[79,2081,2082,2088,2094,2100,2106,2112],{},[36,2083,2084,2087],{},[21,2085,2086],{},"Préférez SFTP"," quand c'est possible pour la sécurité",[36,2089,2090,2093],{},[21,2091,2092],{},"Utilisez des mots de passe forts"," pour vos comptes FTP",[36,2095,2096,2099],{},[21,2097,2098],{},"Évitez le FTP anonyme"," sur des serveurs sensibles",[36,2101,2102,2105],{},[21,2103,2104],{},"Limitez les permissions"," des utilisateurs FTP",[36,2107,2108,2111],{},[21,2109,2110],{},"Utilisez le mode passif"," pour éviter les problèmes de pare-feu",[36,2113,2114,2117],{},[21,2115,2116],{},"Sauvegardez avant transfert"," en cas de modification de fichiers critiques",[12,2119,406],{"id":405},[17,2121,2122],{},"Le FTP reste un outil essentiel pour le transfert de fichiers, notamment dans le domaine de l'hébergement web. Bien que des alternatives plus sécurisées comme le SFTP existent, comprendre le FTP traditionnel est fondamental pour tout développeur ou administrateur système.",[17,2124,2125,2126,2128],{},"Pour vos projets sur ",[21,2127,23],{},", privilégiez toujours les connexions sécurisées lorsque c'est possible.",[12,2130,419],{"id":418},[33,2132,2133,2140,2147],{},[36,2134,2135],{},[730,2136,2139],{"href":2137,"rel":2138},"https://tools.ietf.org/html/rfc959",[734],"Documentation officielle FTP (RFC 959)",[36,2141,2142],{},[730,2143,2146],{"href":2144,"rel":2145},"https://learn.rivolink.mg",[734],"Guide de sécurité FTP",[36,2148,2149],{},[730,2150,2153],{"href":2151,"rel":2152},"https://filezilla-project.org/support.php",[734],"Tutoriel FileZilla",[438,2155,2156],{},"html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}",{"title":111,"searchDepth":189,"depth":189,"links":2158},[2159,2160,2163,2164,2168,2172,2177,2178,2179],{"id":1063,"depth":189,"text":1064},{"id":1077,"depth":189,"text":1078,"children":2161},[2162],{"id":1098,"depth":448,"text":1099},{"id":1114,"depth":189,"text":1115},{"id":1251,"depth":189,"text":1252,"children":2165},[2166,2167],{"id":1255,"depth":448,"text":1256},{"id":1287,"depth":448,"text":1288},{"id":1878,"depth":189,"text":1879,"children":2169},[2170,2171],{"id":1885,"depth":448,"text":1886},{"id":1910,"depth":448,"text":1911},{"id":1925,"depth":189,"text":1926,"children":2173},[2174,2175,2176],{"id":1929,"depth":448,"text":1930},{"id":1956,"depth":448,"text":1957},{"id":1972,"depth":448,"text":1973},{"id":2078,"depth":189,"text":2079},{"id":405,"depth":189,"text":406},{"id":418,"depth":189,"text":419},"2026-04-03","Apprenez le protocole FTP pour transférer des fichiers. Commandes essentielles, modes de connexion et sécurité pour vos projets web.","/images/posts/2026/04/comprendre-et-utiliser-le-protocole-ftp-guide-complet-pour-debutants.webp",{},"/posts/comprendre-et-utiliser-le-protocole-ftp-guide-complet-pour-debutants",{"title":1058,"description":2181},"posts/comprendre-et-utiliser-le-protocole-ftp-guide-complet-pour-debutants",[1070,275,2188,2189,2190,2191],"Linux","Réseau","Débutant","Hébergement web","YrvkGkpvLVqSEU7UHiYH5GYjKK-ocLS33ZH2dW0_Kr8",{"id":2194,"title":2195,"author":2196,"body":2197,"date":2180,"description":2584,"extension":474,"image":2585,"meta":2586,"navigation":477,"path":2587,"readingTime":479,"seo":2588,"stem":2589,"tags":2590,"updatedAt":2180,"__hash__":2595},"posts/posts/comprendre-et-utiliser-le-protocole-vnc-pour-l-acces-a-distance.md","Comprendre et utiliser le protocole VNC pour l'accès à distance","Drafter",{"type":9,"value":2198,"toc":2567},[2199,2203,2208,2214,2218,2221,2235,2242,2246,2250,2276,2280,2300,2302,2306,2309,2336,2339,2348,2355,2388,2391,2427,2431,2438,2452,2456,2459,2463,2483,2493,2497,2502,2554,2556,2559,2564],[12,2200,2202],{"id":2201},"introduction-au-protocole-vnc","Introduction au protocole VNC",[17,2204,1067,2205,2207],{},[21,2206,395],{}," (Virtual Network Computing) est un système de partage de bureau graphique qui utilise le protocole RFB (Remote Frame Buffer) pour permettre le contrôle à distance d'un ordinateur. Contrairement à d'autres solutions comme le Bureau à distance de Windows (RDP), VNC est indépendant de la plateforme et fonctionne sur la plupart des systèmes d'exploitation.",[17,2209,2210,2211,2213],{},"Sur ",[21,2212,23],{},", nous explorons les fondamentaux de cette technologie essentielle pour l'administration système et le support technique.",[12,2215,2217],{"id":2216},"comment-fonctionne-le-vnc","Comment fonctionne le VNC ?",[17,2219,2220],{},"L'architecture VNC repose sur un modèle client-serveur simple :",[33,2222,2223,2229],{},[36,2224,2225,2228],{},[21,2226,2227],{},"Le serveur VNC"," : S'exécute sur la machine à contrôler. Il capture les changements de l'écran et les envoie au client, tout en recevant les entrées clavier et souris.",[36,2230,2231,2234],{},[21,2232,2233],{},"Le client VNC (ou viewer)"," : S'exécute sur la machine de l'utilisateur. Il affiche l'écran distant et transmet les actions de l'utilisateur au serveur.",[17,2236,2237,2238,2241],{},"La communication se fait généralement sur le port TCP ",[21,2239,2240],{},"5900"," (pour l'affichage :0), mais ce port peut être configuré différemment.",[12,2243,2245],{"id":2244},"avantages-et-inconvénients","Avantages et inconvénients",[53,2247,2249],{"id":2248},"avantages","Avantages",[33,2251,2252,2258,2264,2270],{},[36,2253,2254,2257],{},[21,2255,2256],{},"Multiplateforme"," : Fonctionne sur Windows, Linux, macOS, Android et iOS.",[36,2259,2260,2263],{},[21,2261,2262],{},"Open Source"," : De nombreuses implémentations gratuites existent (TigerVNC, RealVNC, TightVNC).",[36,2265,2266,2269],{},[21,2267,2268],{},"Simplicité"," : Facile à installer et à configurer pour un accès rapide.",[36,2271,2272,2275],{},[21,2273,2274],{},"Indépendance"," : Ne nécessite pas de compte utilisateur spécifique sur certaines implémentations (accès à la session physique).",[53,2277,2279],{"id":2278},"inconvénients","Inconvénients",[33,2281,2282,2288,2294],{},[36,2283,2284,2287],{},[21,2285,2286],{},"Performance"," : Peut être lent sur des connexions à faible bande passante car il transmet des images brutes.",[36,2289,2290,2293],{},[21,2291,2292],{},"Sécurité"," : Le protocole de base n'est pas chiffré. Il est fortement recommandé de l'utiliser via un tunnel SSH.",[36,2295,2296,2299],{},[21,2297,2298],{},"Fonctionnalités limitées"," : Moins riche en fonctionnalités que RDP (pas de redirection de son ou d'imprimante native facile).",[12,2301,51],{"id":50},[53,2303,2305],{"id":2304},"sur-linux-ubuntudebian","Sur Linux (Ubuntu/Debian)",[17,2307,2308],{},"Pour installer un serveur VNC populaire comme TigerVNC :",[102,2310,2312],{"className":173,"code":2311,"language":175,"meta":111,"style":111},"sudo apt update\nsudo apt install tigervnc-standalone-server tigervnc-common\n",[109,2313,2314,2322],{"__ignoreMap":111},[179,2315,2316,2318,2320],{"class":181,"line":182},[179,2317,567],{"class":192},[179,2319,621],{"class":196},[179,2321,624],{"class":196},[179,2323,2324,2326,2328,2330,2333],{"class":181,"line":189},[179,2325,567],{"class":192},[179,2327,621],{"class":196},[179,2329,573],{"class":196},[179,2331,2332],{"class":196}," tigervnc-standalone-server",[179,2334,2335],{"class":196}," tigervnc-common\n",[17,2337,2338],{},"Configurez le mot de passe pour l'accès VNC :",[102,2340,2342],{"className":173,"code":2341,"language":175,"meta":111,"style":111},"vncpasswd\n",[109,2343,2344],{"__ignoreMap":111},[179,2345,2346],{"class":181,"line":182},[179,2347,2341],{"class":192},[17,2349,2350,2351,2354],{},"Créez un fichier de configuration ",[109,2352,2353],{},"~/.vnc/xstartup"," pour définir l'environnement de bureau à lancer :",[102,2356,2358],{"className":173,"code":2357,"language":175,"meta":111,"style":111},"#!/bin/sh\nunset SESSION_MANAGER\nunset DBUS_SESSION_BUS_ADDRESS\nexec startxfce4\n",[109,2359,2360,2365,2373,2380],{"__ignoreMap":111},[179,2361,2362],{"class":181,"line":182},[179,2363,2364],{"class":185},"#!/bin/sh\n",[179,2366,2367,2370],{"class":181,"line":189},[179,2368,2369],{"class":224},"unset",[179,2371,2372],{"class":196}," SESSION_MANAGER\n",[179,2374,2375,2377],{"class":181,"line":448},[179,2376,2369],{"class":224},[179,2378,2379],{"class":196}," DBUS_SESSION_BUS_ADDRESS\n",[179,2381,2382,2385],{"class":181,"line":775},[179,2383,2384],{"class":224},"exec",[179,2386,2387],{"class":196}," startxfce4\n",[17,2389,2390],{},"Rendez le script exécutable et lancez le serveur :",[102,2392,2394],{"className":173,"code":2393,"language":175,"meta":111,"style":111},"chmod +x ~/.vnc/xstartup\nvncserver :1 -geometry 1920x1080 -depth 24\n",[109,2395,2396,2407],{"__ignoreMap":111},[179,2397,2398,2401,2404],{"class":181,"line":182},[179,2399,2400],{"class":192},"chmod",[179,2402,2403],{"class":196}," +x",[179,2405,2406],{"class":196}," ~/.vnc/xstartup\n",[179,2408,2409,2412,2415,2418,2421,2424],{"class":181,"line":189},[179,2410,2411],{"class":192},"vncserver",[179,2413,2414],{"class":196}," :1",[179,2416,2417],{"class":224}," -geometry",[179,2419,2420],{"class":196}," 1920x1080",[179,2422,2423],{"class":224}," -depth",[179,2425,2426],{"class":224}," 24\n",[53,2428,2430],{"id":2429},"sur-windows","Sur Windows",[17,2432,2433,2434,2437],{},"L'installation est souvent plus simple via un exécutable. Pour ",[21,2435,2436],{},"TightVNC"," par exemple :",[79,2439,2440,2443,2446,2449],{},[36,2441,2442],{},"Téléchargez l'installateur depuis le site officiel.",[36,2444,2445],{},"Lors de l'installation, choisissez d'installer le composant \"Server\".",[36,2447,2448],{},"Définissez un mot de passe lors de la configuration initiale.",[36,2450,2451],{},"Le service se lance automatiquement au démarrage.",[12,2453,2455],{"id":2454},"se-connecter-à-une-machine-distante","Se connecter à une machine distante",[17,2457,2458],{},"Une fois le serveur configuré, utilisez un client VNC sur votre machine locale.",[53,2460,2462],{"id":2461},"clients-populaires","Clients populaires",[33,2464,2465,2471,2477],{},[36,2466,2467,2470],{},[21,2468,2469],{},"RealVNC Viewer"," : Disponible sur toutes les plateformes.",[36,2472,2473,2476],{},[21,2474,2475],{},"TigerVNC Viewer"," : Léger et performant.",[36,2478,2479,2482],{},[21,2480,2481],{},"Remmina"," : Excellent client pour Linux supportant VNC, RDP et SSH.",[17,2484,2485,2486,665,2489,2492],{},"Pour vous connecter, saisissez simplement l'adresse IP de la machine distante suivie du port (ex: ",[109,2487,2488],{},"192.168.1.10:5901",[109,2490,2491],{},"192.168.1.10:1"," selon le client).",[12,2494,2496],{"id":2495},"sécuriser-sa-connexion-vnc","Sécuriser sa connexion VNC",[17,2498,2499,2500,642],{},"Comme mentionné, le trafic VNC n'est pas chiffré par défaut. Voici les meilleures pratiques recommandées par ",[21,2501,23],{},[79,2503,2504,2536,2542,2548],{},[36,2505,2506,2509,2510,2529,2532,2533,436],{},[21,2507,2508],{},"Utiliser un tunnel SSH"," : C'est la méthode la plus sûre. Elle chiffre tout le trafic VNC via SSH.",[102,2511,2513],{"className":173,"code":2512,"language":175,"meta":111,"style":111},"ssh -L 5901:localhost:5901 utilisateur@adresse_ip_distante\n",[109,2514,2515],{"__ignoreMap":111},[179,2516,2517,2520,2523,2526],{"class":181,"line":182},[179,2518,2519],{"class":192},"ssh",[179,2521,2522],{"class":224}," -L",[179,2524,2525],{"class":196}," 5901:localhost:5901",[179,2527,2528],{"class":196}," utilisateur@adresse_ip_distante\n",[2530,2531],"br",{},"Ensuite, connectez votre client VNC à ",[109,2534,2535],{},"localhost:5901",[36,2537,2538,2541],{},[21,2539,2540],{},"Changer le port par défaut"," : Pour éviter les scans automatiques.",[36,2543,2544,2547],{},[21,2545,2546],{},"Utiliser un mot de passe fort"," : Indispensable pour l'authentification.",[36,2549,2550,2553],{},[21,2551,2552],{},"Restreindre l'accès par IP"," : Configurez votre pare-feu pour n'accepter les connexions VNC que depuis des adresses IP de confiance.",[12,2555,406],{"id":405},[17,2557,2558],{},"Le protocole VNC reste un outil incontournable pour l'accès à distance, notamment dans les environnements hétérogènes. Bien qu'il demande quelques précautions de sécurité, sa flexibilité et sa simplicité en font un choix privilégié pour de nombreux administrateurs.",[17,2560,2561,2562,436],{},"Pour aller plus loin, explorez nos autres articles sur l'administration réseau et la sécurisation des services sur ",[21,2563,23],{},[438,2565,2566],{},"html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}",{"title":111,"searchDepth":189,"depth":189,"links":2568},[2569,2570,2571,2575,2579,2582,2583],{"id":2201,"depth":189,"text":2202},{"id":2216,"depth":189,"text":2217},{"id":2244,"depth":189,"text":2245,"children":2572},[2573,2574],{"id":2248,"depth":448,"text":2249},{"id":2278,"depth":448,"text":2279},{"id":50,"depth":189,"text":51,"children":2576},[2577,2578],{"id":2304,"depth":448,"text":2305},{"id":2429,"depth":448,"text":2430},{"id":2454,"depth":189,"text":2455,"children":2580},[2581],{"id":2461,"depth":448,"text":2462},{"id":2495,"depth":189,"text":2496},{"id":405,"depth":189,"text":406},"Découvrez le protocole VNC pour l'accès à distance. Configuez serveur et client, et sécurisez vos connexions pour contrôler un ordinateur à distance.","/images/posts/2026/04/comprendre-et-utiliser-le-protocole-vnc-pour-l-acces-a-distance.webp",{},"/posts/comprendre-et-utiliser-le-protocole-vnc-pour-l-acces-a-distance",{"title":2195,"description":2584},"posts/comprendre-et-utiliser-le-protocole-vnc-pour-l-acces-a-distance",[486,2591,487,2592,2593,2594],"administration","linux","windows","acces-distance","ziIVgPM0PPIFVqnaXs8EYffddEDn7JWIZlNkdI_njwk",{"id":2597,"title":2598,"author":23,"body":2599,"date":2180,"description":2876,"extension":474,"image":2877,"meta":2878,"navigation":477,"path":2879,"readingTime":479,"seo":2880,"stem":2881,"tags":2882,"updatedAt":2180,"__hash__":2886},"posts/posts/comprendre-le-remote-desktop-acceder-a-son-ordinateur-a-distance.md","Comprendre le Remote Desktop : Accéder à son ordinateur à distance",{"type":9,"value":2600,"toc":2863},[2601,2605,2611,2614,2642,2646,2652,2672,2675,2695,2699,2702,2706,2709,2721,2725,2728,2740,2744,2747,2759,2763,2766,2778,2782,2788,2818,2822,2825,2853,2855,2858],[12,2602,2604],{"id":2603},"quest-ce-que-le-remote-desktop","Qu'est-ce que le Remote Desktop ?",[17,2606,1067,2607,2610],{},[21,2608,2609],{},"Remote Desktop"," (bureau à distance) est une technologie logicielle qui permet à un utilisateur de se connecter à un ordinateur distant et d'en prendre le contrôle total comme s'il était physiquement présent devant la machine. L'écran de l'ordinateur distant est affiché sur votre appareil local, et vos actions (clavier, souris) sont transmises en temps réel.",[17,2612,2613],{},"Cette technologie est devenue incontournable pour :",[33,2615,2616,2622,2628,2635],{},[36,2617,1067,2618,2621],{},[21,2619,2620],{},"télétravail"," : accéder à son poste de travail depuis chez soi.",[36,2623,1067,2624,2627],{},[21,2625,2626],{},"support technique"," : permettre à un technicien de résoudre un problème à distance.",[36,2629,2630,2631,2634],{},"La ",[21,2632,2633],{},"gestion de serveurs"," : administrer des machines hébergées dans des datacenters.",[36,2636,2637,2638,2641],{},"L'",[21,2639,2640],{},"accès aux fichiers"," : récupérer des documents stockés sur un ordinateur spécifique.",[12,2643,2645],{"id":2644},"comment-fonctionne-le-bureau-à-distance","Comment fonctionne le Bureau à Distance ?",[17,2647,2648,2649,642],{},"Le fonctionnement repose sur une architecture ",[21,2650,2651],{},"client-serveur",[79,2653,2654,2660,2666],{},[36,2655,2656,2659],{},[21,2657,2658],{},"L'hôte (Serveur)"," : C'est l'ordinateur distant que vous souhaitez contrôler. Il doit exécuter un logiciel serveur de bureau à distance et être accessible via le réseau (Internet ou réseau local).",[36,2661,2662,2665],{},[21,2663,2664],{},"Le client"," : C'est l'appareil que vous utilisez (PC, Mac, tablette, smartphone) pour vous connecter à l'hôte.",[36,2667,2668,2671],{},[21,2669,2670],{},"Le protocole de communication"," : Les données d'affichage (images de l'écran) sont compressées et envoyées de l'hôte vers le client. En retour, les entrées utilisateur (clics, frappes clavier) sont envoyées du client vers l'hôte.",[17,2673,2674],{},"Les protocoles les plus courants incluent :",[33,2676,2677,2683,2689],{},[36,2678,2679,2682],{},[21,2680,2681],{},"RDP (Remote Desktop Protocol)"," : Développé par Microsoft, natif sur Windows.",[36,2684,2685,2688],{},[21,2686,2687],{},"VNC (Virtual Network Computing)"," : Une solution open-source multiplateforme.",[36,2690,2691,2694],{},[21,2692,2693],{},"SSH avec X11 forwarding"," : Souvent utilisé pour les interfaces graphiques sur Linux.",[12,2696,2698],{"id":2697},"les-solutions-populaires","Les solutions populaires",[17,2700,2701],{},"Plusieurs outils permettent de mettre en place une connexion bureau à distance :",[53,2703,2705],{"id":2704},"_1-bureau-à-distance-microsoft-rdp","1. Bureau à distance Microsoft (RDP)",[17,2707,2708],{},"Intégré directement dans les versions Professionnelles de Windows.",[33,2710,2711,2716],{},[36,2712,2713,2715],{},[21,2714,2249],{}," : Pas d'installation supplémentaire nécessaire, performances élevées sur réseau local.",[36,2717,2718,2720],{},[21,2719,2279],{}," : Configuration du routeur (port forwarding) requise pour un accès depuis l'extérieur, souvent complexe pour les débutants.",[53,2722,2724],{"id":2723},"_2-teamviewer","2. TeamViewer",[17,2726,2727],{},"Une solution tierce très populaire pour le support technique.",[33,2729,2730,2735],{},[36,2731,2732,2734],{},[21,2733,2249],{}," : Configuration très simple (pas besoin d'ouvrir les ports du routeur), fonctionne derrière les pare-feux.",[36,2736,2737,2739],{},[21,2738,2279],{}," : Limité à un usage personnel gratuit, peut détecter un usage commercial et bloquer la session.",[53,2741,2743],{"id":2742},"_3-anydesk","3. AnyDesk",[17,2745,2746],{},"Connu pour sa légèreté et sa faible latence.",[33,2748,2749,2754],{},[36,2750,2751,2753],{},[21,2752,2249],{}," : Très rapide même avec une connexion internet moyenne, interface épurée.",[36,2755,2756,2758],{},[21,2757,2279],{}," : Certaines fonctionnalités avancées sont payantes.",[53,2760,2762],{"id":2761},"_4-chrome-remote-desktop","4. Chrome Remote Desktop",[17,2764,2765],{},"Une extension pour le navigateur Google Chrome.",[33,2767,2768,2773],{},[36,2769,2770,2772],{},[21,2771,2249],{}," : Gratuit, facile à configurer via un compte Google, accessible depuis n'importe quel navigateur.",[36,2774,2775,2777],{},[21,2776,2279],{}," : Fonctionnalités limitées par rapport à des logiciels dédiés.",[12,2779,2781],{"id":2780},"configurer-une-connexion-sécurisée","Configurer une connexion sécurisée",[17,2783,2784,2785,2787],{},"La sécurité est primordiale lorsqu'on ouvre un accès à son ordinateur. Voici les bonnes pratiques à respecter sur ",[21,2786,23],{}," et ailleurs :",[33,2789,2790,2796,2802,2808],{},[36,2791,2792,2795],{},[21,2793,2794],{},"Mot de passe fort"," : Utilisez toujours des mots de passe complexes pour le compte utilisateur distant.",[36,2797,2798,2801],{},[21,2799,2800],{},"Authentification à deux facteurs (2FA)"," : Activez-la whenever possible (disponible sur TeamViewer, AnyDesk, Chrome RD).",[36,2803,2804,2807],{},[21,2805,2806],{},"Mise à jour des logiciels"," : Gardez toujours le client et le serveur à jour pour éviter les failles de sécurité.",[36,2809,2810,2813,2814,2817],{},[21,2811,2812],{},"Éviter l'exposition directe"," : Si vous utilisez RDP, évitez d'exposer le port 3389 directement sur Internet. Privilégiez un ",[21,2815,2816],{},"VPN"," pour vous connecter d'abord au réseau local de manière sécurisée, puis utilisez le bureau à distance.",[12,2819,2821],{"id":2820},"exemple-dutilisation-basique-avec-rdp-windows","Exemple d'utilisation basique avec RDP (Windows)",[17,2823,2824],{},"Si vous êtes sur un réseau local et que vous souhaitez vous connecter à un autre PC Windows :",[79,2826,2827,2834,2837,2843,2846],{},[36,2828,2829,2830,2833],{},"Sur l'ordinateur hôte, allez dans ",[21,2831,2832],{},"Paramètres > Système > Bureau à distance"," et activez l'option.",[36,2835,2836],{},"Notez le nom de l'ordinateur ou son adresse IP locale.",[36,2838,2839,2840,436],{},"Sur votre ordinateur client, ouvrez l'application ",[21,2841,2842],{},"Connexion Bureau à distance",[36,2844,2845],{},"Entrez le nom ou l'IP de l'hôte.",[36,2847,2848,2849,2852],{},"Cliquez sur ",[21,2850,2851],{},"Connexion"," et saisissez vos identifiants Windows.",[12,2854,406],{"id":405},[17,2856,2857],{},"Le Remote Desktop est un outil puissant qui offre une grande flexibilité pour travailler et gérer des systèmes à distance. Que vous choisissiez la solution native de Windows ou un outil tiers comme TeamViewer ou AnyDesk, assurez-vous toujours de prioriser la sécurité de vos connexions.",[17,2859,2860,2861,436],{},"Pour plus de tutoriels techniques, restez connecté sur ",[21,2862,23],{},{"title":111,"searchDepth":189,"depth":189,"links":2864},[2865,2866,2867,2873,2874,2875],{"id":2603,"depth":189,"text":2604},{"id":2644,"depth":189,"text":2645},{"id":2697,"depth":189,"text":2698,"children":2868},[2869,2870,2871,2872],{"id":2704,"depth":448,"text":2705},{"id":2723,"depth":448,"text":2724},{"id":2742,"depth":448,"text":2743},{"id":2761,"depth":448,"text":2762},{"id":2780,"depth":189,"text":2781},{"id":2820,"depth":189,"text":2821},{"id":405,"depth":189,"text":406},"Le Remote Desktop permet d'accéder à un ordinateur à distance. Découvrez ses usages, outils populaires et bonnes pratiques de sécurité.","/images/posts/2026/04/comprendre-le-remote-desktop-acceder-a-son-ordinateur-a-distance.webp",{},"/posts/comprendre-le-remote-desktop-acceder-a-son-ordinateur-a-distance",{"title":2598,"description":2876},"posts/comprendre-le-remote-desktop-acceder-a-son-ordinateur-a-distance",[2883,2884,2620,2885,2593,2626],"remote desktop","réseau","sécurité","xWTeQ6ZXdhGB1frERuney-ryVlHTIPHWmrW9ZGwowpk",{"id":2888,"title":2889,"author":23,"body":2890,"date":2180,"description":3270,"extension":474,"image":1043,"meta":3271,"navigation":477,"path":3272,"readingTime":479,"seo":3273,"stem":3274,"tags":3275,"updatedAt":2180,"__hash__":3280},"posts/posts/introduction-a-linux-ubuntu-guide-complet-pour-debutants.md","Introduction a Linux Ubuntu : Guide Complet pour Debutants",{"type":9,"value":2891,"toc":3257},[2892,2896,2899,2906,2910,2913,2943,2947,2950,2993,2997,3000,3098,3110,3114,3121,3125,3141,3150,3154,3170,3174,3190,3194,3217,3221,3224,3227,3252,3255],[12,2893,2895],{"id":2894},"quest-ce-que-linux-ubuntu","Qu'est-ce que Linux Ubuntu ?",[17,2897,2898],{},"Ubuntu est une distribution Linux basée sur Debian, développée et maintenue par Canonical Ltd. Lancée en 2004, elle est devenue l'une des distributions les plus populaires au monde grâce à sa facilité d'utilisation, sa stabilité et son immense communauté.",[17,2900,2901,2902,2905],{},"Contrairement à Windows ou macOS, Ubuntu est ",[21,2903,2904],{},"open source",", ce qui signifie que son code source est librement accessible, modifiable et redistribuable. Cela en fait un choix idéal pour les développeurs, les administrateurs système et tous ceux qui souhaitent reprendre le contrôle de leur ordinateur.",[12,2907,2909],{"id":2908},"pourquoi-choisir-ubuntu","Pourquoi choisir Ubuntu ?",[17,2911,2912],{},"Plusieurs raisons expliquent le succès d'Ubuntu :",[33,2914,2915,2921,2926,2931,2937],{},[36,2916,2917,2920],{},[21,2918,2919],{},"Gratuité"," : Aucune licence à payer, le système et la plupart des logiciels sont gratuits.",[36,2922,2923,2925],{},[21,2924,2292],{}," : Moins exposé aux virus et malwares que les systèmes propriétaires.",[36,2927,2928,2930],{},[21,2929,2286],{}," : Fonctionne bien même sur du matériel ancien ou peu puissant.",[36,2932,2933,2936],{},[21,2934,2935],{},"Personnalisation"," : Des milliers de thèmes, extensions et environnements de bureau disponibles.",[36,2938,2939,2942],{},[21,2940,2941],{},"Support communautaire"," : Une documentation riche et des forums actifs pour vous aider.",[12,2944,2946],{"id":2945},"installation-pas-à-pas","Installation pas à pas",[17,2948,2949],{},"L'installation d'Ubuntu est aujourd'hui très simplifiée. Voici les étapes principales :",[79,2951,2952,2963,2969,2975,2981,2987],{},[36,2953,2954,2957,2958,436],{},[21,2955,2956],{},"Téléchargement"," : Récupérez l'image ISO sur le site officiel ",[730,2959,2962],{"href":2960,"rel":2961},"https://ubuntu.com/download/desktop",[734],"ubuntu.com",[36,2964,2965,2968],{},[21,2966,2967],{},"Création d'une clé USB bootable"," : Utilisez un outil comme Rufus (Windows) ou BalenaEtcher (multi-plateforme) pour graver l'ISO sur une clé USB.",[36,2970,2971,2974],{},[21,2972,2973],{},"Démarrage"," : Redémarrez votre ordinateur et accédez au menu de démarrage (souvent via F12, F2 ou Suppr) pour booter sur la clé USB.",[36,2976,2977,2980],{},[21,2978,2979],{},"Lancement de l'installateur"," : Choisissez \"Essayer Ubuntu\" pour tester sans installer, ou \"Installer Ubuntu\" pour lancer le processus.",[36,2982,2983,2986],{},[21,2984,2985],{},"Configuration"," : Suivez les instructions à l'écran (choix de la langue, disposition du clavier, partitionnement du disque).",[36,2988,2989,2992],{},[21,2990,2991],{},"Finalisation"," : Créez votre compte utilisateur et redémarrez une fois l'installation terminée.",[12,2994,2996],{"id":2995},"premières-commandes-essentielles","Premières commandes essentielles",[17,2998,2999],{},"Une fois connecté, ouvrez le terminal (Ctrl+Alt+T) pour commencer à maîtriser votre système. Voici quelques commandes de base :",[102,3001,3003],{"className":173,"code":3002,"language":175,"meta":111,"style":111},"# Mettre à jour la liste des paquets disponibles\nsudo apt update\n\n# Mettre à jour les logiciels installés\nsudo apt upgrade\n\n# Afficher le répertoire courant\npwd\n\n# Lister les fichiers d'un dossier\nls -la\n\n# Créer un nouveau dossier\nmkdir mon_dossier\n\n# Se déplacer dans un dossier\ncd mon_dossier\n",[109,3004,3005,3010,3018,3022,3027,3036,3040,3045,3049,3053,3058,3066,3070,3075,3083,3087,3092],{"__ignoreMap":111},[179,3006,3007],{"class":181,"line":182},[179,3008,3009],{"class":185},"# Mettre à jour la liste des paquets disponibles\n",[179,3011,3012,3014,3016],{"class":181,"line":189},[179,3013,567],{"class":192},[179,3015,621],{"class":196},[179,3017,624],{"class":196},[179,3019,3020],{"class":181,"line":448},[179,3021,1404],{"emptyLinePlaceholder":477},[179,3023,3024],{"class":181,"line":775},[179,3025,3026],{"class":185},"# Mettre à jour les logiciels installés\n",[179,3028,3029,3031,3033],{"class":181,"line":852},[179,3030,567],{"class":192},[179,3032,621],{"class":196},[179,3034,3035],{"class":196}," upgrade\n",[179,3037,3038],{"class":181,"line":1351},[179,3039,1404],{"emptyLinePlaceholder":477},[179,3041,3042],{"class":181,"line":1363},[179,3043,3044],{"class":185},"# Afficher le répertoire courant\n",[179,3046,3047],{"class":181,"line":1381},[179,3048,1415],{"class":224},[179,3050,3051],{"class":181,"line":1401},[179,3052,1404],{"emptyLinePlaceholder":477},[179,3054,3055],{"class":181,"line":1407},[179,3056,3057],{"class":185},"# Lister les fichiers d'un dossier\n",[179,3059,3060,3063],{"class":181,"line":1418},[179,3061,3062],{"class":192},"ls",[179,3064,3065],{"class":224}," -la\n",[179,3067,3068],{"class":181,"line":1435},[179,3069,1404],{"emptyLinePlaceholder":477},[179,3071,3072],{"class":181,"line":1440},[179,3073,3074],{"class":185},"# Créer un nouveau dossier\n",[179,3076,3077,3080],{"class":181,"line":1450},[179,3078,3079],{"class":192},"mkdir",[179,3081,3082],{"class":196}," mon_dossier\n",[179,3084,3085],{"class":181,"line":1483},[179,3086,1404],{"emptyLinePlaceholder":477},[179,3088,3089],{"class":181,"line":1503},[179,3090,3091],{"class":185},"# Se déplacer dans un dossier\n",[179,3093,3094,3096],{"class":181,"line":1533},[179,3095,748],{"class":224},[179,3097,3082],{"class":196},[3099,3100,3101],"blockquote",{},[17,3102,3103,3106,3107,3109],{},[21,3104,3105],{},"Note"," : La commande ",[109,3108,567],{}," permet d'exécuter une commande avec les privilèges d'administrateur. Soyez prudent lors de son utilisation.",[12,3111,3113],{"id":3112},"gestion-des-paquets-avec-apt","Gestion des paquets avec APT",[17,3115,3116,3117,3120],{},"Ubuntu utilise le gestionnaire de paquets ",[21,3118,3119],{},"APT"," (Advanced Package Tool) pour installer, mettre à jour et supprimer des logiciels.",[53,3122,3124],{"id":3123},"installer-un-logiciel","Installer un logiciel",[102,3126,3128],{"className":173,"code":3127,"language":175,"meta":111,"style":111},"sudo apt install nom_du_logiciel\n",[109,3129,3130],{"__ignoreMap":111},[179,3131,3132,3134,3136,3138],{"class":181,"line":182},[179,3133,567],{"class":192},[179,3135,621],{"class":196},[179,3137,573],{"class":196},[179,3139,3140],{"class":196}," nom_du_logiciel\n",[17,3142,3143],{},[902,3144,3145,3146,3149],{},"Exemple : ",[109,3147,3148],{},"sudo apt install vlc"," pour installer le lecteur vidéo VLC.",[53,3151,3153],{"id":3152},"désinstaller-un-logiciel","Désinstaller un logiciel",[102,3155,3157],{"className":173,"code":3156,"language":175,"meta":111,"style":111},"sudo apt remove nom_du_logiciel\n",[109,3158,3159],{"__ignoreMap":111},[179,3160,3161,3163,3165,3168],{"class":181,"line":182},[179,3162,567],{"class":192},[179,3164,621],{"class":196},[179,3166,3167],{"class":196}," remove",[179,3169,3140],{"class":196},[53,3171,3173],{"id":3172},"rechercher-un-paquet","Rechercher un paquet",[102,3175,3177],{"className":173,"code":3176,"language":175,"meta":111,"style":111},"apt search mot_cle\n",[109,3178,3179],{"__ignoreMap":111},[179,3180,3181,3184,3187],{"class":181,"line":182},[179,3182,3183],{"class":192},"apt",[179,3185,3186],{"class":196}," search",[179,3188,3189],{"class":196}," mot_cle\n",[53,3191,3193],{"id":3192},"nettoyer-le-système","Nettoyer le système",[102,3195,3197],{"className":173,"code":3196,"language":175,"meta":111,"style":111},"sudo apt autoremove\nsudo apt clean\n",[109,3198,3199,3208],{"__ignoreMap":111},[179,3200,3201,3203,3205],{"class":181,"line":182},[179,3202,567],{"class":192},[179,3204,621],{"class":196},[179,3206,3207],{"class":196}," autoremove\n",[179,3209,3210,3212,3214],{"class":181,"line":189},[179,3211,567],{"class":192},[179,3213,621],{"class":196},[179,3215,3216],{"class":196}," clean\n",[12,3218,3220],{"id":3219},"conclusion-et-ressources","Conclusion et ressources",[17,3222,3223],{},"Ubuntu est une porte d'entrée idéale dans le monde de Linux. Que vous soyez développeur, étudiant ou simple curieux, il offre un environnement puissant et flexible.",[17,3225,3226],{},"Pour aller plus loin, consultez les ressources officielles :",[33,3228,3229,3236,3243],{},[36,3230,3231],{},[730,3232,3235],{"href":3233,"rel":3234},"https://help.ubuntu.com/",[734],"Documentation Ubuntu",[36,3237,3238],{},[730,3239,3242],{"href":3240,"rel":3241},"https://forum.ubuntu-fr.org/",[734],"Forum Ubuntu Francophone",[36,3244,3245,3251],{},[730,3246,3248,3249],{"href":2144,"rel":3247},[734],"Site officiel de ",[21,3250,23],{}," pour d'autres tutoriels techniques.",[17,3253,3254],{},"N'hésitez pas à expérimenter dans une machine virtuelle avant de l'installer sur votre machine principale si vous êtes hésitant. Bonne découverte !",[438,3256,440],{},{"title":111,"searchDepth":189,"depth":189,"links":3258},[3259,3260,3261,3262,3263,3269],{"id":2894,"depth":189,"text":2895},{"id":2908,"depth":189,"text":2909},{"id":2945,"depth":189,"text":2946},{"id":2995,"depth":189,"text":2996},{"id":3112,"depth":189,"text":3113,"children":3264},[3265,3266,3267,3268],{"id":3123,"depth":448,"text":3124},{"id":3152,"depth":448,"text":3153},{"id":3172,"depth":448,"text":3173},{"id":3192,"depth":448,"text":3193},{"id":3219,"depth":189,"text":3220},"Decouvrez Linux Ubuntu, la distribution Linux la plus populaire. Installation, configuration et premiers pas pour bien debuter sur ce systeme open source.",{},"/posts/introduction-a-linux-ubuntu-guide-complet-pour-debutants",{"title":2889,"description":3270},"posts/introduction-a-linux-ubuntu-guide-complet-pour-debutants",[2188,3276,2262,3277,3278,3279,3119],"Ubuntu","Systeme d'exploitation","Debutant","Terminal","LZfNHW1NTSonQCOnMYCbB857rhkaC6NzBdwXsPu4kHo",{"id":3282,"title":3283,"author":7,"body":3284,"date":2180,"description":3701,"extension":474,"image":1043,"meta":3702,"navigation":477,"path":3703,"readingTime":479,"seo":3704,"stem":3705,"tags":3706,"updatedAt":2180,"__hash__":3707},"posts/posts/maitriser-le-transfert-de-fichiers-securise-avec-scp-sous-linux.md","Maîtriser le transfert de fichiers sécurisé avec SCP sous Linux",{"type":9,"value":3285,"toc":3676},[3286,3288,3291,3294,3296,3299,3310,3314,3327,3331,3335,3350,3354,3369,3373,3391,3395,3415,3419,3423,3426,3445,3448,3452,3468,3471,3475,3491,3495,3514,3518,3522,3565,3569,3587,3591,3606,3610,3636,3640,3643,3662,3664,3667,3673],[12,3287,15],{"id":14},[17,3289,3290],{},"SCP (Secure Copy Protocol) est un outil en ligne de commande qui permet de transférer des fichiers entre deux machines de manière sécurisée. Il utilise le protocole SSH pour chiffrer les données pendant le transfert, garantissant ainsi la confidentialité et l'intégrité de vos fichiers.",[17,3292,3293],{},"Dans ce guide, vous découvrirez les bases de SCP, des exemples pratiques et des options avancées pour optimiser vos transferts.",[12,3295,506],{"id":505},[17,3297,3298],{},"Avant d'utiliser SCP, assurez-vous que :",[33,3300,3301,3304,3307],{},[36,3302,3303],{},"SSH est installé et configuré sur les deux machines",[36,3305,3306],{},"Vous disposez des droits d'accès appropriés",[36,3308,3309],{},"Le port SSH (généralement 22) est ouvert sur le firewall",[12,3311,3313],{"id":3312},"syntaxe-de-base","Syntaxe de base",[102,3315,3317],{"className":173,"code":3316,"language":175,"meta":111,"style":111},"scp [options] source destination\n",[109,3318,3319],{"__ignoreMap":111},[179,3320,3321,3324],{"class":181,"line":182},[179,3322,3323],{"class":192},"scp",[179,3325,3326],{"class":681}," [options] source destination\n",[12,3328,3330],{"id":3329},"exemples-fondamentaux","Exemples fondamentaux",[53,3332,3334],{"id":3333},"transférer-un-fichier-vers-un-serveur-distant","Transférer un fichier vers un serveur distant",[102,3336,3338],{"className":173,"code":3337,"language":175,"meta":111,"style":111},"scp fichier.txt utilisateur@192.168.1.100:/chemin/destination\n",[109,3339,3340],{"__ignoreMap":111},[179,3341,3342,3344,3347],{"class":181,"line":182},[179,3343,3323],{"class":192},[179,3345,3346],{"class":196}," fichier.txt",[179,3348,3349],{"class":196}," utilisateur@192.168.1.100:/chemin/destination\n",[53,3351,3353],{"id":3352},"transférer-un-fichier-depuis-un-serveur-distant","Transférer un fichier depuis un serveur distant",[102,3355,3357],{"className":173,"code":3356,"language":175,"meta":111,"style":111},"scp utilisateur@192.168.1.100:/chemin/fichier.txt ./dossier-local/\n",[109,3358,3359],{"__ignoreMap":111},[179,3360,3361,3363,3366],{"class":181,"line":182},[179,3362,3323],{"class":192},[179,3364,3365],{"class":196}," utilisateur@192.168.1.100:/chemin/fichier.txt",[179,3367,3368],{"class":196}," ./dossier-local/\n",[53,3370,3372],{"id":3371},"transférer-un-dossier-entier-récursif","Transférer un dossier entier (récursif)",[102,3374,3376],{"className":173,"code":3375,"language":175,"meta":111,"style":111},"scp -r dossier-local utilisateur@192.168.1.100:/chemin/destination/\n",[109,3377,3378],{"__ignoreMap":111},[179,3379,3380,3382,3385,3388],{"class":181,"line":182},[179,3381,3323],{"class":192},[179,3383,3384],{"class":224}," -r",[179,3386,3387],{"class":196}," dossier-local",[179,3389,3390],{"class":196}," utilisateur@192.168.1.100:/chemin/destination/\n",[53,3392,3394],{"id":3393},"spécifier-un-port-ssh-personnalisé","Spécifier un port SSH personnalisé",[102,3396,3398],{"className":173,"code":3397,"language":175,"meta":111,"style":111},"scp -P 2222 fichier.txt utilisateur@serveur.com:/distant/\n",[109,3399,3400],{"__ignoreMap":111},[179,3401,3402,3404,3407,3410,3412],{"class":181,"line":182},[179,3403,3323],{"class":192},[179,3405,3406],{"class":224}," -P",[179,3408,3409],{"class":224}," 2222",[179,3411,3346],{"class":196},[179,3413,3414],{"class":196}," utilisateur@serveur.com:/distant/\n",[12,3416,3418],{"id":3417},"options-avancées","Options avancées",[53,3420,3422],{"id":3421},"limiter-la-bande-passante","Limiter la bande passante",[17,3424,3425],{},"Pour éviter de saturer le réseau pendant le transfert :",[102,3427,3429],{"className":173,"code":3428,"language":175,"meta":111,"style":111},"scp -l 500 fichier.txt utilisateur@serveur.com:/distant/\n",[109,3430,3431],{"__ignoreMap":111},[179,3432,3433,3435,3438,3441,3443],{"class":181,"line":182},[179,3434,3323],{"class":192},[179,3436,3437],{"class":224}," -l",[179,3439,3440],{"class":224}," 500",[179,3442,3346],{"class":196},[179,3444,3414],{"class":196},[17,3446,3447],{},"La valeur est en Kbit/s (ici 500 Kbit/s = 62.5 Ko/s).",[53,3449,3451],{"id":3450},"afficher-la-progression-du-transfert","Afficher la progression du transfert",[102,3453,3455],{"className":173,"code":3454,"language":175,"meta":111,"style":111},"scp -v fichier.txt utilisateur@serveur.com:/distant/\n",[109,3456,3457],{"__ignoreMap":111},[179,3458,3459,3461,3464,3466],{"class":181,"line":182},[179,3460,3323],{"class":192},[179,3462,3463],{"class":224}," -v",[179,3465,3346],{"class":196},[179,3467,3414],{"class":196},[17,3469,3470],{},"Le mode verbose affiche les détails de la connexion et du transfert.",[53,3472,3474],{"id":3473},"conserver-les-permissions-et-timestamps","Conserver les permissions et timestamps",[102,3476,3478],{"className":173,"code":3477,"language":175,"meta":111,"style":111},"scp -p fichier.txt utilisateur@serveur.com:/distant/\n",[109,3479,3480],{"__ignoreMap":111},[179,3481,3482,3484,3487,3489],{"class":181,"line":182},[179,3483,3323],{"class":192},[179,3485,3486],{"class":224}," -p",[179,3488,3346],{"class":196},[179,3490,3414],{"class":196},[53,3492,3494],{"id":3493},"utiliser-une-clé-ssh-spécifique","Utiliser une clé SSH spécifique",[102,3496,3498],{"className":173,"code":3497,"language":175,"meta":111,"style":111},"scp -i ~/.ssh/ma_cle_privée fichier.txt utilisateur@serveur.com:/distant/\n",[109,3499,3500],{"__ignoreMap":111},[179,3501,3502,3504,3507,3510,3512],{"class":181,"line":182},[179,3503,3323],{"class":192},[179,3505,3506],{"class":224}," -i",[179,3508,3509],{"class":196}," ~/.ssh/ma_cle_privée",[179,3511,3346],{"class":196},[179,3513,3414],{"class":196},[12,3515,3517],{"id":3516},"exemples-pratiques-courants","Exemples pratiques courants",[53,3519,3521],{"id":3520},"sauvegarde-automatique-vers-un-serveur-distant","Sauvegarde automatique vers un serveur distant",[102,3523,3525],{"className":173,"code":3524,"language":175,"meta":111,"style":111},"#!/bin/bash\nDATE=$(date +%Y%m%d)\nscp -r /var/www/html utilisateur@backup-server:/sauvegardes/site-$DATE\n",[109,3526,3527,3532,3550],{"__ignoreMap":111},[179,3528,3529],{"class":181,"line":182},[179,3530,3531],{"class":185},"#!/bin/bash\n",[179,3533,3534,3537,3539,3542,3545,3548],{"class":181,"line":189},[179,3535,3536],{"class":681},"DATE",[179,3538,685],{"class":549},[179,3540,3541],{"class":681},"$(",[179,3543,3544],{"class":192},"date",[179,3546,3547],{"class":196}," +%Y%m%d",[179,3549,1480],{"class":681},[179,3551,3552,3554,3556,3559,3562],{"class":181,"line":448},[179,3553,3323],{"class":192},[179,3555,3384],{"class":224},[179,3557,3558],{"class":196}," /var/www/html",[179,3560,3561],{"class":196}," utilisateur@backup-server:/sauvegardes/site-",[179,3563,3564],{"class":681},"$DATE\n",[53,3566,3568],{"id":3567},"transférer-plusieurs-fichiers-avec-un-motif","Transférer plusieurs fichiers avec un motif",[102,3570,3572],{"className":173,"code":3571,"language":175,"meta":111,"style":111},"scp *.log utilisateur@serveur.com:/logs/\n",[109,3573,3574],{"__ignoreMap":111},[179,3575,3576,3578,3581,3584],{"class":181,"line":182},[179,3577,3323],{"class":192},[179,3579,3580],{"class":224}," *",[179,3582,3583],{"class":196},".log",[179,3585,3586],{"class":196}," utilisateur@serveur.com:/logs/\n",[53,3588,3590],{"id":3589},"transférer-entre-deux-serveurs-distants-depuis-votre-machine","Transférer entre deux serveurs distants (depuis votre machine)",[102,3592,3594],{"className":173,"code":3593,"language":175,"meta":111,"style":111},"scp utilisateur1@serveur1:/chemin/fichier.txt utilisateur2@serveur2:/chemin/\n",[109,3595,3596],{"__ignoreMap":111},[179,3597,3598,3600,3603],{"class":181,"line":182},[179,3599,3323],{"class":192},[179,3601,3602],{"class":196}," utilisateur1@serveur1:/chemin/fichier.txt",[179,3604,3605],{"class":196}," utilisateur2@serveur2:/chemin/\n",[12,3607,3609],{"id":3608},"bonnes-pratiques","Bonnes pratiques",[33,3611,3612,3618,3624,3630],{},[36,3613,3614,3617],{},[21,3615,3616],{},"Toujours vérifier la destination"," avant d'exécuter la commande",[36,3619,3620,3623],{},[21,3621,3622],{},"Utiliser des clés SSH"," plutôt que des mots de passe pour l'automatisation",[36,3625,3626,3629],{},[21,3627,3628],{},"Compresser les gros fichiers"," avant transfert pour gagner du temps",[36,3631,3632,3635],{},[21,3633,3634],{},"Tester avec un petit fichier"," avant de transférer des données importantes",[12,3637,3639],{"id":3638},"alternatives-à-scp","Alternatives à SCP",[17,3641,3642],{},"Bien que SCP soit largement utilisé, considérez ces alternatives :",[33,3644,3645,3651,3656],{},[36,3646,3647,3650],{},[21,3648,3649],{},"rsync"," : Plus efficace pour les transferts incrémentiels",[36,3652,3653,3655],{},[21,3654,1983],{}," : Interface interactive avec plus de fonctionnalités",[36,3657,3658,3661],{},[21,3659,3660],{},"rclone"," : Idéal pour les transferts vers le cloud",[12,3663,406],{"id":405},[17,3665,3666],{},"SCP reste un outil indispensable pour tout administrateur système. Simple, sécurisé et disponible par défaut sur la plupart des systèmes Unix/Linux, il permet de transférer des fichiers rapidement et en toute confiance.",[17,3668,3669,3670],{},"Pour aller plus loin, consultez la page de manuel : ",[109,3671,3672],{},"man scp",[438,3674,3675],{},"html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}",{"title":111,"searchDepth":189,"depth":189,"links":3677},[3678,3679,3680,3681,3687,3693,3698,3699,3700],{"id":14,"depth":189,"text":15},{"id":505,"depth":189,"text":506},{"id":3312,"depth":189,"text":3313},{"id":3329,"depth":189,"text":3330,"children":3682},[3683,3684,3685,3686],{"id":3333,"depth":448,"text":3334},{"id":3352,"depth":448,"text":3353},{"id":3371,"depth":448,"text":3372},{"id":3393,"depth":448,"text":3394},{"id":3417,"depth":189,"text":3418,"children":3688},[3689,3690,3691,3692],{"id":3421,"depth":448,"text":3422},{"id":3450,"depth":448,"text":3451},{"id":3473,"depth":448,"text":3474},{"id":3493,"depth":448,"text":3494},{"id":3516,"depth":189,"text":3517,"children":3694},[3695,3696,3697],{"id":3520,"depth":448,"text":3521},{"id":3567,"depth":448,"text":3568},{"id":3589,"depth":448,"text":3590},{"id":3608,"depth":189,"text":3609},{"id":3638,"depth":189,"text":3639},{"id":405,"depth":189,"text":406},"Apprenez à utiliser SCP pour transférer des fichiers sécurisés entre machines. Guide complet avec exemples, options avancées et bonnes pratiques Linux.",{},"/posts/maitriser-le-transfert-de-fichiers-securise-avec-scp-sous-linux",{"title":3283,"description":3701},"posts/maitriser-le-transfert-de-fichiers-securise-avec-scp-sous-linux",[2592,3323,2519,2591,2884,2885],"5LolY1scQTVpCz93KqxvYs1lK_ekLsP27qv3Wdn40Ik",{"id":3709,"title":3710,"author":7,"body":3711,"date":2180,"description":5855,"extension":474,"image":479,"meta":5856,"navigation":477,"path":5857,"readingTime":479,"seo":5858,"stem":5859,"tags":5860,"updatedAt":479,"__hash__":5862},"posts/posts/test-syntax-highlighting.md","Coloration syntaxique des blocs de code",{"type":9,"value":3712,"toc":5840},[3713,3717,3872,3876,4036,4040,4364,4368,4519,4523,4735,4738,4838,4841,4949,4953,5053,5057,5133,5137,5325,5329,5442,5445,5620,5624,5837],[12,3714,3716],{"id":3715},"javascript","JavaScript",[102,3718,3721],{"className":3719,"code":3720,"language":3715,"meta":111,"style":111},"language-javascript shiki shiki-themes github-light github-dark","// Fetch API avec async/await\nasync function fetchUsers() {\n  const response = await fetch('/api/users');\n  const data = await response.json();\n  return data.filter(user => user.active);\n}\n\nconst greeting = (name) => `Bonjour, ${name} !`;\nconsole.log(greeting('monde'));\n",[109,3722,3723,3728,3742,3768,3787,3810,3815,3819,3851],{"__ignoreMap":111},[179,3724,3725],{"class":181,"line":182},[179,3726,3727],{"class":185},"// Fetch API avec async/await\n",[179,3729,3730,3733,3736,3739],{"class":181,"line":189},[179,3731,3732],{"class":549},"async",[179,3734,3735],{"class":549}," function",[179,3737,3738],{"class":192}," fetchUsers",[179,3740,3741],{"class":681},"() {\n",[179,3743,3744,3747,3750,3753,3756,3759,3762,3765],{"class":181,"line":448},[179,3745,3746],{"class":549},"  const",[179,3748,3749],{"class":224}," response",[179,3751,3752],{"class":549}," =",[179,3754,3755],{"class":549}," await",[179,3757,3758],{"class":192}," fetch",[179,3760,3761],{"class":681},"(",[179,3763,3764],{"class":196},"'/api/users'",[179,3766,3767],{"class":681},");\n",[179,3769,3770,3772,3774,3776,3778,3781,3784],{"class":181,"line":775},[179,3771,3746],{"class":549},[179,3773,1666],{"class":224},[179,3775,3752],{"class":549},[179,3777,3755],{"class":549},[179,3779,3780],{"class":681}," response.",[179,3782,3783],{"class":192},"json",[179,3785,3786],{"class":681},"();\n",[179,3788,3789,3792,3795,3798,3800,3804,3807],{"class":181,"line":852},[179,3790,3791],{"class":549},"  return",[179,3793,3794],{"class":681}," data.",[179,3796,3797],{"class":192},"filter",[179,3799,3761],{"class":681},[179,3801,3803],{"class":3802},"s4XuR","user",[179,3805,3806],{"class":549}," =>",[179,3808,3809],{"class":681}," user.active);\n",[179,3811,3812],{"class":181,"line":1351},[179,3813,3814],{"class":681},"}\n",[179,3816,3817],{"class":181,"line":1363},[179,3818,1404],{"emptyLinePlaceholder":477},[179,3820,3821,3824,3827,3829,3831,3834,3837,3840,3843,3845,3848],{"class":181,"line":1381},[179,3822,3823],{"class":549},"const",[179,3825,3826],{"class":192}," greeting",[179,3828,3752],{"class":549},[179,3830,1468],{"class":681},[179,3832,3833],{"class":3802},"name",[179,3835,3836],{"class":681},") ",[179,3838,3839],{"class":549},"=>",[179,3841,3842],{"class":196}," `Bonjour, ${",[179,3844,3833],{"class":681},[179,3846,3847],{"class":196},"} !`",[179,3849,3850],{"class":681},";\n",[179,3852,3853,3856,3859,3861,3864,3866,3869],{"class":181,"line":1401},[179,3854,3855],{"class":681},"console.",[179,3857,3858],{"class":192},"log",[179,3860,3761],{"class":681},[179,3862,3863],{"class":192},"greeting",[179,3865,3761],{"class":681},[179,3867,3868],{"class":196},"'monde'",[179,3870,3871],{"class":681},"));\n",[12,3873,3875],{"id":3874},"typescript","TypeScript",[102,3877,3880],{"className":3878,"code":3879,"language":3874,"meta":111,"style":111},"language-typescript shiki shiki-themes github-light github-dark","interface User {\n  id: number;\n  name: string;\n  email: string;\n  roles: string[];\n}\n\nfunction getAdmin(users: User[]): User | undefined {\n  return users.find(u => u.roles.includes('admin'));\n}\n\nconst count: number = 42;\n",[109,3881,3882,3893,3906,3918,3929,3941,3945,3949,3980,4010,4014,4018],{"__ignoreMap":111},[179,3883,3884,3887,3890],{"class":181,"line":182},[179,3885,3886],{"class":549},"interface",[179,3888,3889],{"class":192}," User",[179,3891,3892],{"class":681}," {\n",[179,3894,3895,3898,3901,3904],{"class":181,"line":189},[179,3896,3897],{"class":3802},"  id",[179,3899,3900],{"class":549},":",[179,3902,3903],{"class":224}," number",[179,3905,3850],{"class":681},[179,3907,3908,3911,3913,3916],{"class":181,"line":448},[179,3909,3910],{"class":3802},"  name",[179,3912,3900],{"class":549},[179,3914,3915],{"class":224}," string",[179,3917,3850],{"class":681},[179,3919,3920,3923,3925,3927],{"class":181,"line":775},[179,3921,3922],{"class":3802},"  email",[179,3924,3900],{"class":549},[179,3926,3915],{"class":224},[179,3928,3850],{"class":681},[179,3930,3931,3934,3936,3938],{"class":181,"line":852},[179,3932,3933],{"class":3802},"  roles",[179,3935,3900],{"class":549},[179,3937,3915],{"class":224},[179,3939,3940],{"class":681},"[];\n",[179,3942,3943],{"class":181,"line":1351},[179,3944,3814],{"class":681},[179,3946,3947],{"class":181,"line":1363},[179,3948,1404],{"emptyLinePlaceholder":477},[179,3950,3951,3954,3957,3959,3962,3964,3966,3969,3971,3973,3975,3978],{"class":181,"line":1381},[179,3952,3953],{"class":549},"function",[179,3955,3956],{"class":192}," getAdmin",[179,3958,3761],{"class":681},[179,3960,3961],{"class":3802},"users",[179,3963,3900],{"class":549},[179,3965,3889],{"class":192},[179,3967,3968],{"class":681},"[])",[179,3970,3900],{"class":549},[179,3972,3889],{"class":192},[179,3974,550],{"class":549},[179,3976,3977],{"class":224}," undefined",[179,3979,3892],{"class":681},[179,3981,3982,3984,3987,3990,3992,3995,3997,4000,4003,4005,4008],{"class":181,"line":1401},[179,3983,3791],{"class":549},[179,3985,3986],{"class":681}," users.",[179,3988,3989],{"class":192},"find",[179,3991,3761],{"class":681},[179,3993,3994],{"class":3802},"u",[179,3996,3806],{"class":549},[179,3998,3999],{"class":681}," u.roles.",[179,4001,4002],{"class":192},"includes",[179,4004,3761],{"class":681},[179,4006,4007],{"class":196},"'admin'",[179,4009,3871],{"class":681},[179,4011,4012],{"class":181,"line":1407},[179,4013,3814],{"class":681},[179,4015,4016],{"class":181,"line":1418},[179,4017,1404],{"emptyLinePlaceholder":477},[179,4019,4020,4022,4025,4027,4029,4031,4034],{"class":181,"line":1435},[179,4021,3823],{"class":549},[179,4023,4024],{"class":224}," count",[179,4026,3900],{"class":549},[179,4028,3903],{"class":224},[179,4030,3752],{"class":549},[179,4032,4033],{"class":224}," 42",[179,4035,3850],{"class":681},[12,4037,4039],{"id":4038},"vue","Vue",[102,4041,4044],{"className":4042,"code":4043,"language":4038,"meta":111,"style":111},"language-vue shiki shiki-themes github-light github-dark","\u003Ctemplate>\n  \u003Cdiv class=\"card\">\n    \u003Ch2>{{ title }}\u003C/h2>\n    \u003Cp v-if=\"description\">{{ description }}\u003C/p>\n    \u003Cbutton @click=\"handleClick\">Valider\u003C/button>\n  \u003C/div>\n\u003C/template>\n\n\u003Cscript setup lang=\"ts\">\nconst props = defineProps\u003C{\n  title: string;\n  description?: string;\n}>();\n\nconst emit = defineEmits\u003C{\n  submit: [value: string];\n}>();\n\nfunction handleClick() {\n  emit('submit', props.title);\n}\n\u003C/script>\n\n\u003Cstyle scoped>\n.card {\n  padding: 1rem;\n  border-radius: 8px;\n}\n\u003C/style>\n",[109,4045,4046,4058,4076,4090,4111,4133,4142,4151,4155,4175,4190,4201,4213,4218,4222,4236,4258,4262,4266,4275,4288,4292,4300,4304,4315,4322,4337,4352,4356],{"__ignoreMap":111},[179,4047,4048,4051,4055],{"class":181,"line":182},[179,4049,4050],{"class":681},"\u003C",[179,4052,4054],{"class":4053},"s9eBZ","template",[179,4056,4057],{"class":681},">\n",[179,4059,4060,4063,4066,4069,4071,4074],{"class":181,"line":189},[179,4061,4062],{"class":681},"  \u003C",[179,4064,4065],{"class":4053},"div",[179,4067,4068],{"class":192}," class",[179,4070,685],{"class":681},[179,4072,4073],{"class":196},"\"card\"",[179,4075,4057],{"class":681},[179,4077,4078,4081,4083,4086,4088],{"class":181,"line":448},[179,4079,4080],{"class":681},"    \u003C",[179,4082,12],{"class":4053},[179,4084,4085],{"class":681},">{{ title }}\u003C/",[179,4087,12],{"class":4053},[179,4089,4057],{"class":681},[179,4091,4092,4094,4096,4099,4101,4104,4107,4109],{"class":181,"line":775},[179,4093,4080],{"class":681},[179,4095,17],{"class":4053},[179,4097,4098],{"class":192}," v-if",[179,4100,685],{"class":681},[179,4102,4103],{"class":196},"\"description\"",[179,4105,4106],{"class":681},">{{ description }}\u003C/",[179,4108,17],{"class":4053},[179,4110,4057],{"class":681},[179,4112,4113,4115,4118,4121,4123,4126,4129,4131],{"class":181,"line":852},[179,4114,4080],{"class":681},[179,4116,4117],{"class":4053},"button",[179,4119,4120],{"class":192}," @click",[179,4122,685],{"class":681},[179,4124,4125],{"class":196},"\"handleClick\"",[179,4127,4128],{"class":681},">Valider\u003C/",[179,4130,4117],{"class":4053},[179,4132,4057],{"class":681},[179,4134,4135,4138,4140],{"class":181,"line":1351},[179,4136,4137],{"class":681},"  \u003C/",[179,4139,4065],{"class":4053},[179,4141,4057],{"class":681},[179,4143,4144,4147,4149],{"class":181,"line":1363},[179,4145,4146],{"class":681},"\u003C/",[179,4148,4054],{"class":4053},[179,4150,4057],{"class":681},[179,4152,4153],{"class":181,"line":1381},[179,4154,1404],{"emptyLinePlaceholder":477},[179,4156,4157,4159,4162,4165,4168,4170,4173],{"class":181,"line":1401},[179,4158,4050],{"class":681},[179,4160,4161],{"class":4053},"script",[179,4163,4164],{"class":192}," setup",[179,4166,4167],{"class":192}," lang",[179,4169,685],{"class":681},[179,4171,4172],{"class":196},"\"ts\"",[179,4174,4057],{"class":681},[179,4176,4177,4179,4182,4184,4187],{"class":181,"line":1407},[179,4178,3823],{"class":549},[179,4180,4181],{"class":224}," props",[179,4183,3752],{"class":549},[179,4185,4186],{"class":192}," defineProps",[179,4188,4189],{"class":681},"\u003C{\n",[179,4191,4192,4195,4197,4199],{"class":181,"line":1418},[179,4193,4194],{"class":3802},"  title",[179,4196,3900],{"class":549},[179,4198,3915],{"class":224},[179,4200,3850],{"class":681},[179,4202,4203,4206,4209,4211],{"class":181,"line":1435},[179,4204,4205],{"class":3802},"  description",[179,4207,4208],{"class":549},"?:",[179,4210,3915],{"class":224},[179,4212,3850],{"class":681},[179,4214,4215],{"class":181,"line":1440},[179,4216,4217],{"class":681},"}>();\n",[179,4219,4220],{"class":181,"line":1450},[179,4221,1404],{"emptyLinePlaceholder":477},[179,4223,4224,4226,4229,4231,4234],{"class":181,"line":1483},[179,4225,3823],{"class":549},[179,4227,4228],{"class":224}," emit",[179,4230,3752],{"class":549},[179,4232,4233],{"class":192}," defineEmits",[179,4235,4189],{"class":681},[179,4237,4238,4241,4243,4246,4249,4252,4255],{"class":181,"line":1503},[179,4239,4240],{"class":3802},"  submit",[179,4242,3900],{"class":549},[179,4244,4245],{"class":681}," [",[179,4247,4248],{"class":192},"value",[179,4250,4251],{"class":681},": ",[179,4253,4254],{"class":224},"string",[179,4256,4257],{"class":681},"];\n",[179,4259,4260],{"class":181,"line":1533},[179,4261,4217],{"class":681},[179,4263,4264],{"class":181,"line":1557},[179,4265,1404],{"emptyLinePlaceholder":477},[179,4267,4268,4270,4273],{"class":181,"line":1583},[179,4269,3953],{"class":549},[179,4271,4272],{"class":192}," handleClick",[179,4274,3741],{"class":681},[179,4276,4277,4280,4282,4285],{"class":181,"line":1598},[179,4278,4279],{"class":192},"  emit",[179,4281,3761],{"class":681},[179,4283,4284],{"class":196},"'submit'",[179,4286,4287],{"class":681},", props.title);\n",[179,4289,4290],{"class":181,"line":1603},[179,4291,3814],{"class":681},[179,4293,4294,4296,4298],{"class":181,"line":1615},[179,4295,4146],{"class":681},[179,4297,4161],{"class":4053},[179,4299,4057],{"class":681},[179,4301,4302],{"class":181,"line":1629},[179,4303,1404],{"emptyLinePlaceholder":477},[179,4305,4306,4308,4310,4313],{"class":181,"line":1653},[179,4307,4050],{"class":681},[179,4309,438],{"class":4053},[179,4311,4312],{"class":192}," scoped",[179,4314,4057],{"class":681},[179,4316,4317,4320],{"class":181,"line":1686},[179,4318,4319],{"class":192},".card",[179,4321,3892],{"class":681},[179,4323,4324,4327,4329,4332,4335],{"class":181,"line":1709},[179,4325,4326],{"class":224},"  padding",[179,4328,4251],{"class":681},[179,4330,4331],{"class":224},"1",[179,4333,4334],{"class":549},"rem",[179,4336,3850],{"class":681},[179,4338,4339,4342,4344,4347,4350],{"class":181,"line":1720},[179,4340,4341],{"class":224},"  border-radius",[179,4343,4251],{"class":681},[179,4345,4346],{"class":224},"8",[179,4348,4349],{"class":549},"px",[179,4351,3850],{"class":681},[179,4353,4354],{"class":181,"line":1741},[179,4355,3814],{"class":681},[179,4357,4358,4360,4362],{"class":181,"line":1746},[179,4359,4146],{"class":681},[179,4361,438],{"class":4053},[179,4363,4057],{"class":681},[12,4365,4367],{"id":4366},"css","CSS",[102,4369,4372],{"className":4370,"code":4371,"language":4366,"meta":111,"style":111},"language-css shiki shiki-themes github-light github-dark",":root {\n  --primary: #0284c7;\n  --bg: #f8fafc;\n}\n\n.container {\n  max-width: 1200px;\n  margin: 0 auto;\n  padding: 2rem;\n}\n\n@media (max-width: 768px) {\n  .container {\n    padding: 1rem;\n  }\n}\n",[109,4373,4374,4381,4393,4405,4409,4413,4420,4434,4449,4462,4466,4470,4490,4497,4510,4515],{"__ignoreMap":111},[179,4375,4376,4379],{"class":181,"line":182},[179,4377,4378],{"class":192},":root",[179,4380,3892],{"class":681},[179,4382,4383,4386,4388,4391],{"class":181,"line":189},[179,4384,4385],{"class":3802},"  --primary",[179,4387,4251],{"class":681},[179,4389,4390],{"class":224},"#0284c7",[179,4392,3850],{"class":681},[179,4394,4395,4398,4400,4403],{"class":181,"line":448},[179,4396,4397],{"class":3802},"  --bg",[179,4399,4251],{"class":681},[179,4401,4402],{"class":224},"#f8fafc",[179,4404,3850],{"class":681},[179,4406,4407],{"class":181,"line":775},[179,4408,3814],{"class":681},[179,4410,4411],{"class":181,"line":852},[179,4412,1404],{"emptyLinePlaceholder":477},[179,4414,4415,4418],{"class":181,"line":1351},[179,4416,4417],{"class":192},".container",[179,4419,3892],{"class":681},[179,4421,4422,4425,4427,4430,4432],{"class":181,"line":1363},[179,4423,4424],{"class":224},"  max-width",[179,4426,4251],{"class":681},[179,4428,4429],{"class":224},"1200",[179,4431,4349],{"class":549},[179,4433,3850],{"class":681},[179,4435,4436,4439,4441,4444,4447],{"class":181,"line":1381},[179,4437,4438],{"class":224},"  margin",[179,4440,4251],{"class":681},[179,4442,4443],{"class":224},"0",[179,4445,4446],{"class":224}," auto",[179,4448,3850],{"class":681},[179,4450,4451,4453,4455,4458,4460],{"class":181,"line":1401},[179,4452,4326],{"class":224},[179,4454,4251],{"class":681},[179,4456,4457],{"class":224},"2",[179,4459,4334],{"class":549},[179,4461,3850],{"class":681},[179,4463,4464],{"class":181,"line":1407},[179,4465,3814],{"class":681},[179,4467,4468],{"class":181,"line":1418},[179,4469,1404],{"emptyLinePlaceholder":477},[179,4471,4472,4475,4477,4480,4482,4485,4487],{"class":181,"line":1435},[179,4473,4474],{"class":549},"@media",[179,4476,1468],{"class":681},[179,4478,4479],{"class":224},"max-width",[179,4481,4251],{"class":681},[179,4483,4484],{"class":224},"768",[179,4486,4349],{"class":549},[179,4488,4489],{"class":681},") {\n",[179,4491,4492,4495],{"class":181,"line":1440},[179,4493,4494],{"class":192},"  .container",[179,4496,3892],{"class":681},[179,4498,4499,4502,4504,4506,4508],{"class":181,"line":1450},[179,4500,4501],{"class":224},"    padding",[179,4503,4251],{"class":681},[179,4505,4331],{"class":224},[179,4507,4334],{"class":549},[179,4509,3850],{"class":681},[179,4511,4512],{"class":181,"line":1483},[179,4513,4514],{"class":681},"  }\n",[179,4516,4517],{"class":181,"line":1503},[179,4518,3814],{"class":681},[12,4520,4522],{"id":4521},"html","HTML",[102,4524,4527],{"className":4525,"code":4526,"language":4521,"meta":111,"style":111},"language-html shiki shiki-themes github-light github-dark","\u003C!DOCTYPE html>\n\u003Chtml lang=\"fr\">\n\u003Chead>\n  \u003Cmeta charset=\"UTF-8\">\n  \u003Ctitle>Ma page\u003C/title>\n  \u003Clink rel=\"stylesheet\" href=\"/style.css\">\n\u003C/head>\n\u003Cbody>\n  \u003Cmain id=\"app\">\n    \u003Ch1>Bienvenue\u003C/h1>\n    \u003Cp class=\"intro\">Ceci est un test.\u003C/p>\n  \u003C/main>\n  \u003Cscript src=\"/app.js\">\u003C/script>\n\u003C/body>\n\u003C/html>\n",[109,4528,4529,4542,4557,4566,4583,4597,4622,4630,4639,4656,4670,4690,4698,4719,4727],{"__ignoreMap":111},[179,4530,4531,4534,4537,4540],{"class":181,"line":182},[179,4532,4533],{"class":681},"\u003C!",[179,4535,4536],{"class":4053},"DOCTYPE",[179,4538,4539],{"class":192}," html",[179,4541,4057],{"class":681},[179,4543,4544,4546,4548,4550,4552,4555],{"class":181,"line":189},[179,4545,4050],{"class":681},[179,4547,4521],{"class":4053},[179,4549,4167],{"class":192},[179,4551,685],{"class":681},[179,4553,4554],{"class":196},"\"fr\"",[179,4556,4057],{"class":681},[179,4558,4559,4561,4564],{"class":181,"line":448},[179,4560,4050],{"class":681},[179,4562,4563],{"class":4053},"head",[179,4565,4057],{"class":681},[179,4567,4568,4570,4573,4576,4578,4581],{"class":181,"line":775},[179,4569,4062],{"class":681},[179,4571,4572],{"class":4053},"meta",[179,4574,4575],{"class":192}," charset",[179,4577,685],{"class":681},[179,4579,4580],{"class":196},"\"UTF-8\"",[179,4582,4057],{"class":681},[179,4584,4585,4587,4590,4593,4595],{"class":181,"line":852},[179,4586,4062],{"class":681},[179,4588,4589],{"class":4053},"title",[179,4591,4592],{"class":681},">Ma page\u003C/",[179,4594,4589],{"class":4053},[179,4596,4057],{"class":681},[179,4598,4599,4601,4604,4607,4609,4612,4615,4617,4620],{"class":181,"line":1351},[179,4600,4062],{"class":681},[179,4602,4603],{"class":4053},"link",[179,4605,4606],{"class":192}," rel",[179,4608,685],{"class":681},[179,4610,4611],{"class":196},"\"stylesheet\"",[179,4613,4614],{"class":192}," href",[179,4616,685],{"class":681},[179,4618,4619],{"class":196},"\"/style.css\"",[179,4621,4057],{"class":681},[179,4623,4624,4626,4628],{"class":181,"line":1363},[179,4625,4146],{"class":681},[179,4627,4563],{"class":4053},[179,4629,4057],{"class":681},[179,4631,4632,4634,4637],{"class":181,"line":1381},[179,4633,4050],{"class":681},[179,4635,4636],{"class":4053},"body",[179,4638,4057],{"class":681},[179,4640,4641,4643,4646,4649,4651,4654],{"class":181,"line":1401},[179,4642,4062],{"class":681},[179,4644,4645],{"class":4053},"main",[179,4647,4648],{"class":192}," id",[179,4650,685],{"class":681},[179,4652,4653],{"class":196},"\"app\"",[179,4655,4057],{"class":681},[179,4657,4658,4660,4663,4666,4668],{"class":181,"line":1407},[179,4659,4080],{"class":681},[179,4661,4662],{"class":4053},"h1",[179,4664,4665],{"class":681},">Bienvenue\u003C/",[179,4667,4662],{"class":4053},[179,4669,4057],{"class":681},[179,4671,4672,4674,4676,4678,4680,4683,4686,4688],{"class":181,"line":1418},[179,4673,4080],{"class":681},[179,4675,17],{"class":4053},[179,4677,4068],{"class":192},[179,4679,685],{"class":681},[179,4681,4682],{"class":196},"\"intro\"",[179,4684,4685],{"class":681},">Ceci est un test.\u003C/",[179,4687,17],{"class":4053},[179,4689,4057],{"class":681},[179,4691,4692,4694,4696],{"class":181,"line":1435},[179,4693,4137],{"class":681},[179,4695,4645],{"class":4053},[179,4697,4057],{"class":681},[179,4699,4700,4702,4704,4707,4709,4712,4715,4717],{"class":181,"line":1440},[179,4701,4062],{"class":681},[179,4703,4161],{"class":4053},[179,4705,4706],{"class":192}," src",[179,4708,685],{"class":681},[179,4710,4711],{"class":196},"\"/app.js\"",[179,4713,4714],{"class":681},">\u003C/",[179,4716,4161],{"class":4053},[179,4718,4057],{"class":681},[179,4720,4721,4723,4725],{"class":181,"line":1450},[179,4722,4146],{"class":681},[179,4724,4636],{"class":4053},[179,4726,4057],{"class":681},[179,4728,4729,4731,4733],{"class":181,"line":1483},[179,4730,4146],{"class":681},[179,4732,4521],{"class":4053},[179,4734,4057],{"class":681},[12,4736,4737],{"id":175},"Bash",[102,4739,4741],{"className":173,"code":4740,"language":175,"meta":111,"style":111},"#!/bin/bash\n\n# Deploiement automatique\necho \"Demarrage du deploy...\"\n\nif [ -d \"./dist\" ]; then\n  rsync -avz ./dist/ user@server:/var/www/app/\n  echo \"Deploy termine avec succes\"\nelse\n  echo \"Erreur: dossier dist introuvable\" >&2\n  exit 1\nfi\n",[109,4742,4743,4747,4751,4756,4764,4768,4788,4802,4810,4815,4825,4833],{"__ignoreMap":111},[179,4744,4745],{"class":181,"line":182},[179,4746,3531],{"class":185},[179,4748,4749],{"class":181,"line":189},[179,4750,1404],{"emptyLinePlaceholder":477},[179,4752,4753],{"class":181,"line":448},[179,4754,4755],{"class":185},"# Deploiement automatique\n",[179,4757,4758,4761],{"class":181,"line":775},[179,4759,4760],{"class":224},"echo",[179,4762,4763],{"class":196}," \"Demarrage du deploy...\"\n",[179,4765,4766],{"class":181,"line":852},[179,4767,1404],{"emptyLinePlaceholder":477},[179,4769,4770,4773,4776,4779,4782,4785],{"class":181,"line":1351},[179,4771,4772],{"class":549},"if",[179,4774,4775],{"class":681}," [ ",[179,4777,4778],{"class":549},"-d",[179,4780,4781],{"class":196}," \"./dist\"",[179,4783,4784],{"class":681}," ]; ",[179,4786,4787],{"class":549},"then\n",[179,4789,4790,4793,4796,4799],{"class":181,"line":1363},[179,4791,4792],{"class":192},"  rsync",[179,4794,4795],{"class":224}," -avz",[179,4797,4798],{"class":196}," ./dist/",[179,4800,4801],{"class":196}," user@server:/var/www/app/\n",[179,4803,4804,4807],{"class":181,"line":1381},[179,4805,4806],{"class":224},"  echo",[179,4808,4809],{"class":196}," \"Deploy termine avec succes\"\n",[179,4811,4812],{"class":181,"line":1401},[179,4813,4814],{"class":549},"else\n",[179,4816,4817,4819,4822],{"class":181,"line":1407},[179,4818,4806],{"class":224},[179,4820,4821],{"class":196}," \"Erreur: dossier dist introuvable\"",[179,4823,4824],{"class":549}," >&2\n",[179,4826,4827,4830],{"class":181,"line":1418},[179,4828,4829],{"class":224},"  exit",[179,4831,4832],{"class":224}," 1\n",[179,4834,4835],{"class":181,"line":1435},[179,4836,4837],{"class":549},"fi\n",[12,4839,4840],{"id":3783},"JSON",[102,4842,4845],{"className":4843,"code":4844,"language":3783,"meta":111,"style":111},"language-json shiki shiki-themes github-light github-dark","{\n  \"name\": \"mon-projet\",\n  \"version\": \"1.0.0\",\n  \"scripts\": {\n    \"dev\": \"nuxt dev\",\n    \"build\": \"nuxt build\",\n    \"preview\": \"nuxt preview\"\n  },\n  \"dependencies\": {\n    \"@nuxt/content\": \"^3.11.0\"\n  }\n}\n",[109,4846,4847,4852,4865,4877,4885,4897,4909,4919,4924,4931,4941,4945],{"__ignoreMap":111},[179,4848,4849],{"class":181,"line":182},[179,4850,4851],{"class":681},"{\n",[179,4853,4854,4857,4859,4862],{"class":181,"line":189},[179,4855,4856],{"class":224},"  \"name\"",[179,4858,4251],{"class":681},[179,4860,4861],{"class":196},"\"mon-projet\"",[179,4863,4864],{"class":681},",\n",[179,4866,4867,4870,4872,4875],{"class":181,"line":448},[179,4868,4869],{"class":224},"  \"version\"",[179,4871,4251],{"class":681},[179,4873,4874],{"class":196},"\"1.0.0\"",[179,4876,4864],{"class":681},[179,4878,4879,4882],{"class":181,"line":775},[179,4880,4881],{"class":224},"  \"scripts\"",[179,4883,4884],{"class":681},": {\n",[179,4886,4887,4890,4892,4895],{"class":181,"line":852},[179,4888,4889],{"class":224},"    \"dev\"",[179,4891,4251],{"class":681},[179,4893,4894],{"class":196},"\"nuxt dev\"",[179,4896,4864],{"class":681},[179,4898,4899,4902,4904,4907],{"class":181,"line":1351},[179,4900,4901],{"class":224},"    \"build\"",[179,4903,4251],{"class":681},[179,4905,4906],{"class":196},"\"nuxt build\"",[179,4908,4864],{"class":681},[179,4910,4911,4914,4916],{"class":181,"line":1363},[179,4912,4913],{"class":224},"    \"preview\"",[179,4915,4251],{"class":681},[179,4917,4918],{"class":196},"\"nuxt preview\"\n",[179,4920,4921],{"class":181,"line":1381},[179,4922,4923],{"class":681},"  },\n",[179,4925,4926,4929],{"class":181,"line":1401},[179,4927,4928],{"class":224},"  \"dependencies\"",[179,4930,4884],{"class":681},[179,4932,4933,4936,4938],{"class":181,"line":1407},[179,4934,4935],{"class":224},"    \"@nuxt/content\"",[179,4937,4251],{"class":681},[179,4939,4940],{"class":196},"\"^3.11.0\"\n",[179,4942,4943],{"class":181,"line":1418},[179,4944,4514],{"class":681},[179,4946,4947],{"class":181,"line":1435},[179,4948,3814],{"class":681},[12,4950,4952],{"id":4951},"yaml","YAML",[102,4954,4957],{"className":4955,"code":4956,"language":4951,"meta":111,"style":111},"language-yaml shiki shiki-themes github-light github-dark","server:\n  host: 0.0.0.0\n  port: 3000\n\ndatabase:\n  driver: postgres\n  host: localhost\n  name: mydb\n  credentials:\n    user: admin\n    password: ${DB_PASSWORD}\n",[109,4958,4959,4967,4977,4987,4991,4998,5008,5017,5026,5033,5043],{"__ignoreMap":111},[179,4960,4961,4964],{"class":181,"line":182},[179,4962,4963],{"class":4053},"server",[179,4965,4966],{"class":681},":\n",[179,4968,4969,4972,4974],{"class":181,"line":189},[179,4970,4971],{"class":4053},"  host",[179,4973,4251],{"class":681},[179,4975,4976],{"class":224},"0.0.0.0\n",[179,4978,4979,4982,4984],{"class":181,"line":448},[179,4980,4981],{"class":4053},"  port",[179,4983,4251],{"class":681},[179,4985,4986],{"class":224},"3000\n",[179,4988,4989],{"class":181,"line":775},[179,4990,1404],{"emptyLinePlaceholder":477},[179,4992,4993,4996],{"class":181,"line":852},[179,4994,4995],{"class":4053},"database",[179,4997,4966],{"class":681},[179,4999,5000,5003,5005],{"class":181,"line":1351},[179,5001,5002],{"class":4053},"  driver",[179,5004,4251],{"class":681},[179,5006,5007],{"class":196},"postgres\n",[179,5009,5010,5012,5014],{"class":181,"line":1363},[179,5011,4971],{"class":4053},[179,5013,4251],{"class":681},[179,5015,5016],{"class":196},"localhost\n",[179,5018,5019,5021,5023],{"class":181,"line":1381},[179,5020,3910],{"class":4053},[179,5022,4251],{"class":681},[179,5024,5025],{"class":196},"mydb\n",[179,5027,5028,5031],{"class":181,"line":1401},[179,5029,5030],{"class":4053},"  credentials",[179,5032,4966],{"class":681},[179,5034,5035,5038,5040],{"class":181,"line":1407},[179,5036,5037],{"class":4053},"    user",[179,5039,4251],{"class":681},[179,5041,5042],{"class":196},"admin\n",[179,5044,5045,5048,5050],{"class":181,"line":1418},[179,5046,5047],{"class":4053},"    password",[179,5049,4251],{"class":681},[179,5051,5052],{"class":196},"${DB_PASSWORD}\n",[12,5054,5056],{"id":5055},"markdown","Markdown",[102,5058,5061],{"className":5059,"code":5060,"language":5055,"meta":111,"style":111},"language-markdown shiki shiki-themes github-light github-dark","# Titre principal\n\nUn paragraphe avec du **gras** et de l'*italique*.\n\n- Element 1\n- Element 2\n\n[Lien vers le site](https://example.com)\n",[109,5062,5063,5069,5073,5092,5096,5104,5111,5115],{"__ignoreMap":111},[179,5064,5065],{"class":181,"line":182},[179,5066,5068],{"class":5067},"sq-ep","# Titre principal\n",[179,5070,5071],{"class":181,"line":189},[179,5072,1404],{"emptyLinePlaceholder":477},[179,5074,5075,5078,5082,5085,5089],{"class":181,"line":448},[179,5076,5077],{"class":681},"Un paragraphe avec du ",[179,5079,5081],{"class":5080},"sIZ1i","**gras**",[179,5083,5084],{"class":681}," et de l'",[179,5086,5088],{"class":5087},"s5osK","*italique*",[179,5090,5091],{"class":681},".\n",[179,5093,5094],{"class":181,"line":775},[179,5095,1404],{"emptyLinePlaceholder":477},[179,5097,5098,5101],{"class":181,"line":852},[179,5099,5100],{"class":3802},"-",[179,5102,5103],{"class":681}," Element 1\n",[179,5105,5106,5108],{"class":181,"line":1351},[179,5107,5100],{"class":3802},[179,5109,5110],{"class":681}," Element 2\n",[179,5112,5113],{"class":181,"line":1363},[179,5114,1404],{"emptyLinePlaceholder":477},[179,5116,5117,5120,5124,5127,5131],{"class":181,"line":1381},[179,5118,5119],{"class":681},"[",[179,5121,5123],{"class":5122},"svl0z","Lien vers le site",[179,5125,5126],{"class":681},"](",[179,5128,5130],{"class":5129},"s2frl","https://example.com",[179,5132,1480],{"class":681},[12,5134,5136],{"id":5135},"php","PHP",[102,5138,5141],{"className":5139,"code":5140,"language":5135,"meta":111,"style":111},"language-php shiki shiki-themes github-light github-dark","\u003C?php\n\nnamespace App\\Controller;\n\nuse App\\Repository\\UserRepository;\n\nclass UserController\n{\n    public function __construct(\n        private readonly UserRepository $repository\n    ) {}\n\n    public function index(): array\n    {\n        $users = $this->repository->findAll();\n\n        return array_filter($users, function ($user) {\n            return $user->isActive();\n        });\n    }\n}\n",[109,5142,5143,5151,5155,5165,5169,5179,5183,5191,5195,5208,5222,5227,5231,5248,5253,5276,5280,5296,5311,5316,5321],{"__ignoreMap":111},[179,5144,5145,5148],{"class":181,"line":182},[179,5146,5147],{"class":549},"\u003C?",[179,5149,5150],{"class":224},"php\n",[179,5152,5153],{"class":181,"line":189},[179,5154,1404],{"emptyLinePlaceholder":477},[179,5156,5157,5160,5163],{"class":181,"line":448},[179,5158,5159],{"class":549},"namespace",[179,5161,5162],{"class":192}," App\\Controller",[179,5164,3850],{"class":681},[179,5166,5167],{"class":181,"line":775},[179,5168,1404],{"emptyLinePlaceholder":477},[179,5170,5171,5174,5177],{"class":181,"line":852},[179,5172,5173],{"class":549},"use",[179,5175,5176],{"class":224}," App\\Repository\\UserRepository",[179,5178,3850],{"class":681},[179,5180,5181],{"class":181,"line":1351},[179,5182,1404],{"emptyLinePlaceholder":477},[179,5184,5185,5188],{"class":181,"line":1363},[179,5186,5187],{"class":549},"class",[179,5189,5190],{"class":192}," UserController\n",[179,5192,5193],{"class":181,"line":1381},[179,5194,4851],{"class":681},[179,5196,5197,5200,5202,5205],{"class":181,"line":1401},[179,5198,5199],{"class":549},"    public",[179,5201,3735],{"class":549},[179,5203,5204],{"class":224}," __construct",[179,5206,5207],{"class":681},"(\n",[179,5209,5210,5213,5216,5219],{"class":181,"line":1407},[179,5211,5212],{"class":549},"        private",[179,5214,5215],{"class":549}," readonly",[179,5217,5218],{"class":224}," UserRepository",[179,5220,5221],{"class":681}," $repository\n",[179,5223,5224],{"class":181,"line":1418},[179,5225,5226],{"class":681},"    ) {}\n",[179,5228,5229],{"class":181,"line":1435},[179,5230,1404],{"emptyLinePlaceholder":477},[179,5232,5233,5235,5237,5240,5243,5245],{"class":181,"line":1440},[179,5234,5199],{"class":549},[179,5236,3735],{"class":549},[179,5238,5239],{"class":192}," index",[179,5241,5242],{"class":681},"()",[179,5244,3900],{"class":549},[179,5246,5247],{"class":549}," array\n",[179,5249,5250],{"class":181,"line":1450},[179,5251,5252],{"class":681},"    {\n",[179,5254,5255,5258,5260,5263,5266,5269,5271,5274],{"class":181,"line":1483},[179,5256,5257],{"class":681},"        $users ",[179,5259,685],{"class":549},[179,5261,5262],{"class":224}," $this",[179,5264,5265],{"class":549},"->",[179,5267,5268],{"class":681},"repository",[179,5270,5265],{"class":549},[179,5272,5273],{"class":192},"findAll",[179,5275,3786],{"class":681},[179,5277,5278],{"class":181,"line":1503},[179,5279,1404],{"emptyLinePlaceholder":477},[179,5281,5282,5285,5288,5291,5293],{"class":181,"line":1533},[179,5283,5284],{"class":549},"        return",[179,5286,5287],{"class":224}," array_filter",[179,5289,5290],{"class":681},"($users, ",[179,5292,3953],{"class":549},[179,5294,5295],{"class":681}," ($user) {\n",[179,5297,5298,5301,5304,5306,5309],{"class":181,"line":1557},[179,5299,5300],{"class":549},"            return",[179,5302,5303],{"class":681}," $user",[179,5305,5265],{"class":549},[179,5307,5308],{"class":192},"isActive",[179,5310,3786],{"class":681},[179,5312,5313],{"class":181,"line":1583},[179,5314,5315],{"class":681},"        });\n",[179,5317,5318],{"class":181,"line":1598},[179,5319,5320],{"class":681},"    }\n",[179,5322,5323],{"class":181,"line":1603},[179,5324,3814],{"class":681},[12,5326,5328],{"id":5327},"sql","SQL",[102,5330,5333],{"className":5331,"code":5332,"language":5327,"meta":111,"style":111},"language-sql shiki shiki-themes github-light github-dark","-- Privilegier les JOIN explicites\nSELECT u.username, o.order_date\nFROM users u\nINNER JOIN orders o ON u.id = o.user_id\nWHERE o.status = 'completed'\nORDER BY o.order_date DESC\nLIMIT 10;\n",[109,5334,5335,5340,5364,5372,5400,5417,5432],{"__ignoreMap":111},[179,5336,5337],{"class":181,"line":182},[179,5338,5339],{"class":185},"-- Privilegier les JOIN explicites\n",[179,5341,5342,5345,5348,5350,5353,5356,5359,5361],{"class":181,"line":189},[179,5343,5344],{"class":549},"SELECT",[179,5346,5347],{"class":224}," u",[179,5349,436],{"class":681},[179,5351,5352],{"class":224},"username",[179,5354,5355],{"class":681},", ",[179,5357,5358],{"class":224},"o",[179,5360,436],{"class":681},[179,5362,5363],{"class":224},"order_date\n",[179,5365,5366,5369],{"class":181,"line":448},[179,5367,5368],{"class":549},"FROM",[179,5370,5371],{"class":681}," users u\n",[179,5373,5374,5377,5380,5383,5385,5387,5390,5392,5395,5397],{"class":181,"line":775},[179,5375,5376],{"class":549},"INNER JOIN",[179,5378,5379],{"class":681}," orders o ",[179,5381,5382],{"class":549},"ON",[179,5384,5347],{"class":224},[179,5386,436],{"class":681},[179,5388,5389],{"class":224},"id",[179,5391,3752],{"class":549},[179,5393,5394],{"class":224}," o",[179,5396,436],{"class":681},[179,5398,5399],{"class":224},"user_id\n",[179,5401,5402,5405,5407,5409,5412,5414],{"class":181,"line":852},[179,5403,5404],{"class":549},"WHERE",[179,5406,5394],{"class":224},[179,5408,436],{"class":681},[179,5410,5411],{"class":224},"status",[179,5413,3752],{"class":549},[179,5415,5416],{"class":196}," 'completed'\n",[179,5418,5419,5422,5424,5426,5429],{"class":181,"line":1351},[179,5420,5421],{"class":549},"ORDER BY",[179,5423,5394],{"class":224},[179,5425,436],{"class":681},[179,5427,5428],{"class":224},"order_date",[179,5430,5431],{"class":549}," DESC\n",[179,5433,5434,5437,5440],{"class":181,"line":1363},[179,5435,5436],{"class":549},"LIMIT",[179,5438,5439],{"class":224}," 10",[179,5441,3850],{"class":681},[12,5443,5444],{"id":652},"Java",[102,5446,5449],{"className":5447,"code":5448,"language":652,"meta":111,"style":111},"language-java shiki shiki-themes github-light github-dark","import java.util.List;\nimport java.util.stream.Collectors;\n\npublic class UserService {\n    private final UserRepository repository;\n\n    public UserService(UserRepository repository) {\n        this.repository = repository;\n    }\n\n    public List\u003CString> getActiveEmails() {\n        return repository.findAll().stream()\n            .filter(User::isActive)\n            .map(User::getEmail)\n            .collect(Collectors.toList());\n    }\n}\n",[109,5450,5451,5459,5466,5470,5482,5493,5497,5510,5523,5527,5531,5548,5566,5582,5596,5612,5616],{"__ignoreMap":111},[179,5452,5453,5456],{"class":181,"line":182},[179,5454,5455],{"class":549},"import",[179,5457,5458],{"class":681}," java.util.List;\n",[179,5460,5461,5463],{"class":181,"line":189},[179,5462,5455],{"class":549},[179,5464,5465],{"class":681}," java.util.stream.Collectors;\n",[179,5467,5468],{"class":181,"line":448},[179,5469,1404],{"emptyLinePlaceholder":477},[179,5471,5472,5475,5477,5480],{"class":181,"line":775},[179,5473,5474],{"class":549},"public",[179,5476,4068],{"class":549},[179,5478,5479],{"class":192}," UserService",[179,5481,3892],{"class":681},[179,5483,5484,5487,5490],{"class":181,"line":852},[179,5485,5486],{"class":549},"    private",[179,5488,5489],{"class":549}," final",[179,5491,5492],{"class":681}," UserRepository repository;\n",[179,5494,5495],{"class":181,"line":1351},[179,5496,1404],{"emptyLinePlaceholder":477},[179,5498,5499,5501,5503,5506,5508],{"class":181,"line":1363},[179,5500,5199],{"class":549},[179,5502,5479],{"class":192},[179,5504,5505],{"class":681},"(UserRepository ",[179,5507,5268],{"class":3802},[179,5509,4489],{"class":681},[179,5511,5512,5515,5518,5520],{"class":181,"line":1381},[179,5513,5514],{"class":224},"        this",[179,5516,5517],{"class":681},".repository ",[179,5519,685],{"class":549},[179,5521,5522],{"class":681}," repository;\n",[179,5524,5525],{"class":181,"line":1401},[179,5526,5320],{"class":681},[179,5528,5529],{"class":181,"line":1407},[179,5530,1404],{"emptyLinePlaceholder":477},[179,5532,5533,5535,5538,5541,5543,5546],{"class":181,"line":1418},[179,5534,5199],{"class":549},[179,5536,5537],{"class":681}," List\u003C",[179,5539,5540],{"class":549},"String",[179,5542,1412],{"class":681},[179,5544,5545],{"class":192},"getActiveEmails",[179,5547,3741],{"class":681},[179,5549,5550,5552,5555,5557,5560,5563],{"class":181,"line":1435},[179,5551,5284],{"class":549},[179,5553,5554],{"class":681}," repository.",[179,5556,5273],{"class":192},[179,5558,5559],{"class":681},"().",[179,5561,5562],{"class":192},"stream",[179,5564,5565],{"class":681},"()\n",[179,5567,5568,5571,5573,5576,5579],{"class":181,"line":1440},[179,5569,5570],{"class":681},"            .",[179,5572,3797],{"class":192},[179,5574,5575],{"class":681},"(User",[179,5577,5578],{"class":549},"::",[179,5580,5581],{"class":681},"isActive)\n",[179,5583,5584,5586,5589,5591,5593],{"class":181,"line":1450},[179,5585,5570],{"class":681},[179,5587,5588],{"class":192},"map",[179,5590,5575],{"class":681},[179,5592,5578],{"class":549},[179,5594,5595],{"class":681},"getEmail)\n",[179,5597,5598,5600,5603,5606,5609],{"class":181,"line":1483},[179,5599,5570],{"class":681},[179,5601,5602],{"class":192},"collect",[179,5604,5605],{"class":681},"(Collectors.",[179,5607,5608],{"class":192},"toList",[179,5610,5611],{"class":681},"());\n",[179,5613,5614],{"class":181,"line":1503},[179,5615,5320],{"class":681},[179,5617,5618],{"class":181,"line":1533},[179,5619,3814],{"class":681},[12,5621,5623],{"id":5622},"python","Python",[102,5625,5628],{"className":5626,"code":5627,"language":5622,"meta":111,"style":111},"language-python shiki shiki-themes github-light github-dark","from dataclasses import dataclass\nfrom typing import Optional\n\n@dataclass\nclass Article:\n    title: str\n    content: str\n    author: str\n    tags: list[str] = None\n\n    def summary(self, length: int = 100) -> str:\n        return self.content[:length] + \"...\"\n\narticles = [Article(\"Test\", \"Contenu\", \"RivoLink\")]\nfor article in articles:\n    print(f\"{article.title} par {article.author}\")\n",[109,5629,5630,5643,5655,5659,5664,5673,5681,5688,5695,5711,5715,5741,5757,5761,5787,5801],{"__ignoreMap":111},[179,5631,5632,5635,5638,5640],{"class":181,"line":182},[179,5633,5634],{"class":549},"from",[179,5636,5637],{"class":681}," dataclasses ",[179,5639,5455],{"class":549},[179,5641,5642],{"class":681}," dataclass\n",[179,5644,5645,5647,5650,5652],{"class":181,"line":189},[179,5646,5634],{"class":549},[179,5648,5649],{"class":681}," typing ",[179,5651,5455],{"class":549},[179,5653,5654],{"class":681}," Optional\n",[179,5656,5657],{"class":181,"line":448},[179,5658,1404],{"emptyLinePlaceholder":477},[179,5660,5661],{"class":181,"line":775},[179,5662,5663],{"class":192},"@dataclass\n",[179,5665,5666,5668,5671],{"class":181,"line":852},[179,5667,5187],{"class":549},[179,5669,5670],{"class":192}," Article",[179,5672,4966],{"class":681},[179,5674,5675,5678],{"class":181,"line":1351},[179,5676,5677],{"class":681},"    title: ",[179,5679,5680],{"class":224},"str\n",[179,5682,5683,5686],{"class":181,"line":1363},[179,5684,5685],{"class":681},"    content: ",[179,5687,5680],{"class":224},[179,5689,5690,5693],{"class":181,"line":1381},[179,5691,5692],{"class":681},"    author: ",[179,5694,5680],{"class":224},[179,5696,5697,5700,5703,5706,5708],{"class":181,"line":1401},[179,5698,5699],{"class":681},"    tags: list[",[179,5701,5702],{"class":224},"str",[179,5704,5705],{"class":681},"] ",[179,5707,685],{"class":549},[179,5709,5710],{"class":224}," None\n",[179,5712,5713],{"class":181,"line":1407},[179,5714,1404],{"emptyLinePlaceholder":477},[179,5716,5717,5720,5723,5726,5729,5731,5734,5737,5739],{"class":181,"line":1418},[179,5718,5719],{"class":549},"    def",[179,5721,5722],{"class":192}," summary",[179,5724,5725],{"class":681},"(self, length: ",[179,5727,5728],{"class":224},"int",[179,5730,3752],{"class":549},[179,5732,5733],{"class":224}," 100",[179,5735,5736],{"class":681},") -> ",[179,5738,5702],{"class":224},[179,5740,4966],{"class":681},[179,5742,5743,5745,5748,5751,5754],{"class":181,"line":1435},[179,5744,5284],{"class":549},[179,5746,5747],{"class":224}," self",[179,5749,5750],{"class":681},".content[:length] ",[179,5752,5753],{"class":549},"+",[179,5755,5756],{"class":196}," \"...\"\n",[179,5758,5759],{"class":181,"line":1440},[179,5760,1404],{"emptyLinePlaceholder":477},[179,5762,5763,5766,5768,5771,5774,5776,5779,5781,5784],{"class":181,"line":1450},[179,5764,5765],{"class":681},"articles ",[179,5767,685],{"class":549},[179,5769,5770],{"class":681}," [Article(",[179,5772,5773],{"class":196},"\"Test\"",[179,5775,5355],{"class":681},[179,5777,5778],{"class":196},"\"Contenu\"",[179,5780,5355],{"class":681},[179,5782,5783],{"class":196},"\"RivoLink\"",[179,5785,5786],{"class":681},")]\n",[179,5788,5789,5792,5795,5798],{"class":181,"line":1483},[179,5790,5791],{"class":549},"for",[179,5793,5794],{"class":681}," article ",[179,5796,5797],{"class":549},"in",[179,5799,5800],{"class":681}," articles:\n",[179,5802,5803,5806,5808,5811,5814,5817,5820,5823,5826,5828,5831,5833,5835],{"class":181,"line":1503},[179,5804,5805],{"class":224},"    print",[179,5807,3761],{"class":681},[179,5809,5810],{"class":549},"f",[179,5812,5813],{"class":196},"\"",[179,5815,5816],{"class":224},"{",[179,5818,5819],{"class":681},"article.title",[179,5821,5822],{"class":224},"}",[179,5824,5825],{"class":196}," par ",[179,5827,5816],{"class":224},[179,5829,5830],{"class":681},"article.author",[179,5832,5822],{"class":224},[179,5834,5813],{"class":196},[179,5836,1480],{"class":681},[438,5838,5839],{},"html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s9eBZ, html code.shiki .s9eBZ{--shiki-default:#22863A;--shiki-dark:#85E89D}html pre.shiki code .sq-ep, html code.shiki .sq-ep{--shiki-default:#005CC5;--shiki-default-font-weight:bold;--shiki-dark:#79B8FF;--shiki-dark-font-weight:bold}html pre.shiki code .sIZ1i, html code.shiki .sIZ1i{--shiki-default:#24292E;--shiki-default-font-weight:bold;--shiki-dark:#E1E4E8;--shiki-dark-font-weight:bold}html pre.shiki code .s5osK, html code.shiki .s5osK{--shiki-default:#24292E;--shiki-default-font-style:italic;--shiki-dark:#E1E4E8;--shiki-dark-font-style:italic}html pre.shiki code .svl0z, html code.shiki .svl0z{--shiki-default:#032F62;--shiki-default-text-decoration:underline;--shiki-dark:#DBEDFF;--shiki-dark-text-decoration:underline}html pre.shiki code .s2frl, html code.shiki .s2frl{--shiki-default:#24292E;--shiki-default-text-decoration:underline;--shiki-dark:#E1E4E8;--shiki-dark-text-decoration:underline}",{"title":111,"searchDepth":189,"depth":189,"links":5841},[5842,5843,5844,5845,5846,5847,5848,5849,5850,5851,5852,5853,5854],{"id":3715,"depth":189,"text":3716},{"id":3874,"depth":189,"text":3875},{"id":4038,"depth":189,"text":4039},{"id":4366,"depth":189,"text":4367},{"id":4521,"depth":189,"text":4522},{"id":175,"depth":189,"text":4737},{"id":3783,"depth":189,"text":4840},{"id":4951,"depth":189,"text":4952},{"id":5055,"depth":189,"text":5056},{"id":5135,"depth":189,"text":5136},{"id":5327,"depth":189,"text":5328},{"id":652,"depth":189,"text":5444},{"id":5622,"depth":189,"text":5623},"Article de test pour verifier la coloration syntaxique de tous les langages supportes par Shiki",{},"/posts/test-syntax-highlighting",{"title":3710,"description":5855},"posts/test-syntax-highlighting",[5861],"test","s8wCMmVNTsdSmwiaoE4bQxlY8G-R-npMUqnNuKO2y-c",{"id":5864,"title":5865,"author":23,"body":5866,"date":6375,"description":6376,"extension":474,"image":6377,"meta":6378,"navigation":477,"path":6379,"readingTime":479,"seo":6380,"stem":6381,"tags":6382,"updatedAt":6375,"__hash__":6387},"posts/posts/optimisation-des-requetes-sql-indexation-et-plans-d-execution.md","Optimisation des requêtes SQL : Indexation et plans d'exécution",{"type":9,"value":5867,"toc":6354},[5868,5870,5873,5877,5881,5884,5888,5966,5970,6023,6027,6031,6034,6038,6077,6082,6088,6092,6118,6122,6126,6167,6171,6244,6248,6284,6288,6291,6316,6320,6346,6348,6351],[12,5869,15],{"id":14},[17,5871,5872],{},"Les performances d'une application dépendent souvent de l'efficacité de ses requêtes SQL. Une requête mal optimisée peut ralentir considérablement votre système, surtout lorsque le volume de données augmente. Dans cet article, nous explorons deux leviers essentiels pour améliorer les performances : l'indexation et l'analyse des plans d'exécution.",[12,5874,5876],{"id":5875},"comprendre-lindexation","Comprendre l'indexation",[53,5878,5880],{"id":5879},"quest-ce-quun-index","Qu'est-ce qu'un index ?",[17,5882,5883],{},"Un index est une structure de données qui permet d'accélérer les opérations de recherche dans une table. Imaginez un index comme la table des matières d'un livre : au lieu de parcourir toutes les pages, vous consultez directement la section qui vous intéresse.",[53,5885,5887],{"id":5886},"types-dindex-courants","Types d'index courants",[102,5889,5891],{"className":5331,"code":5890,"language":5327,"meta":111,"style":111},"-- Index simple sur une colonne\nCREATE INDEX idx_users_email ON users(email);\n\n-- Index composite sur plusieurs colonnes\nCREATE INDEX idx_orders_date_status ON orders(order_date, status);\n\n-- Index unique (empêche les doublons)\nCREATE UNIQUE INDEX idx_users_username ON users(username);\n",[109,5892,5893,5898,5915,5919,5924,5942,5946,5951],{"__ignoreMap":111},[179,5894,5895],{"class":181,"line":182},[179,5896,5897],{"class":185},"-- Index simple sur une colonne\n",[179,5899,5900,5903,5906,5909,5912],{"class":181,"line":189},[179,5901,5902],{"class":549},"CREATE",[179,5904,5905],{"class":549}," INDEX",[179,5907,5908],{"class":192}," idx_users_email",[179,5910,5911],{"class":549}," ON",[179,5913,5914],{"class":681}," users(email);\n",[179,5916,5917],{"class":181,"line":448},[179,5918,1404],{"emptyLinePlaceholder":477},[179,5920,5921],{"class":181,"line":775},[179,5922,5923],{"class":185},"-- Index composite sur plusieurs colonnes\n",[179,5925,5926,5928,5930,5933,5935,5938,5940],{"class":181,"line":852},[179,5927,5902],{"class":549},[179,5929,5905],{"class":549},[179,5931,5932],{"class":192}," idx_orders_date_status",[179,5934,5911],{"class":549},[179,5936,5937],{"class":681}," orders(order_date, ",[179,5939,5411],{"class":549},[179,5941,3767],{"class":681},[179,5943,5944],{"class":181,"line":1351},[179,5945,1404],{"emptyLinePlaceholder":477},[179,5947,5948],{"class":181,"line":1363},[179,5949,5950],{"class":185},"-- Index unique (empêche les doublons)\n",[179,5952,5953,5955,5958,5961,5963],{"class":181,"line":1381},[179,5954,5902],{"class":549},[179,5956,5957],{"class":549}," UNIQUE INDEX",[179,5959,5960],{"class":192}," idx_users_username",[179,5962,5911],{"class":549},[179,5964,5965],{"class":681}," users(username);\n",[53,5967,5969],{"id":5968},"quand-créer-un-index","Quand créer un index ?",[1120,5971,5972,5982],{},[1123,5973,5974],{},[1126,5975,5976,5979],{},[1129,5977,5978],{},"Situation",[1129,5980,5981],{},"Recommandation",[1136,5983,5984,5992,5999,6007,6015],{},[1126,5985,5986,5989],{},[1141,5987,5988],{},"Colonnes fréquemment utilisées dans WHERE",[1141,5990,5991],{},"Oui",[1126,5993,5994,5997],{},[1141,5995,5996],{},"Colonnes utilisées dans JOIN",[1141,5998,5991],{},[1126,6000,6001,6004],{},[1141,6002,6003],{},"Colonnes avec peu de valeurs distinctes",[1141,6005,6006],{},"Non",[1126,6008,6009,6012],{},[1141,6010,6011],{},"Tables très petites",[1141,6013,6014],{},"Non nécessaire",[1126,6016,6017,6020],{},[1141,6018,6019],{},"Colonnes fréquemment mises à jour",[1141,6021,6022],{},"Attention (coût d'écriture)",[12,6024,6026],{"id":6025},"analyser-les-plans-dexécution","Analyser les plans d'exécution",[53,6028,6030],{"id":6029},"quest-ce-quun-plan-dexécution","Qu'est-ce qu'un plan d'exécution ?",[17,6032,6033],{},"Un plan d'exécution décrit comment le moteur de base de données va exécuter votre requête. Il révèle les opérations effectuées (scan, seek, join) et leur coût estimé.",[53,6035,6037],{"id":6036},"exemple-avec-postgresql","Exemple avec PostgreSQL",[102,6039,6041],{"className":5331,"code":6040,"language":5327,"meta":111,"style":111},"-- Activer l'analyse détaillée\nEXPLAIN ANALYZE\nSELECT * FROM users WHERE email = 'test@example.com';\n",[109,6042,6043,6048,6053],{"__ignoreMap":111},[179,6044,6045],{"class":181,"line":182},[179,6046,6047],{"class":185},"-- Activer l'analyse détaillée\n",[179,6049,6050],{"class":181,"line":189},[179,6051,6052],{"class":681},"EXPLAIN ANALYZE\n",[179,6054,6055,6057,6059,6062,6065,6067,6070,6072,6075],{"class":181,"line":448},[179,6056,5344],{"class":549},[179,6058,3580],{"class":549},[179,6060,6061],{"class":549}," FROM",[179,6063,6064],{"class":681}," users ",[179,6066,5404],{"class":549},[179,6068,6069],{"class":681}," email ",[179,6071,685],{"class":549},[179,6073,6074],{"class":196}," 'test@example.com'",[179,6076,3850],{"class":681},[17,6078,6079],{},[21,6080,6081],{},"Sortie typique :",[102,6083,6086],{"className":6084,"code":6085,"language":107},[105],"Index Scan using idx_users_email on users  (cost=0.42..8.44 rows=1 width=32)\n  Actual time=0.035..0.037 rows=1 loops=1\n  Index Cond: (email = 'test@example.com')\nPlanning Time: 0.150 ms\nExecution Time: 0.052 ms\n",[109,6087,6085],{"__ignoreMap":111},[53,6089,6091],{"id":6090},"interpréter-les-résultats","Interpréter les résultats",[33,6093,6094,6100,6106,6112],{},[36,6095,6096,6099],{},[21,6097,6098],{},"Index Scan"," : L'index est utilisé (bon signe)",[36,6101,6102,6105],{},[21,6103,6104],{},"Seq Scan"," : Parcours séquentiel de la table (à éviter sur les grandes tables)",[36,6107,6108,6111],{},[21,6109,6110],{},"Actual time"," : Temps réel d'exécution en millisecondes",[36,6113,6114,6117],{},[21,6115,6116],{},"rows"," : Nombre de lignes retournées",[12,6119,6121],{"id":6120},"bonnes-pratiques-doptimisation","Bonnes pratiques d'optimisation",[53,6123,6125],{"id":6124},"_1-éviter-select","1. Éviter SELECT *",[102,6127,6129],{"className":5331,"code":6128,"language":5327,"meta":111,"style":111},"-- Mauvaise pratique\nSELECT * FROM users;\n\n-- Bonne pratique\nSELECT id, email, username FROM users;\n",[109,6130,6131,6136,6147,6151,6156],{"__ignoreMap":111},[179,6132,6133],{"class":181,"line":182},[179,6134,6135],{"class":185},"-- Mauvaise pratique\n",[179,6137,6138,6140,6142,6144],{"class":181,"line":189},[179,6139,5344],{"class":549},[179,6141,3580],{"class":549},[179,6143,6061],{"class":549},[179,6145,6146],{"class":681}," users;\n",[179,6148,6149],{"class":181,"line":448},[179,6150,1404],{"emptyLinePlaceholder":477},[179,6152,6153],{"class":181,"line":775},[179,6154,6155],{"class":185},"-- Bonne pratique\n",[179,6157,6158,6160,6163,6165],{"class":181,"line":852},[179,6159,5344],{"class":549},[179,6161,6162],{"class":681}," id, email, username ",[179,6164,5368],{"class":549},[179,6166,6146],{"class":681},[53,6168,6170],{"id":6169},"_2-utiliser-les-jointures-appropriées","2. Utiliser les jointures appropriées",[102,6172,6174],{"className":5331,"code":6173,"language":5327,"meta":111,"style":111},"-- Privilégier les JOIN explicites\nSELECT u.username, o.order_date\nFROM users u\nINNER JOIN orders o ON u.id = o.user_id\nWHERE o.status = 'completed';\n",[109,6175,6176,6181,6199,6205,6227],{"__ignoreMap":111},[179,6177,6178],{"class":181,"line":182},[179,6179,6180],{"class":185},"-- Privilégier les JOIN explicites\n",[179,6182,6183,6185,6187,6189,6191,6193,6195,6197],{"class":181,"line":189},[179,6184,5344],{"class":549},[179,6186,5347],{"class":224},[179,6188,436],{"class":681},[179,6190,5352],{"class":224},[179,6192,5355],{"class":681},[179,6194,5358],{"class":224},[179,6196,436],{"class":681},[179,6198,5363],{"class":224},[179,6200,6201,6203],{"class":181,"line":448},[179,6202,5368],{"class":549},[179,6204,5371],{"class":681},[179,6206,6207,6209,6211,6213,6215,6217,6219,6221,6223,6225],{"class":181,"line":775},[179,6208,5376],{"class":549},[179,6210,5379],{"class":681},[179,6212,5382],{"class":549},[179,6214,5347],{"class":224},[179,6216,436],{"class":681},[179,6218,5389],{"class":224},[179,6220,3752],{"class":549},[179,6222,5394],{"class":224},[179,6224,436],{"class":681},[179,6226,5399],{"class":224},[179,6228,6229,6231,6233,6235,6237,6239,6242],{"class":181,"line":852},[179,6230,5404],{"class":549},[179,6232,5394],{"class":224},[179,6234,436],{"class":681},[179,6236,5411],{"class":224},[179,6238,3752],{"class":549},[179,6240,6241],{"class":196}," 'completed'",[179,6243,3850],{"class":681},[53,6245,6247],{"id":6246},"_3-limiter-les-résultats","3. Limiter les résultats",[102,6249,6251],{"className":5331,"code":6250,"language":5327,"meta":111,"style":111},"-- Utiliser LIMIT pour les grandes tables\nSELECT * FROM logs ORDER BY created_at DESC LIMIT 100;\n",[109,6252,6253,6258],{"__ignoreMap":111},[179,6254,6255],{"class":181,"line":182},[179,6256,6257],{"class":185},"-- Utiliser LIMIT pour les grandes tables\n",[179,6259,6260,6262,6264,6266,6269,6271,6274,6277,6280,6282],{"class":181,"line":189},[179,6261,5344],{"class":549},[179,6263,3580],{"class":549},[179,6265,6061],{"class":549},[179,6267,6268],{"class":681}," logs ",[179,6270,5421],{"class":549},[179,6272,6273],{"class":681}," created_at ",[179,6275,6276],{"class":549},"DESC",[179,6278,6279],{"class":549}," LIMIT",[179,6281,5733],{"class":224},[179,6283,3850],{"class":681},[53,6285,6287],{"id":6286},"_4-surveiller-les-requêtes-lentes","4. Surveiller les requêtes lentes",[17,6289,6290],{},"Activez le slow query log dans votre SGBD pour identifier les requêtes problématiques :",[102,6292,6294],{"className":5331,"code":6293,"language":5327,"meta":111,"style":111},"-- PostgreSQL : requêtes > 1 seconde\nSET log_min_duration_statement = 1000;\n",[109,6295,6296,6301],{"__ignoreMap":111},[179,6297,6298],{"class":181,"line":182},[179,6299,6300],{"class":185},"-- PostgreSQL : requêtes > 1 seconde\n",[179,6302,6303,6306,6309,6311,6314],{"class":181,"line":189},[179,6304,6305],{"class":549},"SET",[179,6307,6308],{"class":681}," log_min_duration_statement ",[179,6310,685],{"class":549},[179,6312,6313],{"class":224}," 1000",[179,6315,3850],{"class":681},[12,6317,6319],{"id":6318},"outils-recommandés","Outils recommandés",[33,6321,6322,6328,6334,6340],{},[36,6323,6324,6327],{},[21,6325,6326],{},"pg_stat_statements"," (PostgreSQL) : Suivi des statistiques de requêtes",[36,6329,6330,6333],{},[21,6331,6332],{},"MySQL Slow Query Log"," : Journal des requêtes lentes",[36,6335,6336,6339],{},[21,6337,6338],{},"EXPLAIN VISUAL"," : Visualisation graphique des plans d'exécution",[36,6341,6342,6345],{},[21,6343,6344],{},"Query Profiler"," : Outils intégrés aux IDE de développement",[12,6347,406],{"id":405},[17,6349,6350],{},"L'optimisation SQL est un processus itératif. Commencez par identifier les requêtes lentes, analysez leurs plans d'exécution, puis ajoutez des index stratégiques. Surveillez régulièrement les performances et ajustez votre stratégie selon l'évolution de vos données.",[438,6352,6353],{},"html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}",{"title":111,"searchDepth":189,"depth":189,"links":6355},[6356,6357,6362,6367,6373,6374],{"id":14,"depth":189,"text":15},{"id":5875,"depth":189,"text":5876,"children":6358},[6359,6360,6361],{"id":5879,"depth":448,"text":5880},{"id":5886,"depth":448,"text":5887},{"id":5968,"depth":448,"text":5969},{"id":6025,"depth":189,"text":6026,"children":6363},[6364,6365,6366],{"id":6029,"depth":448,"text":6030},{"id":6036,"depth":448,"text":6037},{"id":6090,"depth":448,"text":6091},{"id":6120,"depth":189,"text":6121,"children":6368},[6369,6370,6371,6372],{"id":6124,"depth":448,"text":6125},{"id":6169,"depth":448,"text":6170},{"id":6246,"depth":448,"text":6247},{"id":6286,"depth":448,"text":6287},{"id":6318,"depth":189,"text":6319},{"id":405,"depth":189,"text":406},"2026-03-31","Apprenez à optimiser vos requêtes SQL grâce à l'indexation et l'analyse des plans d'exécution. Boostez les performances de votre base de données.","/images/posts/2026/03/optimisation-des-requetes-sql-indexation-et-plans-d-execution.webp",{},"/posts/optimisation-des-requetes-sql-indexation-et-plans-d-execution",{"title":5865,"description":6376},"posts/optimisation-des-requetes-sql-indexation-et-plans-d-execution",[5327,6383,6384,6385,6386],"performance","base-de-données","optimisation","indexation","N_lvbNnmwLt_uScYmwlnq2a363oc1zYuVq6lczyUwoY",{"id":6389,"title":6390,"author":7,"body":6391,"date":6375,"description":7448,"extension":474,"image":7449,"meta":7450,"navigation":477,"path":7451,"readingTime":479,"seo":7452,"stem":7453,"tags":7454,"updatedAt":6375,"__hash__":7460},"posts/posts/securiser-une-application-web-les-bonnes-pratiques-essentielles.md","Sécuriser une application web : Les bonnes pratiques essentielles",{"type":9,"value":6392,"toc":7425},[6393,6395,6401,6404,6408,6411,6415,6418,6423,6453,6458,6487,6491,6494,6499,6510,6539,6543,6546,6551,6565,6628,6632,6636,6639,6733,6737,6740,6869,6873,6877,6891,6911,6915,6976,6980,6983,7090,7094,7097,7102,7191,7195,7199,7202,7216,7335,7339,7342,7409,7411,7414,7419,7422],[12,6394,15],{"id":14},[17,6396,6397,6398,6400],{},"La sécurité des applications web est devenue une priorité absolue dans un monde numérique où les cyberattaques se multiplient. Chaque développeur doit intégrer la sécurité dès la conception de son application. Sur ",[21,6399,23],{},", nous vous guidons à travers les pratiques essentielles pour protéger vos utilisateurs et vos données.",[17,6402,6403],{},"Dans cet article, nous explorerons les vulnérabilités les plus courantes et les mesures concrètes pour les prévenir.",[12,6405,6407],{"id":6406},"les-vulnérabilités-owasp-top-10","Les vulnérabilités OWASP Top 10",[17,6409,6410],{},"L'Open Web Application Security Project (OWASP) publie régulièrement une liste des dix vulnérabilités les plus critiques. Voici les principales à connaître :",[53,6412,6414],{"id":6413},"injection-sql","Injection SQL",[17,6416,6417],{},"Les attaques par injection permettent à un attaquant d'exécuter des commandes SQL malveillantes dans votre base de données.",[17,6419,6420],{},[21,6421,6422],{},"Mauvaise pratique :",[102,6424,6426],{"className":3719,"code":6425,"language":3715,"meta":111,"style":111},"const query = \"SELECT * FROM users WHERE email = '\" + userEmail + \"'\";\n",[109,6427,6428],{"__ignoreMap":111},[179,6429,6430,6432,6435,6437,6440,6443,6446,6448,6451],{"class":181,"line":182},[179,6431,3823],{"class":549},[179,6433,6434],{"class":224}," query",[179,6436,3752],{"class":549},[179,6438,6439],{"class":196}," \"SELECT * FROM users WHERE email = '\"",[179,6441,6442],{"class":549}," +",[179,6444,6445],{"class":681}," userEmail ",[179,6447,5753],{"class":549},[179,6449,6450],{"class":196}," \"'\"",[179,6452,3850],{"class":681},[17,6454,6455],{},[21,6456,6457],{},"Bonne pratique - Utiliser des requêtes paramétrées :",[102,6459,6461],{"className":3719,"code":6460,"language":3715,"meta":111,"style":111},"const query = \"SELECT * FROM users WHERE email = ?\";\ndb.execute(query, [userEmail]);\n",[109,6462,6463,6476],{"__ignoreMap":111},[179,6464,6465,6467,6469,6471,6474],{"class":181,"line":182},[179,6466,3823],{"class":549},[179,6468,6434],{"class":224},[179,6470,3752],{"class":549},[179,6472,6473],{"class":196}," \"SELECT * FROM users WHERE email = ?\"",[179,6475,3850],{"class":681},[179,6477,6478,6481,6484],{"class":181,"line":189},[179,6479,6480],{"class":681},"db.",[179,6482,6483],{"class":192},"execute",[179,6485,6486],{"class":681},"(query, [userEmail]);\n",[53,6488,6490],{"id":6489},"cross-site-scripting-xss","Cross-Site Scripting (XSS)",[17,6492,6493],{},"Le XSS permet d'injecter du code JavaScript malveillant dans les pages web consultées par d'autres utilisateurs.",[17,6495,6496],{},[21,6497,6498],{},"Protection :",[33,6500,6501,6504,6507],{},[36,6502,6503],{},"Échapper toutes les entrées utilisateur",[36,6505,6506],{},"Utiliser des frameworks qui échappent automatiquement le contenu",[36,6508,6509],{},"Implémenter une politique de sécurité de contenu (CSP)",[102,6511,6513],{"className":4525,"code":6512,"language":4521,"meta":111,"style":111},"\u003Cmeta http-equiv=\"Content-Security-Policy\" content=\"default-src 'self'\">\n",[109,6514,6515],{"__ignoreMap":111},[179,6516,6517,6519,6521,6524,6526,6529,6532,6534,6537],{"class":181,"line":182},[179,6518,4050],{"class":681},[179,6520,4572],{"class":4053},[179,6522,6523],{"class":192}," http-equiv",[179,6525,685],{"class":681},[179,6527,6528],{"class":196},"\"Content-Security-Policy\"",[179,6530,6531],{"class":192}," content",[179,6533,685],{"class":681},[179,6535,6536],{"class":196},"\"default-src 'self'\"",[179,6538,4057],{"class":681},[53,6540,6542],{"id":6541},"authentification-cassée","Authentification cassée",[17,6544,6545],{},"Une mauvaise gestion de l'authentification peut permettre aux attaquants d'accéder aux comptes utilisateurs.",[17,6547,6548],{},[21,6549,6550],{},"Bonnes pratiques :",[33,6552,6553,6556,6559,6562],{},[36,6554,6555],{},"Imposer des mots de passe forts",[36,6557,6558],{},"Implémenter l'authentification multifacteur (MFA)",[36,6560,6561],{},"Limiter les tentatives de connexion",[36,6563,6564],{},"Utiliser des tokens JWT sécurisés",[102,6566,6568],{"className":3719,"code":6567,"language":3715,"meta":111,"style":111},"// Exemple de génération de token JWT sécurisé\nconst token = jwt.sign(\n  { userId: user.id },\n  process.env.JWT_SECRET,\n  { expiresIn: '1h', algorithm: 'HS256' }\n);\n",[109,6569,6570,6575,6592,6597,6607,6624],{"__ignoreMap":111},[179,6571,6572],{"class":181,"line":182},[179,6573,6574],{"class":185},"// Exemple de génération de token JWT sécurisé\n",[179,6576,6577,6579,6582,6584,6587,6590],{"class":181,"line":189},[179,6578,3823],{"class":549},[179,6580,6581],{"class":224}," token",[179,6583,3752],{"class":549},[179,6585,6586],{"class":681}," jwt.",[179,6588,6589],{"class":192},"sign",[179,6591,5207],{"class":681},[179,6593,6594],{"class":181,"line":448},[179,6595,6596],{"class":681},"  { userId: user.id },\n",[179,6598,6599,6602,6605],{"class":181,"line":775},[179,6600,6601],{"class":681},"  process.env.",[179,6603,6604],{"class":224},"JWT_SECRET",[179,6606,4864],{"class":681},[179,6608,6609,6612,6615,6618,6621],{"class":181,"line":852},[179,6610,6611],{"class":681},"  { expiresIn: ",[179,6613,6614],{"class":196},"'1h'",[179,6616,6617],{"class":681},", algorithm: ",[179,6619,6620],{"class":196},"'HS256'",[179,6622,6623],{"class":681}," }\n",[179,6625,6626],{"class":181,"line":1351},[179,6627,3767],{"class":681},[12,6629,6631],{"id":6630},"chiffrement-des-données","Chiffrement des données",[53,6633,6635],{"id":6634},"données-en-transit","Données en transit",[17,6637,6638],{},"Toutes les communications doivent être chiffrées via HTTPS :",[102,6640,6642],{"className":3719,"code":6641,"language":3715,"meta":111,"style":111},"// Force HTTPS dans Express.js\napp.use((req, res, next) => {\n  if (!req.secure) {\n    return res.redirect('https://' + req.headers.host + req.url);\n  }\n  next();\n});\n",[109,6643,6644,6649,6678,6691,6717,6721,6728],{"__ignoreMap":111},[179,6645,6646],{"class":181,"line":182},[179,6647,6648],{"class":185},"// Force HTTPS dans Express.js\n",[179,6650,6651,6654,6656,6659,6662,6664,6667,6669,6672,6674,6676],{"class":181,"line":189},[179,6652,6653],{"class":681},"app.",[179,6655,5173],{"class":192},[179,6657,6658],{"class":681},"((",[179,6660,6661],{"class":3802},"req",[179,6663,5355],{"class":681},[179,6665,6666],{"class":3802},"res",[179,6668,5355],{"class":681},[179,6670,6671],{"class":3802},"next",[179,6673,3836],{"class":681},[179,6675,3839],{"class":549},[179,6677,3892],{"class":681},[179,6679,6680,6683,6685,6688],{"class":181,"line":448},[179,6681,6682],{"class":549},"  if",[179,6684,1468],{"class":681},[179,6686,6687],{"class":549},"!",[179,6689,6690],{"class":681},"req.secure) {\n",[179,6692,6693,6696,6699,6702,6704,6707,6709,6712,6714],{"class":181,"line":775},[179,6694,6695],{"class":549},"    return",[179,6697,6698],{"class":681}," res.",[179,6700,6701],{"class":192},"redirect",[179,6703,3761],{"class":681},[179,6705,6706],{"class":196},"'https://'",[179,6708,6442],{"class":549},[179,6710,6711],{"class":681}," req.headers.host ",[179,6713,5753],{"class":549},[179,6715,6716],{"class":681}," req.url);\n",[179,6718,6719],{"class":181,"line":852},[179,6720,4514],{"class":681},[179,6722,6723,6726],{"class":181,"line":1351},[179,6724,6725],{"class":192},"  next",[179,6727,3786],{"class":681},[179,6729,6730],{"class":181,"line":1363},[179,6731,6732],{"class":681},"});\n",[53,6734,6736],{"id":6735},"données-au-repos","Données au repos",[17,6738,6739],{},"Les données sensibles stockées doivent être chiffrées :",[102,6741,6743],{"className":3719,"code":6742,"language":3715,"meta":111,"style":111},"const crypto = require('crypto');\n\nfunction encryptData(data, key) {\n  const cipher = crypto.createCipher('aes-256-gcm', key);\n  let encrypted = cipher.update(data, 'utf8', 'hex');\n  encrypted += cipher.final('hex');\n  return encrypted;\n}\n",[109,6744,6745,6764,6768,6787,6810,6839,6858,6865],{"__ignoreMap":111},[179,6746,6747,6749,6752,6754,6757,6759,6762],{"class":181,"line":182},[179,6748,3823],{"class":549},[179,6750,6751],{"class":224}," crypto",[179,6753,3752],{"class":549},[179,6755,6756],{"class":192}," require",[179,6758,3761],{"class":681},[179,6760,6761],{"class":196},"'crypto'",[179,6763,3767],{"class":681},[179,6765,6766],{"class":181,"line":189},[179,6767,1404],{"emptyLinePlaceholder":477},[179,6769,6770,6772,6775,6777,6780,6782,6785],{"class":181,"line":448},[179,6771,3953],{"class":549},[179,6773,6774],{"class":192}," encryptData",[179,6776,3761],{"class":681},[179,6778,6779],{"class":3802},"data",[179,6781,5355],{"class":681},[179,6783,6784],{"class":3802},"key",[179,6786,4489],{"class":681},[179,6788,6789,6791,6794,6796,6799,6802,6804,6807],{"class":181,"line":775},[179,6790,3746],{"class":549},[179,6792,6793],{"class":224}," cipher",[179,6795,3752],{"class":549},[179,6797,6798],{"class":681}," crypto.",[179,6800,6801],{"class":192},"createCipher",[179,6803,3761],{"class":681},[179,6805,6806],{"class":196},"'aes-256-gcm'",[179,6808,6809],{"class":681},", key);\n",[179,6811,6812,6815,6818,6820,6823,6826,6829,6832,6834,6837],{"class":181,"line":852},[179,6813,6814],{"class":549},"  let",[179,6816,6817],{"class":681}," encrypted ",[179,6819,685],{"class":549},[179,6821,6822],{"class":681}," cipher.",[179,6824,6825],{"class":192},"update",[179,6827,6828],{"class":681},"(data, ",[179,6830,6831],{"class":196},"'utf8'",[179,6833,5355],{"class":681},[179,6835,6836],{"class":196},"'hex'",[179,6838,3767],{"class":681},[179,6840,6841,6844,6847,6849,6852,6854,6856],{"class":181,"line":1351},[179,6842,6843],{"class":681},"  encrypted ",[179,6845,6846],{"class":549},"+=",[179,6848,6822],{"class":681},[179,6850,6851],{"class":192},"final",[179,6853,3761],{"class":681},[179,6855,6836],{"class":196},[179,6857,3767],{"class":681},[179,6859,6860,6862],{"class":181,"line":1363},[179,6861,3791],{"class":549},[179,6863,6864],{"class":681}," encrypted;\n",[179,6866,6867],{"class":181,"line":1381},[179,6868,3814],{"class":681},[12,6870,6872],{"id":6871},"gestion-des-sessions","Gestion des sessions",[53,6874,6876],{"id":6875},"bonnes-pratiques-pour-les-sessions","Bonnes pratiques pour les sessions",[33,6878,6879,6882,6885,6888],{},[36,6880,6881],{},"Utiliser des identifiants de session aléatoires et longs",[36,6883,6884],{},"Définir une durée d'expiration appropriée",[36,6886,6887],{},"Invalider les sessions après déconnexion",[36,6889,6890],{},"Régénérer l'ID de session après authentification",[102,6892,6894],{"className":3719,"code":6893,"language":3715,"meta":111,"style":111},"session.regenerateID(true);\n",[109,6895,6896],{"__ignoreMap":111},[179,6897,6898,6901,6904,6906,6909],{"class":181,"line":182},[179,6899,6900],{"class":681},"session.",[179,6902,6903],{"class":192},"regenerateID",[179,6905,3761],{"class":681},[179,6907,6908],{"class":224},"true",[179,6910,3767],{"class":681},[53,6912,6914],{"id":6913},"cookies-sécurisés","Cookies sécurisés",[102,6916,6918],{"className":3719,"code":6917,"language":3715,"meta":111,"style":111},"res.cookie('sessionId', sessionId, {\n  httpOnly: true,\n  secure: true,\n  sameSite: 'strict',\n  maxAge: 3600000\n});\n",[109,6919,6920,6936,6945,6954,6964,6972],{"__ignoreMap":111},[179,6921,6922,6925,6928,6930,6933],{"class":181,"line":182},[179,6923,6924],{"class":681},"res.",[179,6926,6927],{"class":192},"cookie",[179,6929,3761],{"class":681},[179,6931,6932],{"class":196},"'sessionId'",[179,6934,6935],{"class":681},", sessionId, {\n",[179,6937,6938,6941,6943],{"class":181,"line":189},[179,6939,6940],{"class":681},"  httpOnly: ",[179,6942,6908],{"class":224},[179,6944,4864],{"class":681},[179,6946,6947,6950,6952],{"class":181,"line":448},[179,6948,6949],{"class":681},"  secure: ",[179,6951,6908],{"class":224},[179,6953,4864],{"class":681},[179,6955,6956,6959,6962],{"class":181,"line":775},[179,6957,6958],{"class":681},"  sameSite: ",[179,6960,6961],{"class":196},"'strict'",[179,6963,4864],{"class":681},[179,6965,6966,6969],{"class":181,"line":852},[179,6967,6968],{"class":681},"  maxAge: ",[179,6970,6971],{"class":224},"3600000\n",[179,6973,6974],{"class":181,"line":1351},[179,6975,6732],{"class":681},[12,6977,6979],{"id":6978},"validation-des-entrées","Validation des entrées",[17,6981,6982],{},"Toujours valider et assainir les données provenant des utilisateurs :",[102,6984,6986],{"className":3719,"code":6985,"language":3715,"meta":111,"style":111},"const validator = require('validator');\n\n// Validation d'email\nif (!validator.isEmail(userInput)) {\n  return res.status(400).json({ error: 'Email invalide' });\n}\n\n// Échappement des caractères spéciaux\nconst sanitized = validator.escape(userInput);\n",[109,6987,6988,7006,7010,7015,7032,7059,7063,7067,7072],{"__ignoreMap":111},[179,6989,6990,6992,6995,6997,6999,7001,7004],{"class":181,"line":182},[179,6991,3823],{"class":549},[179,6993,6994],{"class":224}," validator",[179,6996,3752],{"class":549},[179,6998,6756],{"class":192},[179,7000,3761],{"class":681},[179,7002,7003],{"class":196},"'validator'",[179,7005,3767],{"class":681},[179,7007,7008],{"class":181,"line":189},[179,7009,1404],{"emptyLinePlaceholder":477},[179,7011,7012],{"class":181,"line":448},[179,7013,7014],{"class":185},"// Validation d'email\n",[179,7016,7017,7019,7021,7023,7026,7029],{"class":181,"line":775},[179,7018,4772],{"class":549},[179,7020,1468],{"class":681},[179,7022,6687],{"class":549},[179,7024,7025],{"class":681},"validator.",[179,7027,7028],{"class":192},"isEmail",[179,7030,7031],{"class":681},"(userInput)) {\n",[179,7033,7034,7036,7038,7040,7042,7045,7048,7050,7053,7056],{"class":181,"line":852},[179,7035,3791],{"class":549},[179,7037,6698],{"class":681},[179,7039,5411],{"class":192},[179,7041,3761],{"class":681},[179,7043,7044],{"class":224},"400",[179,7046,7047],{"class":681},").",[179,7049,3783],{"class":192},[179,7051,7052],{"class":681},"({ error: ",[179,7054,7055],{"class":196},"'Email invalide'",[179,7057,7058],{"class":681}," });\n",[179,7060,7061],{"class":181,"line":1351},[179,7062,3814],{"class":681},[179,7064,7065],{"class":181,"line":1363},[179,7066,1404],{"emptyLinePlaceholder":477},[179,7068,7069],{"class":181,"line":1381},[179,7070,7071],{"class":185},"// Échappement des caractères spéciaux\n",[179,7073,7074,7076,7079,7081,7084,7087],{"class":181,"line":1401},[179,7075,3823],{"class":549},[179,7077,7078],{"class":224}," sanitized",[179,7080,3752],{"class":549},[179,7082,7083],{"class":681}," validator.",[179,7085,7086],{"class":192},"escape",[179,7088,7089],{"class":681},"(userInput);\n",[12,7091,7093],{"id":7092},"protection-contre-les-attaques-csrf","Protection contre les attaques CSRF",[17,7095,7096],{},"Cross-Site Request Forgery permet d'exécuter des actions non désirées au nom d'un utilisateur authentifié.",[17,7098,7099],{},[21,7100,7101],{},"Protection avec token CSRF :",[102,7103,7105],{"className":3719,"code":7104,"language":3715,"meta":111,"style":111},"const csrf = require('csurf');\nconst csrfProtection = csrf({ cookie: true });\n\napp.post('/transfer', csrfProtection, (req, res) => {\n  // Le token CSRF est validé automatiquement\n  processTransfer(req.body);\n});\n",[109,7106,7107,7125,7143,7147,7174,7179,7187],{"__ignoreMap":111},[179,7108,7109,7111,7114,7116,7118,7120,7123],{"class":181,"line":182},[179,7110,3823],{"class":549},[179,7112,7113],{"class":224}," csrf",[179,7115,3752],{"class":549},[179,7117,6756],{"class":192},[179,7119,3761],{"class":681},[179,7121,7122],{"class":196},"'csurf'",[179,7124,3767],{"class":681},[179,7126,7127,7129,7132,7134,7136,7139,7141],{"class":181,"line":189},[179,7128,3823],{"class":549},[179,7130,7131],{"class":224}," csrfProtection",[179,7133,3752],{"class":549},[179,7135,7113],{"class":192},[179,7137,7138],{"class":681},"({ cookie: ",[179,7140,6908],{"class":224},[179,7142,7058],{"class":681},[179,7144,7145],{"class":181,"line":448},[179,7146,1404],{"emptyLinePlaceholder":477},[179,7148,7149,7151,7154,7156,7159,7162,7164,7166,7168,7170,7172],{"class":181,"line":775},[179,7150,6653],{"class":681},[179,7152,7153],{"class":192},"post",[179,7155,3761],{"class":681},[179,7157,7158],{"class":196},"'/transfer'",[179,7160,7161],{"class":681},", csrfProtection, (",[179,7163,6661],{"class":3802},[179,7165,5355],{"class":681},[179,7167,6666],{"class":3802},[179,7169,3836],{"class":681},[179,7171,3839],{"class":549},[179,7173,3892],{"class":681},[179,7175,7176],{"class":181,"line":852},[179,7177,7178],{"class":185},"  // Le token CSRF est validé automatiquement\n",[179,7180,7181,7184],{"class":181,"line":1351},[179,7182,7183],{"class":192},"  processTransfer",[179,7185,7186],{"class":681},"(req.body);\n",[179,7188,7189],{"class":181,"line":1363},[179,7190,6732],{"class":681},[12,7192,7194],{"id":7193},"journalisation-et-surveillance","Journalisation et surveillance",[53,7196,7198],{"id":7197},"logs-de-sécurité","Logs de sécurité",[17,7200,7201],{},"Conservez des traces des événements de sécurité :",[33,7203,7204,7207,7210,7213],{},[36,7205,7206],{},"Tentatives de connexion échouées",[36,7208,7209],{},"Accès aux données sensibles",[36,7211,7212],{},"Modifications de configuration",[36,7214,7215],{},"Erreurs d'application",[102,7217,7219],{"className":3719,"code":7218,"language":3715,"meta":111,"style":111},"const winston = require('winston');\n\nconst logger = winston.createLogger({\n  level: 'info',\n  format: winston.format.json(),\n  transports: [\n    new winston.transports.File({ filename: 'security.log' })\n  ]\n});\n\nlogger.warn('Tentative de connexion échouée', { userId, ip: req.ip });\n",[109,7220,7221,7239,7243,7261,7271,7281,7286,7306,7311,7315,7319],{"__ignoreMap":111},[179,7222,7223,7225,7228,7230,7232,7234,7237],{"class":181,"line":182},[179,7224,3823],{"class":549},[179,7226,7227],{"class":224}," winston",[179,7229,3752],{"class":549},[179,7231,6756],{"class":192},[179,7233,3761],{"class":681},[179,7235,7236],{"class":196},"'winston'",[179,7238,3767],{"class":681},[179,7240,7241],{"class":181,"line":189},[179,7242,1404],{"emptyLinePlaceholder":477},[179,7244,7245,7247,7250,7252,7255,7258],{"class":181,"line":448},[179,7246,3823],{"class":549},[179,7248,7249],{"class":224}," logger",[179,7251,3752],{"class":549},[179,7253,7254],{"class":681}," winston.",[179,7256,7257],{"class":192},"createLogger",[179,7259,7260],{"class":681},"({\n",[179,7262,7263,7266,7269],{"class":181,"line":775},[179,7264,7265],{"class":681},"  level: ",[179,7267,7268],{"class":196},"'info'",[179,7270,4864],{"class":681},[179,7272,7273,7276,7278],{"class":181,"line":852},[179,7274,7275],{"class":681},"  format: winston.format.",[179,7277,3783],{"class":192},[179,7279,7280],{"class":681},"(),\n",[179,7282,7283],{"class":181,"line":1351},[179,7284,7285],{"class":681},"  transports: [\n",[179,7287,7288,7291,7294,7297,7300,7303],{"class":181,"line":1363},[179,7289,7290],{"class":549},"    new",[179,7292,7293],{"class":681}," winston.transports.",[179,7295,7296],{"class":192},"File",[179,7298,7299],{"class":681},"({ filename: ",[179,7301,7302],{"class":196},"'security.log'",[179,7304,7305],{"class":681}," })\n",[179,7307,7308],{"class":181,"line":1381},[179,7309,7310],{"class":681},"  ]\n",[179,7312,7313],{"class":181,"line":1401},[179,7314,6732],{"class":681},[179,7316,7317],{"class":181,"line":1407},[179,7318,1404],{"emptyLinePlaceholder":477},[179,7320,7321,7324,7327,7329,7332],{"class":181,"line":1418},[179,7322,7323],{"class":681},"logger.",[179,7325,7326],{"class":192},"warn",[179,7328,3761],{"class":681},[179,7330,7331],{"class":196},"'Tentative de connexion échouée'",[179,7333,7334],{"class":681},", { userId, ip: req.ip });\n",[12,7336,7338],{"id":7337},"checklist-de-sécurité-rapide","Checklist de sécurité rapide",[17,7340,7341],{},"Voici une checklist à suivre avant le déploiement :",[33,7343,7346,7355,7361,7367,7373,7379,7385,7391,7397,7403],{"className":7344},[7345],"contains-task-list",[36,7347,7350,7354],{"className":7348},[7349],"task-list-item",[7351,7352],"input",{"disabled":477,"type":7353},"checkbox"," HTTPS activé sur tous les endpoints",[36,7356,7358,7360],{"className":7357},[7349],[7351,7359],{"disabled":477,"type":7353}," Authentification multifacteur disponible",[36,7362,7364,7366],{"className":7363},[7349],[7351,7365],{"disabled":477,"type":7353}," Mots de passe hachés avec bcrypt ou argon2",[36,7368,7370,7372],{"className":7369},[7349],[7351,7371],{"disabled":477,"type":7353}," Requêtes SQL paramétrées",[36,7374,7376,7378],{"className":7375},[7349],[7351,7377],{"disabled":477,"type":7353}," Entrées utilisateur validées et échappées",[36,7380,7382,7384],{"className":7381},[7349],[7351,7383],{"disabled":477,"type":7353}," Tokens CSRF implémentés",[36,7386,7388,7390],{"className":7387},[7349],[7351,7389],{"disabled":477,"type":7353}," En-têtes de sécurité configurés (HSTS, CSP, X-Frame-Options)",[36,7392,7394,7396],{"className":7393},[7349],[7351,7395],{"disabled":477,"type":7353}," Sessions sécurisées avec expiration",[36,7398,7400,7402],{"className":7399},[7349],[7351,7401],{"disabled":477,"type":7353}," Journalisation des événements de sécurité",[36,7404,7406,7408],{"className":7405},[7349],[7351,7407],{"disabled":477,"type":7353}," Dépendances mises à jour régulièrement",[12,7410,406],{"id":405},[17,7412,7413],{},"La sécurité d'une application web n'est pas une fonctionnalité optionnelle mais une nécessité. En suivant ces bonnes pratiques, vous réduisez considérablement les risques de violations de données et protégez vos utilisateurs.",[17,7415,2210,7416,7418],{},[21,7417,23],{},", nous vous encourageons à intégrer la sécurité dès les premières phases de développement. La sécurité n'est pas un produit final mais un processus continu qui nécessite vigilance et mise à jour régulière.",[17,7420,7421],{},"N'hésitez pas à consulter la documentation OWASP complète pour approfondir chaque point abordé dans cet article.",[438,7423,7424],{},"html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}html pre.shiki code .s9eBZ, html code.shiki .s9eBZ{--shiki-default:#22863A;--shiki-dark:#85E89D}",{"title":111,"searchDepth":189,"depth":189,"links":7426},[7427,7428,7433,7437,7441,7442,7443,7446,7447],{"id":14,"depth":189,"text":15},{"id":6406,"depth":189,"text":6407,"children":7429},[7430,7431,7432],{"id":6413,"depth":448,"text":6414},{"id":6489,"depth":448,"text":6490},{"id":6541,"depth":448,"text":6542},{"id":6630,"depth":189,"text":6631,"children":7434},[7435,7436],{"id":6634,"depth":448,"text":6635},{"id":6735,"depth":448,"text":6736},{"id":6871,"depth":189,"text":6872,"children":7438},[7439,7440],{"id":6875,"depth":448,"text":6876},{"id":6913,"depth":448,"text":6914},{"id":6978,"depth":189,"text":6979},{"id":7092,"depth":189,"text":7093},{"id":7193,"depth":189,"text":7194,"children":7444},[7445],{"id":7197,"depth":448,"text":7198},{"id":7337,"depth":189,"text":7338},{"id":405,"depth":189,"text":406},"Découvrez les bonnes pratiques essentielles pour sécuriser votre application web. Protection contre les vulnérabilités OWASP, authentification et chiffrement.","/images/posts/2026/03/securiser-une-application-web-les-bonnes-pratiques-essentielles.webp",{},"/posts/securiser-une-application-web-les-bonnes-pratiques-essentielles",{"title":6390,"description":7448},"posts/securiser-une-application-web-les-bonnes-pratiques-essentielles",[2885,7455,7456,7457,7458,7459],"web","développement","OWASP","authentification","chiffrement","w3KngCPw8rYQK-f-azfvncd4_9q1AfGL6JJKHAbsuVs",{"id":7462,"title":7463,"author":23,"body":7464,"date":8118,"description":8119,"extension":474,"image":8120,"meta":8121,"navigation":477,"path":8122,"readingTime":479,"seo":8123,"stem":8124,"tags":8125,"updatedAt":8118,"__hash__":8130},"posts/posts/comprendre-apache-http-server-installation-configuration-et-modules-essentiels.md","Comprendre Apache HTTP Server : Installation, Configuration et Modules Essentiels",{"type":9,"value":7465,"toc":8096},[7466,7470,7473,7476,7480,7483,7518,7522,7525,7529,7553,7556,7571,7575,7597,7600,7628,7635,7639,7642,7680,7684,7738,7742,7745,7751,7826,7831,7856,7868,7872,7875,7879,7889,7947,7951,7977,7981,7984,7988,7991,8006,8010,8020,8040,8044,8055,8083,8086,8088,8091,8094],[12,7467,7469],{"id":7468},"introduction-à-apache-http-server","Introduction à Apache HTTP Server",[17,7471,7472],{},"Apache HTTP Server, souvent appelé simplement \"Apache\", est le serveur web le plus populaire au monde depuis plus de deux décennies. Développé par la fondation Apache Software Foundation, ce logiciel libre et open-source est réputé pour sa flexibilité, sa stabilité et sa richesse fonctionnelle.",[17,7474,7475],{},"Dans cet article, nous allons explorer les bases d'Apache, de son installation à la configuration de fonctionnalités avancées comme les VirtualHosts et la sécurisation.",[12,7477,7479],{"id":7478},"pourquoi-choisir-apache","Pourquoi choisir Apache ?",[17,7481,7482],{},"Avant de plonger dans la technique, voici quelques raisons pour lesquelles Apache reste un choix privilégié :",[33,7484,7485,7491,7503,7512],{},[36,7486,7487,7490],{},[21,7488,7489],{},"Modularité"," : Une architecture basée sur des modules permet d'activer uniquement les fonctionnalités nécessaires.",[36,7492,7493,7496,7497,665,7500,436],{},[21,7494,7495],{},"Compatibilité"," : Support natif de nombreux langages (PHP, Python, Perl) via des modules comme ",[109,7498,7499],{},"mod_php",[109,7501,7502],{},"mod_wsgi",[36,7504,7505,7508,7509,7047],{},[21,7506,7507],{},"Configuration flexible"," : Fichiers de configuration lisibles et possibilité de surcharger la configuration par dossier (fichiers ",[109,7510,7511],{},".htaccess",[36,7513,7514,7517],{},[21,7515,7516],{},"Communauté active"," : Une documentation exhaustive et un support communautaire réactif.",[12,7519,7521],{"id":7520},"installation-dapache","Installation d'Apache",[17,7523,7524],{},"La procédure d'installation varie selon votre système d'exploitation. Voici les commandes pour les distributions Linux les plus courantes.",[53,7526,7528],{"id":7527},"sur-ubuntudebian","Sur Ubuntu/Debian",[102,7530,7532],{"className":173,"code":7531,"language":175,"meta":111,"style":111},"sudo apt update\nsudo apt install apache2\n",[109,7533,7534,7542],{"__ignoreMap":111},[179,7535,7536,7538,7540],{"class":181,"line":182},[179,7537,567],{"class":192},[179,7539,621],{"class":196},[179,7541,624],{"class":196},[179,7543,7544,7546,7548,7550],{"class":181,"line":189},[179,7545,567],{"class":192},[179,7547,621],{"class":196},[179,7549,573],{"class":196},[179,7551,7552],{"class":196}," apache2\n",[17,7554,7555],{},"Une fois installé, le service démarre automatiquement. Vous pouvez vérifier son statut avec :",[102,7557,7559],{"className":173,"code":7558,"language":175,"meta":111,"style":111},"systemctl status apache2\n",[109,7560,7561],{"__ignoreMap":111},[179,7562,7563,7566,7569],{"class":181,"line":182},[179,7564,7565],{"class":192},"systemctl",[179,7567,7568],{"class":196}," status",[179,7570,7552],{"class":196},[53,7572,7574],{"id":7573},"sur-centosrhelfedora","Sur CentOS/RHEL/Fedora",[102,7576,7578],{"className":173,"code":7577,"language":175,"meta":111,"style":111},"sudo dnf install httpd\n# Ou pour les anciennes versions : sudo yum install httpd\n",[109,7579,7580,7592],{"__ignoreMap":111},[179,7581,7582,7584,7587,7589],{"class":181,"line":182},[179,7583,567],{"class":192},[179,7585,7586],{"class":196}," dnf",[179,7588,573],{"class":196},[179,7590,7591],{"class":196}," httpd\n",[179,7593,7594],{"class":181,"line":189},[179,7595,7596],{"class":185},"# Ou pour les anciennes versions : sudo yum install httpd\n",[17,7598,7599],{},"Démarrez et activez le service au démarrage :",[102,7601,7603],{"className":173,"code":7602,"language":175,"meta":111,"style":111},"sudo systemctl start httpd\nsudo systemctl enable httpd\n",[109,7604,7605,7617],{"__ignoreMap":111},[179,7606,7607,7609,7612,7615],{"class":181,"line":182},[179,7608,567],{"class":192},[179,7610,7611],{"class":196}," systemctl",[179,7613,7614],{"class":196}," start",[179,7616,7591],{"class":196},[179,7618,7619,7621,7623,7626],{"class":181,"line":189},[179,7620,567],{"class":192},[179,7622,7611],{"class":196},[179,7624,7625],{"class":196}," enable",[179,7627,7591],{"class":196},[17,7629,7630,7631,7634],{},"Après installation, ouvrez votre navigateur et accédez à ",[109,7632,7633],{},"http://votre_ip_serveur",". Vous devriez voir la page par défaut d'Apache.",[12,7636,7638],{"id":7637},"structure-de-configuration","Structure de configuration",[17,7640,7641],{},"La puissance d'Apache réside dans sa configuration. Bien que les emplacements varient légèrement selon la distribution, la logique reste similaire.",[33,7643,7644,7658,7667],{},[36,7645,7646,7649,7650,7653,7654,7657],{},[21,7647,7648],{},"Fichier principal"," : Souvent situé dans ",[109,7651,7652],{},"/etc/apache2/apache2.conf"," (Debian/Ubuntu) ou ",[109,7655,7656],{},"/etc/httpd/conf/httpd.conf"," (RHEL/CentOS).",[36,7659,7660,7663,7664,436],{},[21,7661,7662],{},"Répertoire des sites"," : Sur Debian/Ubuntu, les configurations de sites sont généralement dans ",[109,7665,7666],{},"/etc/apache2/sites-available/",[36,7668,7669,7672,7673,7676,7677,436],{},[21,7670,7671],{},"Modules"," : Les modules disponibles sont dans ",[109,7674,7675],{},"/etc/apache2/mods-available/"," et activés via des liens symboliques dans ",[109,7678,7679],{},"mods-enabled/",[53,7681,7683],{"id":7682},"commandes-utiles-pour-la-gestion","Commandes utiles pour la gestion",[33,7685,7686,7719],{},[36,7687,7688,7689],{},"Tester la configuration syntaxique :\n",[102,7690,7692],{"className":173,"code":7691,"language":175,"meta":111,"style":111},"sudo apache2ctl configtest\n# ou\nsudo httpd -t\n",[109,7693,7694,7704,7709],{"__ignoreMap":111},[179,7695,7696,7698,7701],{"class":181,"line":182},[179,7697,567],{"class":192},[179,7699,7700],{"class":196}," apache2ctl",[179,7702,7703],{"class":196}," configtest\n",[179,7705,7706],{"class":181,"line":189},[179,7707,7708],{"class":185},"# ou\n",[179,7710,7711,7713,7716],{"class":181,"line":448},[179,7712,567],{"class":192},[179,7714,7715],{"class":196}," httpd",[179,7717,7718],{"class":224}," -t\n",[36,7720,7721,7722],{},"Recharger la configuration sans interruption de service :\n",[102,7723,7725],{"className":173,"code":7724,"language":175,"meta":111,"style":111},"sudo systemctl reload apache2\n",[109,7726,7727],{"__ignoreMap":111},[179,7728,7729,7731,7733,7736],{"class":181,"line":182},[179,7730,567],{"class":192},[179,7732,7611],{"class":196},[179,7734,7735],{"class":196}," reload",[179,7737,7552],{"class":196},[12,7739,7741],{"id":7740},"configuration-des-virtualhosts","Configuration des VirtualHosts",[17,7743,7744],{},"Les VirtualHosts permettent d'héberger plusieurs domaines ou applications sur un seul serveur IP. C'est une fonctionnalité essentielle pour tout hébergeur ou développeur gérant plusieurs projets.",[17,7746,7747,7748,642],{},"Voici un exemple de configuration pour un domaine ",[109,7749,7750],{},"monsite.com",[102,7752,7756],{"className":7753,"code":7754,"language":7755,"meta":111,"style":111},"language-apache shiki shiki-themes github-light github-dark","\u003CVirtualHost *:80>\n    ServerName monsite.com\n    ServerAlias www.monsite.com\n    DocumentRoot /var/www/monsite\n\n    \u003CDirectory /var/www/monsite>\n        Options Indexes FollowSymLinks\n        AllowOverride All\n        Require all granted\n    \u003C/Directory>\n\n    ErrorLog ${APACHE_LOG_DIR}/monsite_error.log\n    CustomLog ${APACHE_LOG_DIR}/monsite_access.log combined\n\u003C/VirtualHost>\n","apache",[109,7757,7758,7763,7768,7773,7778,7782,7787,7792,7797,7802,7807,7811,7816,7821],{"__ignoreMap":111},[179,7759,7760],{"class":181,"line":182},[179,7761,7762],{},"\u003CVirtualHost *:80>\n",[179,7764,7765],{"class":181,"line":189},[179,7766,7767],{},"    ServerName monsite.com\n",[179,7769,7770],{"class":181,"line":448},[179,7771,7772],{},"    ServerAlias www.monsite.com\n",[179,7774,7775],{"class":181,"line":775},[179,7776,7777],{},"    DocumentRoot /var/www/monsite\n",[179,7779,7780],{"class":181,"line":852},[179,7781,1404],{"emptyLinePlaceholder":477},[179,7783,7784],{"class":181,"line":1351},[179,7785,7786],{},"    \u003CDirectory /var/www/monsite>\n",[179,7788,7789],{"class":181,"line":1363},[179,7790,7791],{},"        Options Indexes FollowSymLinks\n",[179,7793,7794],{"class":181,"line":1381},[179,7795,7796],{},"        AllowOverride All\n",[179,7798,7799],{"class":181,"line":1401},[179,7800,7801],{},"        Require all granted\n",[179,7803,7804],{"class":181,"line":1407},[179,7805,7806],{},"    \u003C/Directory>\n",[179,7808,7809],{"class":181,"line":1418},[179,7810,1404],{"emptyLinePlaceholder":477},[179,7812,7813],{"class":181,"line":1435},[179,7814,7815],{},"    ErrorLog ${APACHE_LOG_DIR}/monsite_error.log\n",[179,7817,7818],{"class":181,"line":1440},[179,7819,7820],{},"    CustomLog ${APACHE_LOG_DIR}/monsite_access.log combined\n",[179,7822,7823],{"class":181,"line":1450},[179,7824,7825],{},"\u003C/VirtualHost>\n",[17,7827,7828],{},[21,7829,7830],{},"Étapes pour activer ce site :",[79,7832,7833,7843,7850],{},[36,7834,7835,7836,7839,7840,7047],{},"Créez le fichier de configuration dans ",[109,7837,7838],{},"sites-available"," (ex: ",[109,7841,7842],{},"monsite.conf",[36,7844,7845,7846,7849],{},"Activez le site : ",[109,7847,7848],{},"sudo a2ensite monsite.conf"," (sur Debian/Ubuntu).",[36,7851,7852,7853,436],{},"Rechargez Apache : ",[109,7854,7855],{},"sudo systemctl reload apache2",[17,7857,7858],{},[902,7859,7860,7861,7864,7865,7867],{},"Note : La directive ",[109,7862,7863],{},"AllowOverride All"," est cruciale si vous souhaitez utiliser des fichiers ",[109,7866,7511],{}," pour gérer les réécritures d'URL ou l'authentification.",[12,7869,7871],{"id":7870},"gestion-des-modules","Gestion des modules",[17,7873,7874],{},"Apache fonctionne avec un cœur léger et des modules chargés dynamiquement. Voici comment gérer les modules courants.",[53,7876,7878],{"id":7877},"activerdésactiver-un-module-debianubuntu","Activer/Désactiver un module (Debian/Ubuntu)",[17,7880,7881,7882,7885,7886,642],{},"Utilisez les utilitaires ",[109,7883,7884],{},"a2enmod"," et ",[109,7887,7888],{},"a2dismod",[102,7890,7892],{"className":173,"code":7891,"language":175,"meta":111,"style":111},"# Activer le module de réécriture d'URL (indispensable pour WordPress, Laravel, etc.)\nsudo a2enmod rewrite\n\n# Désactiver un module\nsudo a2dismod status\n\n# N'oubliez pas de recharger Apache\nsudo systemctl reload apache2\n",[109,7893,7894,7899,7909,7913,7918,7928,7932,7937],{"__ignoreMap":111},[179,7895,7896],{"class":181,"line":182},[179,7897,7898],{"class":185},"# Activer le module de réécriture d'URL (indispensable pour WordPress, Laravel, etc.)\n",[179,7900,7901,7903,7906],{"class":181,"line":189},[179,7902,567],{"class":192},[179,7904,7905],{"class":196}," a2enmod",[179,7907,7908],{"class":196}," rewrite\n",[179,7910,7911],{"class":181,"line":448},[179,7912,1404],{"emptyLinePlaceholder":477},[179,7914,7915],{"class":181,"line":775},[179,7916,7917],{"class":185},"# Désactiver un module\n",[179,7919,7920,7922,7925],{"class":181,"line":852},[179,7921,567],{"class":192},[179,7923,7924],{"class":196}," a2dismod",[179,7926,7927],{"class":196}," status\n",[179,7929,7930],{"class":181,"line":1351},[179,7931,1404],{"emptyLinePlaceholder":477},[179,7933,7934],{"class":181,"line":1363},[179,7935,7936],{"class":185},"# N'oubliez pas de recharger Apache\n",[179,7938,7939,7941,7943,7945],{"class":181,"line":1381},[179,7940,567],{"class":192},[179,7942,7611],{"class":196},[179,7944,7735],{"class":196},[179,7946,7552],{"class":196},[53,7948,7950],{"id":7949},"modules-essentiels-à-connaître","Modules essentiels à connaître",[33,7952,7953,7959,7965,7971],{},[36,7954,7955,7958],{},[21,7956,7957],{},"mod_rewrite"," : Pour la réécriture d'URL propre et le SEO.",[36,7960,7961,7964],{},[21,7962,7963],{},"mod_ssl"," : Pour gérer le HTTPS et les certificats SSL/TLS.",[36,7966,7967,7970],{},[21,7968,7969],{},"mod_headers"," : Pour manipuler les en-têtes HTTP (sécurité, cache).",[36,7972,7973,7976],{},[21,7974,7975],{},"mod_proxy"," : Pour configurer Apache comme proxy inverse (utile avec Node.js ou des conteneurs Docker).",[12,7978,7980],{"id":7979},"sécuriser-votre-serveur-apache","Sécuriser votre serveur Apache",[17,7982,7983],{},"La sécurité ne doit jamais être une réflexion après coup. Voici quelques bonnes pratiques immédiates.",[53,7985,7987],{"id":7986},"_1-masquer-la-version-dapache","1. Masquer la version d'Apache",[17,7989,7990],{},"Par défaut, Apache expose sa version dans les en-têtes. Ajoutez ceci à votre configuration principale :",[102,7992,7994],{"className":7753,"code":7993,"language":7755,"meta":111,"style":111},"ServerTokens Prod\nServerSignature Off\n",[109,7995,7996,8001],{"__ignoreMap":111},[179,7997,7998],{"class":181,"line":182},[179,7999,8000],{},"ServerTokens Prod\n",[179,8002,8003],{"class":181,"line":189},[179,8004,8005],{},"ServerSignature Off\n",[53,8007,8009],{"id":8008},"_2-désactiver-le-listing-de-directory","2. Désactiver le listing de directory",[17,8011,8012,8013,665,8016,8019],{},"Si aucun fichier ",[109,8014,8015],{},"index.html",[109,8017,8018],{},"index.php"," n'est présent, Apache affiche la liste des fichiers. Désactivez cela globalement ou par dossier :",[102,8021,8023],{"className":7753,"code":8022,"language":7755,"meta":111,"style":111},"\u003CDirectory /var/www/>\n    Options -Indexes\n\u003C/Directory>\n",[109,8024,8025,8030,8035],{"__ignoreMap":111},[179,8026,8027],{"class":181,"line":182},[179,8028,8029],{},"\u003CDirectory /var/www/>\n",[179,8031,8032],{"class":181,"line":189},[179,8033,8034],{},"    Options -Indexes\n",[179,8036,8037],{"class":181,"line":448},[179,8038,8039],{},"\u003C/Directory>\n",[53,8041,8043],{"id":8042},"_3-utiliser-https","3. Utiliser HTTPS",[17,8045,8046,8047,8050,8051,8054],{},"Aujourd'hui, le HTTPS est obligatoire. Utilisez ",[21,8048,8049],{},"Let's Encrypt"," avec l'outil ",[21,8052,8053],{},"Certbot"," pour obtenir un certificat gratuit :",[102,8056,8058],{"className":173,"code":8057,"language":175,"meta":111,"style":111},"sudo apt install certbot python3-certbot-apache\nsudo certbot --apache\n",[109,8059,8060,8074],{"__ignoreMap":111},[179,8061,8062,8064,8066,8068,8071],{"class":181,"line":182},[179,8063,567],{"class":192},[179,8065,621],{"class":196},[179,8067,573],{"class":196},[179,8069,8070],{"class":196}," certbot",[179,8072,8073],{"class":196}," python3-certbot-apache\n",[179,8075,8076,8078,8080],{"class":181,"line":189},[179,8077,567],{"class":192},[179,8079,8070],{"class":196},[179,8081,8082],{"class":224}," --apache\n",[17,8084,8085],{},"Cet outil configure automatiquement la redirection HTTP vers HTTPS et renouvelle le certificat.",[12,8087,406],{"id":405},[17,8089,8090],{},"Apache HTTP Server reste une pierre angulaire de l'infrastructure web moderne. Sa capacité à s'adapter à des besoins simples comme complexes en fait un outil indispensable. Maîtriser son installation, la configuration des VirtualHosts et la sécurisation de base vous permettra de déployer des applications web robustes et performantes.",[17,8092,8093],{},"N'hésitez pas à explorer la documentation officielle pour approfondir des sujets comme le caching, l'équilibrage de charge ou l'intégration avec des langages spécifiques.",[438,8095,2566],{},{"title":111,"searchDepth":189,"depth":189,"links":8097},[8098,8099,8100,8104,8107,8108,8112,8117],{"id":7468,"depth":189,"text":7469},{"id":7478,"depth":189,"text":7479},{"id":7520,"depth":189,"text":7521,"children":8101},[8102,8103],{"id":7527,"depth":448,"text":7528},{"id":7573,"depth":448,"text":7574},{"id":7637,"depth":189,"text":7638,"children":8105},[8106],{"id":7682,"depth":448,"text":7683},{"id":7740,"depth":189,"text":7741},{"id":7870,"depth":189,"text":7871,"children":8109},[8110,8111],{"id":7877,"depth":448,"text":7878},{"id":7949,"depth":448,"text":7950},{"id":7979,"depth":189,"text":7980,"children":8113},[8114,8115,8116],{"id":7986,"depth":448,"text":7987},{"id":8008,"depth":448,"text":8009},{"id":8042,"depth":448,"text":8043},{"id":405,"depth":189,"text":406},"2026-03-30","Découvrez Apache HTTP Server : installation, configuration des VirtualHosts, gestion des modules et sécurisation de votre serveur web.","/images/posts/2026/03/comprendre-apache-http-server-installation-configuration-et-modules-essentiels.webp",{},"/posts/comprendre-apache-http-server-installation-configuration-et-modules-essentiels",{"title":7463,"description":8119},"posts/comprendre-apache-http-server-installation-configuration-et-modules-essentiels",[7755,8126,8127,2592,8128,8129],"serveur-web","http","administration-système","webserver","dJEEmc4BPSPVXYny1DhFIsbCsjvdEpOlnoztXnFIVAQ",{"id":8132,"title":8133,"author":8134,"body":8135,"date":8118,"description":9544,"extension":474,"image":9545,"meta":9546,"navigation":477,"path":9547,"readingTime":479,"seo":9548,"stem":9549,"tags":9550,"updatedAt":8118,"__hash__":9557},"posts/posts/deployer-une-application-docker-sur-un-serveur-vps-guide-complet-pas-a-pas.md","Deployer une Application Docker sur un Serveur VPS : Guide Complet Pas a Pas","Automate",{"type":9,"value":8136,"toc":9511},[8137,8139,8142,8145,8149,8153,8156,8168,8171,8187,8191,8194,8240,8244,8247,8279,8283,8287,8290,8351,8355,8358,8381,8385,8388,8462,8466,8470,8473,8479,8483,8486,8858,8862,8865,8909,8915,8919,8923,8926,9001,9005,9008,9054,9058,9075,9079,9083,9086,9200,9204,9207,9268,9272,9275,9339,9343,9347,9350,9415,9419,9422,9481,9483,9486,9500,9503,9508],[12,8138,15],{"id":14},[17,8140,8141],{},"Le deploiement d'une application Docker sur un serveur VPS est une competence essentielle pour tout developpeur ou administrateur systeme. Ce guide pratique vous accompagnera de la preparation du serveur jusqu'a la mise en production de vos conteneurs.",[17,8143,8144],{},"A la fin de ce tutoriel, vous serez capable de deployer et maintenir une application Dockerisee sur un serveur distant de maniere securisee et efficace.",[12,8146,8148],{"id":8147},"preparer-le-serveur-vps","Preparer le Serveur VPS",[53,8150,8152],{"id":8151},"acceder-au-serveur-en-ssh","Acceder au Serveur en SSH",[17,8154,8155],{},"La premiere etape consiste a vous connecter a votre serveur VPS via SSH :",[102,8157,8159],{"className":173,"code":8158,"language":175,"meta":111,"style":111},"ssh root@votre-adresse-ip\n",[109,8160,8161],{"__ignoreMap":111},[179,8162,8163,8165],{"class":181,"line":182},[179,8164,2519],{"class":192},[179,8166,8167],{"class":196}," root@votre-adresse-ip\n",[17,8169,8170],{},"Pour plus de securite, il est recommande d'utiliser une cle SSH plutot qu'un mot de passe :",[102,8172,8174],{"className":173,"code":8173,"language":175,"meta":111,"style":111},"ssh -i ~/.ssh/id_rsa root@votre-adresse-ip\n",[109,8175,8176],{"__ignoreMap":111},[179,8177,8178,8180,8182,8185],{"class":181,"line":182},[179,8179,2519],{"class":192},[179,8181,3506],{"class":224},[179,8183,8184],{"class":196}," ~/.ssh/id_rsa",[179,8186,8167],{"class":196},[53,8188,8190],{"id":8189},"mettre-a-jour-le-systeme","Mettre a Jour le Systeme",[17,8192,8193],{},"Avant toute installation, mettez a jour les paquets du systeme :",[102,8195,8197],{"className":173,"code":8196,"language":175,"meta":111,"style":111},"# Pour Ubuntu/Debian\napt update && apt upgrade -y\n\n# Pour CentOS/RHEL\nyum update -y\n",[109,8198,8199,8204,8222,8226,8231],{"__ignoreMap":111},[179,8200,8201],{"class":181,"line":182},[179,8202,8203],{"class":185},"# Pour Ubuntu/Debian\n",[179,8205,8206,8208,8211,8214,8216,8219],{"class":181,"line":189},[179,8207,3183],{"class":192},[179,8209,8210],{"class":196}," update",[179,8212,8213],{"class":681}," && ",[179,8215,3183],{"class":192},[179,8217,8218],{"class":196}," upgrade",[179,8220,8221],{"class":224}," -y\n",[179,8223,8224],{"class":181,"line":448},[179,8225,1404],{"emptyLinePlaceholder":477},[179,8227,8228],{"class":181,"line":775},[179,8229,8230],{"class":185},"# Pour CentOS/RHEL\n",[179,8232,8233,8236,8238],{"class":181,"line":852},[179,8234,8235],{"class":192},"yum",[179,8237,8210],{"class":196},[179,8239,8221],{"class":224},[53,8241,8243],{"id":8242},"creer-un-utilisateur-dedie","Creer un Utilisateur Dedie",[17,8245,8246],{},"Pour des raisons de securite, evitez d'utiliser le compte root pour les operations quotidiennes :",[102,8248,8250],{"className":173,"code":8249,"language":175,"meta":111,"style":111},"adduser deployeur\npasswd deployeur\nusermod -aG sudo deployeur\n",[109,8251,8252,8260,8267],{"__ignoreMap":111},[179,8253,8254,8257],{"class":181,"line":182},[179,8255,8256],{"class":192},"adduser",[179,8258,8259],{"class":196}," deployeur\n",[179,8261,8262,8265],{"class":181,"line":189},[179,8263,8264],{"class":192},"passwd",[179,8266,8259],{"class":196},[179,8268,8269,8272,8275,8277],{"class":181,"line":448},[179,8270,8271],{"class":192},"usermod",[179,8273,8274],{"class":224}," -aG",[179,8276,553],{"class":196},[179,8278,8259],{"class":196},[12,8280,8282],{"id":8281},"installer-docker-et-docker-compose","Installer Docker et Docker Compose",[53,8284,8286],{"id":8285},"installation-de-docker","Installation de Docker",[17,8288,8289],{},"Suivez ces etapes pour installer Docker sur votre serveur :",[102,8291,8293],{"className":173,"code":8292,"language":175,"meta":111,"style":111},"# Telecharger le script d'installation officiel\ncurl -fsSL https://get.docker.com -o get-docker.sh\n\n# Executer le script\nsh get-docker.sh\n\n# Ajouter l'utilisateur au groupe docker\nusermod -aG docker deployeur\n",[109,8294,8295,8300,8315,8319,8324,8331,8335,8340],{"__ignoreMap":111},[179,8296,8297],{"class":181,"line":182},[179,8298,8299],{"class":185},"# Telecharger le script d'installation officiel\n",[179,8301,8302,8304,8306,8309,8312],{"class":181,"line":189},[179,8303,540],{"class":192},[179,8305,543],{"class":224},[179,8307,8308],{"class":196}," https://get.docker.com",[179,8310,8311],{"class":224}," -o",[179,8313,8314],{"class":196}," get-docker.sh\n",[179,8316,8317],{"class":181,"line":448},[179,8318,1404],{"emptyLinePlaceholder":477},[179,8320,8321],{"class":181,"line":775},[179,8322,8323],{"class":185},"# Executer le script\n",[179,8325,8326,8329],{"class":181,"line":852},[179,8327,8328],{"class":192},"sh",[179,8330,8314],{"class":196},[179,8332,8333],{"class":181,"line":1351},[179,8334,1404],{"emptyLinePlaceholder":477},[179,8336,8337],{"class":181,"line":1363},[179,8338,8339],{"class":185},"# Ajouter l'utilisateur au groupe docker\n",[179,8341,8342,8344,8346,8349],{"class":181,"line":1381},[179,8343,8271],{"class":192},[179,8345,8274],{"class":224},[179,8347,8348],{"class":196}," docker",[179,8350,8259],{"class":196},[53,8352,8354],{"id":8353},"verification-de-linstallation","Verification de l'Installation",[17,8356,8357],{},"Verifiez que Docker est correctement installe :",[102,8359,8361],{"className":173,"code":8360,"language":175,"meta":111,"style":111},"docker --version\ndocker run hello-world\n",[109,8362,8363,8371],{"__ignoreMap":111},[179,8364,8365,8368],{"class":181,"line":182},[179,8366,8367],{"class":192},"docker",[179,8369,8370],{"class":224}," --version\n",[179,8372,8373,8375,8378],{"class":181,"line":189},[179,8374,8367],{"class":192},[179,8376,8377],{"class":196}," run",[179,8379,8380],{"class":196}," hello-world\n",[53,8382,8384],{"id":8383},"installation-de-docker-compose","Installation de Docker Compose",[17,8386,8387],{},"Docker Compose permet de gerer plusieurs conteneurs simultanement :",[102,8389,8391],{"className":173,"code":8390,"language":175,"meta":111,"style":111},"# Telecharger Docker Compose\ncurl -L \"https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)\" -o /usr/local/bin/docker-compose\n\n# Rendre le binaire executable\nchmod +x /usr/local/bin/docker-compose\n\n# Verifier l'installation\ndocker-compose --version\n",[109,8392,8393,8398,8429,8433,8438,8446,8450,8455],{"__ignoreMap":111},[179,8394,8395],{"class":181,"line":182},[179,8396,8397],{"class":185},"# Telecharger Docker Compose\n",[179,8399,8400,8402,8404,8407,8410,8413,8416,8418,8421,8424,8426],{"class":181,"line":189},[179,8401,540],{"class":192},[179,8403,2522],{"class":224},[179,8405,8406],{"class":196}," \"https://github.com/docker/compose/releases/latest/download/docker-compose-$(",[179,8408,8409],{"class":192},"uname",[179,8411,8412],{"class":224}," -s",[179,8414,8415],{"class":196},")-$(",[179,8417,8409],{"class":192},[179,8419,8420],{"class":224}," -m",[179,8422,8423],{"class":196},")\"",[179,8425,8311],{"class":224},[179,8427,8428],{"class":196}," /usr/local/bin/docker-compose\n",[179,8430,8431],{"class":181,"line":448},[179,8432,1404],{"emptyLinePlaceholder":477},[179,8434,8435],{"class":181,"line":775},[179,8436,8437],{"class":185},"# Rendre le binaire executable\n",[179,8439,8440,8442,8444],{"class":181,"line":852},[179,8441,2400],{"class":192},[179,8443,2403],{"class":196},[179,8445,8428],{"class":196},[179,8447,8448],{"class":181,"line":1351},[179,8449,1404],{"emptyLinePlaceholder":477},[179,8451,8452],{"class":181,"line":1363},[179,8453,8454],{"class":185},"# Verifier l'installation\n",[179,8456,8457,8460],{"class":181,"line":1381},[179,8458,8459],{"class":192},"docker-compose",[179,8461,8370],{"class":224},[12,8463,8465],{"id":8464},"configurer-votre-application","Configurer Votre Application",[53,8467,8469],{"id":8468},"structure-du-projet","Structure du Projet",[17,8471,8472],{},"Organisez votre projet de la maniere suivante :",[102,8474,8477],{"className":8475,"code":8476,"language":107},[105],"mon-application/\n├── docker-compose.yml\n├── .env\n├── app/\n│   ├── Dockerfile\n│   └── ... (fichiers de l'application)\n└── nginx/\n    ├── default.conf\n    └── ssl/\n",[109,8478,8476],{"__ignoreMap":111},[53,8480,8482],{"id":8481},"fichier-docker-composeyml","Fichier docker-compose.yml",[17,8484,8485],{},"Voici un exemple de fichier docker-compose.yml pour une application web classique :",[102,8487,8489],{"className":4955,"code":8488,"language":4951,"meta":111,"style":111},"version: '3.8'\n\nservices:\n  app:\n    build: ./app\n    container_name: mon_app\n    restart: unless-stopped\n    environment:\n      - NODE_ENV=production\n      - DATABASE_URL=${DATABASE_URL}\n    networks:\n      - app-network\n    volumes:\n      - app-data:/var/lib/app/data\n\n  nginx:\n    image: nginx:alpine\n    container_name: mon_nginx\n    restart: unless-stopped\n    ports:\n      - \"80:80\"\n      - \"443:443\"\n    volumes:\n      - ./nginx/default.conf:/etc/nginx/conf.d/default.conf\n      - ./nginx/ssl:/etc/nginx/ssl\n    depends_on:\n      - app\n    networks:\n      - app-network\n\n  db:\n    image: postgres:15\n    container_name: mon_db\n    restart: unless-stopped\n    environment:\n      - POSTGRES_DB=${DB_NAME}\n      - POSTGRES_USER=${DB_USER}\n      - POSTGRES_PASSWORD=${DB_PASSWORD}\n    volumes:\n      - db-data:/var/lib/postgresql/data\n    networks:\n      - app-network\n\nnetworks:\n  app-network:\n    driver: bridge\n\nvolumes:\n  app-data:\n  db-data:\n",[109,8490,8491,8501,8505,8512,8519,8529,8539,8549,8556,8564,8571,8578,8585,8592,8599,8603,8610,8620,8629,8637,8644,8651,8658,8664,8671,8678,8685,8692,8698,8704,8708,8715,8724,8733,8741,8747,8754,8761,8768,8775,8783,8790,8797,8802,8810,8818,8829,8834,8842,8850],{"__ignoreMap":111},[179,8492,8493,8496,8498],{"class":181,"line":182},[179,8494,8495],{"class":4053},"version",[179,8497,4251],{"class":681},[179,8499,8500],{"class":196},"'3.8'\n",[179,8502,8503],{"class":181,"line":189},[179,8504,1404],{"emptyLinePlaceholder":477},[179,8506,8507,8510],{"class":181,"line":448},[179,8508,8509],{"class":4053},"services",[179,8511,4966],{"class":681},[179,8513,8514,8517],{"class":181,"line":775},[179,8515,8516],{"class":4053},"  app",[179,8518,4966],{"class":681},[179,8520,8521,8524,8526],{"class":181,"line":852},[179,8522,8523],{"class":4053},"    build",[179,8525,4251],{"class":681},[179,8527,8528],{"class":196},"./app\n",[179,8530,8531,8534,8536],{"class":181,"line":1351},[179,8532,8533],{"class":4053},"    container_name",[179,8535,4251],{"class":681},[179,8537,8538],{"class":196},"mon_app\n",[179,8540,8541,8544,8546],{"class":181,"line":1363},[179,8542,8543],{"class":4053},"    restart",[179,8545,4251],{"class":681},[179,8547,8548],{"class":196},"unless-stopped\n",[179,8550,8551,8554],{"class":181,"line":1381},[179,8552,8553],{"class":4053},"    environment",[179,8555,4966],{"class":681},[179,8557,8558,8561],{"class":181,"line":1401},[179,8559,8560],{"class":681},"      - ",[179,8562,8563],{"class":196},"NODE_ENV=production\n",[179,8565,8566,8568],{"class":181,"line":1407},[179,8567,8560],{"class":681},[179,8569,8570],{"class":196},"DATABASE_URL=${DATABASE_URL}\n",[179,8572,8573,8576],{"class":181,"line":1418},[179,8574,8575],{"class":4053},"    networks",[179,8577,4966],{"class":681},[179,8579,8580,8582],{"class":181,"line":1435},[179,8581,8560],{"class":681},[179,8583,8584],{"class":196},"app-network\n",[179,8586,8587,8590],{"class":181,"line":1440},[179,8588,8589],{"class":4053},"    volumes",[179,8591,4966],{"class":681},[179,8593,8594,8596],{"class":181,"line":1450},[179,8595,8560],{"class":681},[179,8597,8598],{"class":196},"app-data:/var/lib/app/data\n",[179,8600,8601],{"class":181,"line":1483},[179,8602,1404],{"emptyLinePlaceholder":477},[179,8604,8605,8608],{"class":181,"line":1503},[179,8606,8607],{"class":4053},"  nginx",[179,8609,4966],{"class":681},[179,8611,8612,8615,8617],{"class":181,"line":1533},[179,8613,8614],{"class":4053},"    image",[179,8616,4251],{"class":681},[179,8618,8619],{"class":196},"nginx:alpine\n",[179,8621,8622,8624,8626],{"class":181,"line":1557},[179,8623,8533],{"class":4053},[179,8625,4251],{"class":681},[179,8627,8628],{"class":196},"mon_nginx\n",[179,8630,8631,8633,8635],{"class":181,"line":1583},[179,8632,8543],{"class":4053},[179,8634,4251],{"class":681},[179,8636,8548],{"class":196},[179,8638,8639,8642],{"class":181,"line":1598},[179,8640,8641],{"class":4053},"    ports",[179,8643,4966],{"class":681},[179,8645,8646,8648],{"class":181,"line":1603},[179,8647,8560],{"class":681},[179,8649,8650],{"class":196},"\"80:80\"\n",[179,8652,8653,8655],{"class":181,"line":1615},[179,8654,8560],{"class":681},[179,8656,8657],{"class":196},"\"443:443\"\n",[179,8659,8660,8662],{"class":181,"line":1629},[179,8661,8589],{"class":4053},[179,8663,4966],{"class":681},[179,8665,8666,8668],{"class":181,"line":1653},[179,8667,8560],{"class":681},[179,8669,8670],{"class":196},"./nginx/default.conf:/etc/nginx/conf.d/default.conf\n",[179,8672,8673,8675],{"class":181,"line":1686},[179,8674,8560],{"class":681},[179,8676,8677],{"class":196},"./nginx/ssl:/etc/nginx/ssl\n",[179,8679,8680,8683],{"class":181,"line":1709},[179,8681,8682],{"class":4053},"    depends_on",[179,8684,4966],{"class":681},[179,8686,8687,8689],{"class":181,"line":1720},[179,8688,8560],{"class":681},[179,8690,8691],{"class":196},"app\n",[179,8693,8694,8696],{"class":181,"line":1741},[179,8695,8575],{"class":4053},[179,8697,4966],{"class":681},[179,8699,8700,8702],{"class":181,"line":1746},[179,8701,8560],{"class":681},[179,8703,8584],{"class":196},[179,8705,8706],{"class":181,"line":1758},[179,8707,1404],{"emptyLinePlaceholder":477},[179,8709,8710,8713],{"class":181,"line":1770},[179,8711,8712],{"class":4053},"  db",[179,8714,4966],{"class":681},[179,8716,8717,8719,8721],{"class":181,"line":1794},[179,8718,8614],{"class":4053},[179,8720,4251],{"class":681},[179,8722,8723],{"class":196},"postgres:15\n",[179,8725,8726,8728,8730],{"class":181,"line":1809},[179,8727,8533],{"class":4053},[179,8729,4251],{"class":681},[179,8731,8732],{"class":196},"mon_db\n",[179,8734,8735,8737,8739],{"class":181,"line":1827},[179,8736,8543],{"class":4053},[179,8738,4251],{"class":681},[179,8740,8548],{"class":196},[179,8742,8743,8745],{"class":181,"line":1836},[179,8744,8553],{"class":4053},[179,8746,4966],{"class":681},[179,8748,8749,8751],{"class":181,"line":1854},[179,8750,8560],{"class":681},[179,8752,8753],{"class":196},"POSTGRES_DB=${DB_NAME}\n",[179,8755,8756,8758],{"class":181,"line":1859},[179,8757,8560],{"class":681},[179,8759,8760],{"class":196},"POSTGRES_USER=${DB_USER}\n",[179,8762,8763,8765],{"class":181,"line":1869},[179,8764,8560],{"class":681},[179,8766,8767],{"class":196},"POSTGRES_PASSWORD=${DB_PASSWORD}\n",[179,8769,8771,8773],{"class":181,"line":8770},39,[179,8772,8589],{"class":4053},[179,8774,4966],{"class":681},[179,8776,8778,8780],{"class":181,"line":8777},40,[179,8779,8560],{"class":681},[179,8781,8782],{"class":196},"db-data:/var/lib/postgresql/data\n",[179,8784,8786,8788],{"class":181,"line":8785},41,[179,8787,8575],{"class":4053},[179,8789,4966],{"class":681},[179,8791,8793,8795],{"class":181,"line":8792},42,[179,8794,8560],{"class":681},[179,8796,8584],{"class":196},[179,8798,8800],{"class":181,"line":8799},43,[179,8801,1404],{"emptyLinePlaceholder":477},[179,8803,8805,8808],{"class":181,"line":8804},44,[179,8806,8807],{"class":4053},"networks",[179,8809,4966],{"class":681},[179,8811,8813,8816],{"class":181,"line":8812},45,[179,8814,8815],{"class":4053},"  app-network",[179,8817,4966],{"class":681},[179,8819,8821,8824,8826],{"class":181,"line":8820},46,[179,8822,8823],{"class":4053},"    driver",[179,8825,4251],{"class":681},[179,8827,8828],{"class":196},"bridge\n",[179,8830,8832],{"class":181,"line":8831},47,[179,8833,1404],{"emptyLinePlaceholder":477},[179,8835,8837,8840],{"class":181,"line":8836},48,[179,8838,8839],{"class":4053},"volumes",[179,8841,4966],{"class":681},[179,8843,8845,8848],{"class":181,"line":8844},49,[179,8846,8847],{"class":4053},"  app-data",[179,8849,4966],{"class":681},[179,8851,8853,8856],{"class":181,"line":8852},50,[179,8854,8855],{"class":4053},"  db-data",[179,8857,4966],{"class":681},[53,8859,8861],{"id":8860},"fichier-env","Fichier .env",[17,8863,8864],{},"Créez un fichier .env pour stocker vos variables sensibles :",[102,8866,8868],{"className":173,"code":8867,"language":175,"meta":111,"style":111},"DATABASE_URL=postgresql://user:password@db:5432/mydb\nDB_NAME=mydb\nDB_USER=user\nDB_PASSWORD=votre_mot_de_passe_securise\n",[109,8869,8870,8880,8889,8899],{"__ignoreMap":111},[179,8871,8872,8875,8877],{"class":181,"line":182},[179,8873,8874],{"class":681},"DATABASE_URL",[179,8876,685],{"class":549},[179,8878,8879],{"class":196},"postgresql://user:password@db:5432/mydb\n",[179,8881,8882,8885,8887],{"class":181,"line":189},[179,8883,8884],{"class":681},"DB_NAME",[179,8886,685],{"class":549},[179,8888,5025],{"class":196},[179,8890,8891,8894,8896],{"class":181,"line":448},[179,8892,8893],{"class":681},"DB_USER",[179,8895,685],{"class":549},[179,8897,8898],{"class":196},"user\n",[179,8900,8901,8904,8906],{"class":181,"line":775},[179,8902,8903],{"class":681},"DB_PASSWORD",[179,8905,685],{"class":549},[179,8907,8908],{"class":196},"votre_mot_de_passe_securise\n",[17,8910,8911,8914],{},[21,8912,8913],{},"Important :"," N'oubliez jamais d'ajouter .env dans votre .gitignore pour ne pas commiter les secrets.",[12,8916,8918],{"id":8917},"securiser-le-deploiement","Securiser le Deploiement",[53,8920,8922],{"id":8921},"configurer-le-pare-feu","Configurer le Pare-feu",[17,8924,8925],{},"Activez et configurez le pare-feu pour limiter les acces :",[102,8927,8929],{"className":173,"code":8928,"language":175,"meta":111,"style":111},"# Installer UFW (Ubuntu)\napt install ufw -y\n\n# Autoriser SSH, HTTP et HTTPS\nufw allow 22/tcp\nufw allow 80/tcp\nufw allow 443/tcp\n\n# Activer le pare-feu\nufw enable\n",[109,8930,8931,8936,8947,8951,8956,8967,8976,8985,8989,8994],{"__ignoreMap":111},[179,8932,8933],{"class":181,"line":182},[179,8934,8935],{"class":185},"# Installer UFW (Ubuntu)\n",[179,8937,8938,8940,8942,8945],{"class":181,"line":189},[179,8939,3183],{"class":192},[179,8941,573],{"class":196},[179,8943,8944],{"class":196}," ufw",[179,8946,8221],{"class":224},[179,8948,8949],{"class":181,"line":448},[179,8950,1404],{"emptyLinePlaceholder":477},[179,8952,8953],{"class":181,"line":775},[179,8954,8955],{"class":185},"# Autoriser SSH, HTTP et HTTPS\n",[179,8957,8958,8961,8964],{"class":181,"line":852},[179,8959,8960],{"class":192},"ufw",[179,8962,8963],{"class":196}," allow",[179,8965,8966],{"class":196}," 22/tcp\n",[179,8968,8969,8971,8973],{"class":181,"line":1351},[179,8970,8960],{"class":192},[179,8972,8963],{"class":196},[179,8974,8975],{"class":196}," 80/tcp\n",[179,8977,8978,8980,8982],{"class":181,"line":1363},[179,8979,8960],{"class":192},[179,8981,8963],{"class":196},[179,8983,8984],{"class":196}," 443/tcp\n",[179,8986,8987],{"class":181,"line":1381},[179,8988,1404],{"emptyLinePlaceholder":477},[179,8990,8991],{"class":181,"line":1401},[179,8992,8993],{"class":185},"# Activer le pare-feu\n",[179,8995,8996,8998],{"class":181,"line":1407},[179,8997,8960],{"class":192},[179,8999,9000],{"class":196}," enable\n",[53,9002,9004],{"id":9003},"configurer-ssl-avec-lets-encrypt","Configurer SSL avec Let's Encrypt",[17,9006,9007],{},"Pour obtenir un certificat SSL gratuit :",[102,9009,9011],{"className":173,"code":9010,"language":175,"meta":111,"style":111},"# Installer Certbot\napt install certbot python3-certbot-nginx -y\n\n# Obtenir un certificat\ncertbot --nginx -d votre-domaine.com\n",[109,9012,9013,9018,9031,9035,9040],{"__ignoreMap":111},[179,9014,9015],{"class":181,"line":182},[179,9016,9017],{"class":185},"# Installer Certbot\n",[179,9019,9020,9022,9024,9026,9029],{"class":181,"line":189},[179,9021,3183],{"class":192},[179,9023,573],{"class":196},[179,9025,8070],{"class":196},[179,9027,9028],{"class":196}," python3-certbot-nginx",[179,9030,8221],{"class":224},[179,9032,9033],{"class":181,"line":448},[179,9034,1404],{"emptyLinePlaceholder":477},[179,9036,9037],{"class":181,"line":775},[179,9038,9039],{"class":185},"# Obtenir un certificat\n",[179,9041,9042,9045,9048,9051],{"class":181,"line":852},[179,9043,9044],{"class":192},"certbot",[179,9046,9047],{"class":224}," --nginx",[179,9049,9050],{"class":224}," -d",[179,9052,9053],{"class":196}," votre-domaine.com\n",[53,9055,9057],{"id":9056},"bonnes-pratiques-de-securite","Bonnes Pratiques de Securite",[33,9059,9060,9063,9066,9069,9072],{},[36,9061,9062],{},"Utilisez des mots de passe forts pour les bases de donnees",[36,9064,9065],{},"Limitez les ports exposes uniquement aux services necessaires",[36,9067,9068],{},"Mettez regulierement a jour les images Docker",[36,9070,9071],{},"Activez les logs et la surveillance",[36,9073,9074],{},"Sauvegardez regulierement vos volumes de donnees",[12,9076,9078],{"id":9077},"gérer-les-conteneurs-en-production","Gérer les Conteneurs en Production",[53,9080,9082],{"id":9081},"commandes-essentielles","Commandes Essentielles",[17,9084,9085],{},"Voici les commandes Docker Compose les plus utiles :",[102,9087,9089],{"className":173,"code":9088,"language":175,"meta":111,"style":111},"# Demarrer les conteneurs\ndocker-compose up -d\n\n# Arreter les conteneurs\ndocker-compose down\n\n# Voir les logs\ndocker-compose logs -f\n\n# Redemarrer un service\ndocker-compose restart app\n\n# Mettre a jour les images\ndocker-compose pull\ndocker-compose up -d\n\n# Voir l'etat des conteneurs\ndocker-compose ps\n",[109,9090,9091,9096,9106,9110,9115,9122,9126,9131,9141,9145,9150,9160,9164,9169,9176,9184,9188,9193],{"__ignoreMap":111},[179,9092,9093],{"class":181,"line":182},[179,9094,9095],{"class":185},"# Demarrer les conteneurs\n",[179,9097,9098,9100,9103],{"class":181,"line":189},[179,9099,8459],{"class":192},[179,9101,9102],{"class":196}," up",[179,9104,9105],{"class":224}," -d\n",[179,9107,9108],{"class":181,"line":448},[179,9109,1404],{"emptyLinePlaceholder":477},[179,9111,9112],{"class":181,"line":775},[179,9113,9114],{"class":185},"# Arreter les conteneurs\n",[179,9116,9117,9119],{"class":181,"line":852},[179,9118,8459],{"class":192},[179,9120,9121],{"class":196}," down\n",[179,9123,9124],{"class":181,"line":1351},[179,9125,1404],{"emptyLinePlaceholder":477},[179,9127,9128],{"class":181,"line":1363},[179,9129,9130],{"class":185},"# Voir les logs\n",[179,9132,9133,9135,9138],{"class":181,"line":1381},[179,9134,8459],{"class":192},[179,9136,9137],{"class":196}," logs",[179,9139,9140],{"class":224}," -f\n",[179,9142,9143],{"class":181,"line":1401},[179,9144,1404],{"emptyLinePlaceholder":477},[179,9146,9147],{"class":181,"line":1407},[179,9148,9149],{"class":185},"# Redemarrer un service\n",[179,9151,9152,9154,9157],{"class":181,"line":1418},[179,9153,8459],{"class":192},[179,9155,9156],{"class":196}," restart",[179,9158,9159],{"class":196}," app\n",[179,9161,9162],{"class":181,"line":1435},[179,9163,1404],{"emptyLinePlaceholder":477},[179,9165,9166],{"class":181,"line":1440},[179,9167,9168],{"class":185},"# Mettre a jour les images\n",[179,9170,9171,9173],{"class":181,"line":1450},[179,9172,8459],{"class":192},[179,9174,9175],{"class":196}," pull\n",[179,9177,9178,9180,9182],{"class":181,"line":1483},[179,9179,8459],{"class":192},[179,9181,9102],{"class":196},[179,9183,9105],{"class":224},[179,9185,9186],{"class":181,"line":1503},[179,9187,1404],{"emptyLinePlaceholder":477},[179,9189,9190],{"class":181,"line":1533},[179,9191,9192],{"class":185},"# Voir l'etat des conteneurs\n",[179,9194,9195,9197],{"class":181,"line":1557},[179,9196,8459],{"class":192},[179,9198,9199],{"class":196}," ps\n",[53,9201,9203],{"id":9202},"surveillance-et-logs","Surveillance et Logs",[17,9205,9206],{},"Configurez la rotation des logs pour eviter de remplir le disque :",[102,9208,9210],{"className":4955,"code":9209,"language":4951,"meta":111,"style":111},"services:\n  app:\n    logging:\n      driver: \"json-file\"\n      options:\n        max-size: \"10m\"\n        max-file: \"3\"\n",[109,9211,9212,9218,9224,9231,9241,9248,9258],{"__ignoreMap":111},[179,9213,9214,9216],{"class":181,"line":182},[179,9215,8509],{"class":4053},[179,9217,4966],{"class":681},[179,9219,9220,9222],{"class":181,"line":189},[179,9221,8516],{"class":4053},[179,9223,4966],{"class":681},[179,9225,9226,9229],{"class":181,"line":448},[179,9227,9228],{"class":4053},"    logging",[179,9230,4966],{"class":681},[179,9232,9233,9236,9238],{"class":181,"line":775},[179,9234,9235],{"class":4053},"      driver",[179,9237,4251],{"class":681},[179,9239,9240],{"class":196},"\"json-file\"\n",[179,9242,9243,9246],{"class":181,"line":852},[179,9244,9245],{"class":4053},"      options",[179,9247,4966],{"class":681},[179,9249,9250,9253,9255],{"class":181,"line":1351},[179,9251,9252],{"class":4053},"        max-size",[179,9254,4251],{"class":681},[179,9256,9257],{"class":196},"\"10m\"\n",[179,9259,9260,9263,9265],{"class":181,"line":1363},[179,9261,9262],{"class":4053},"        max-file",[179,9264,4251],{"class":681},[179,9266,9267],{"class":196},"\"3\"\n",[53,9269,9271],{"id":9270},"sauvegardes-automatisees","Sauvegardes Automatisees",[17,9273,9274],{},"Mettez en place un script de sauvegarde pour vos volumes :",[102,9276,9278],{"className":173,"code":9277,"language":175,"meta":111,"style":111},"#!/bin/bash\nDATE=$(date +%Y-%m-%d_%H-%M-%S)\ndocker run --rm -v mon-application_db-data:/data -v /backups:/backup alpine tar czf /backup/db-$DATE.tar.gz /data\n",[109,9279,9280,9284,9299],{"__ignoreMap":111},[179,9281,9282],{"class":181,"line":182},[179,9283,3531],{"class":185},[179,9285,9286,9288,9290,9292,9294,9297],{"class":181,"line":189},[179,9287,3536],{"class":681},[179,9289,685],{"class":549},[179,9291,3541],{"class":681},[179,9293,3544],{"class":192},[179,9295,9296],{"class":196}," +%Y-%m-%d_%H-%M-%S",[179,9298,1480],{"class":681},[179,9300,9301,9303,9305,9308,9310,9313,9315,9318,9321,9324,9327,9330,9333,9336],{"class":181,"line":448},[179,9302,8367],{"class":192},[179,9304,8377],{"class":196},[179,9306,9307],{"class":224}," --rm",[179,9309,3463],{"class":224},[179,9311,9312],{"class":196}," mon-application_db-data:/data",[179,9314,3463],{"class":224},[179,9316,9317],{"class":196}," /backups:/backup",[179,9319,9320],{"class":196}," alpine",[179,9322,9323],{"class":196}," tar",[179,9325,9326],{"class":196}," czf",[179,9328,9329],{"class":196}," /backup/db-",[179,9331,9332],{"class":681},"$DATE",[179,9334,9335],{"class":196},".tar.gz",[179,9337,9338],{"class":196}," /data\n",[12,9340,9342],{"id":9341},"maintenance-et-mises-a-jour","Maintenance et Mises a Jour",[53,9344,9346],{"id":9345},"mettre-a-jour-lapplication","Mettre a Jour l'Application",[17,9348,9349],{},"Pour deployer une nouvelle version de votre application :",[102,9351,9353],{"className":173,"code":9352,"language":175,"meta":111,"style":111},"# Se rendre dans le repertoire du projet\ncd /chemin/vers/mon-application\n\n# Tirer les nouvelles images\ndocker-compose pull\n\n# Reconstruire si necessaire\ndocker-compose build\n\n# Redemarrer les services\ndocker-compose up -d\n",[109,9354,9355,9360,9367,9371,9376,9382,9386,9391,9398,9402,9407],{"__ignoreMap":111},[179,9356,9357],{"class":181,"line":182},[179,9358,9359],{"class":185},"# Se rendre dans le repertoire du projet\n",[179,9361,9362,9364],{"class":181,"line":189},[179,9363,748],{"class":224},[179,9365,9366],{"class":196}," /chemin/vers/mon-application\n",[179,9368,9369],{"class":181,"line":448},[179,9370,1404],{"emptyLinePlaceholder":477},[179,9372,9373],{"class":181,"line":775},[179,9374,9375],{"class":185},"# Tirer les nouvelles images\n",[179,9377,9378,9380],{"class":181,"line":852},[179,9379,8459],{"class":192},[179,9381,9175],{"class":196},[179,9383,9384],{"class":181,"line":1351},[179,9385,1404],{"emptyLinePlaceholder":477},[179,9387,9388],{"class":181,"line":1363},[179,9389,9390],{"class":185},"# Reconstruire si necessaire\n",[179,9392,9393,9395],{"class":181,"line":1381},[179,9394,8459],{"class":192},[179,9396,9397],{"class":196}," build\n",[179,9399,9400],{"class":181,"line":1401},[179,9401,1404],{"emptyLinePlaceholder":477},[179,9403,9404],{"class":181,"line":1407},[179,9405,9406],{"class":185},"# Redemarrer les services\n",[179,9408,9409,9411,9413],{"class":181,"line":1418},[179,9410,8459],{"class":192},[179,9412,9102],{"class":196},[179,9414,9105],{"class":224},[53,9416,9418],{"id":9417},"nettoyer-les-ressources-inutilisees","Nettoyer les Ressources Inutilisees",[17,9420,9421],{},"Regularment, nettoyez les ressources Docker inutilisees :",[102,9423,9425],{"className":173,"code":9424,"language":175,"meta":111,"style":111},"# Supprimer les conteneurs arretes\ndocker container prune\n\n# Supprimer les images orphelines\ndocker image prune\n\n# Nettoyer completement (attention)\ndocker system prune -a\n",[109,9426,9427,9432,9442,9446,9451,9460,9464,9469],{"__ignoreMap":111},[179,9428,9429],{"class":181,"line":182},[179,9430,9431],{"class":185},"# Supprimer les conteneurs arretes\n",[179,9433,9434,9436,9439],{"class":181,"line":189},[179,9435,8367],{"class":192},[179,9437,9438],{"class":196}," container",[179,9440,9441],{"class":196}," prune\n",[179,9443,9444],{"class":181,"line":448},[179,9445,1404],{"emptyLinePlaceholder":477},[179,9447,9448],{"class":181,"line":775},[179,9449,9450],{"class":185},"# Supprimer les images orphelines\n",[179,9452,9453,9455,9458],{"class":181,"line":852},[179,9454,8367],{"class":192},[179,9456,9457],{"class":196}," image",[179,9459,9441],{"class":196},[179,9461,9462],{"class":181,"line":1351},[179,9463,1404],{"emptyLinePlaceholder":477},[179,9465,9466],{"class":181,"line":1363},[179,9467,9468],{"class":185},"# Nettoyer completement (attention)\n",[179,9470,9471,9473,9475,9478],{"class":181,"line":1381},[179,9472,8367],{"class":192},[179,9474,1369],{"class":196},[179,9476,9477],{"class":196}," prune",[179,9479,9480],{"class":224}," -a\n",[12,9482,406],{"id":405},[17,9484,9485],{},"Vous avez maintenant toutes les clefs pour deployer et maintenir une application Docker sur un serveur VPS. Les points essentiels a retenir sont :",[33,9487,9488,9491,9494,9497],{},[36,9489,9490],{},"La preparation et la securisation du serveur avant toute installation",[36,9492,9493],{},"L'utilisation de Docker Compose pour orchestrer les services",[36,9495,9496],{},"La mise en place de certificats SSL pour le chiffrement",[36,9498,9499],{},"La surveillance et les sauvegardes regulieres des donnees",[17,9501,9502],{},"Pour aller plus loin, explorez les outils de CI/CD comme GitHub Actions ou GitLab CI pour automatiser vos deploiements.",[17,9504,9505,9507],{},[21,9506,23],{}," vous accompagne dans votre apprentissage technique. N'hesitez pas a consulter nos autres tutoriels pour approfondir vos connaissances en DevOps et deployment.",[438,9509,9510],{},"html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .s9eBZ, html code.shiki .s9eBZ{--shiki-default:#22863A;--shiki-dark:#85E89D}",{"title":111,"searchDepth":189,"depth":189,"links":9512},[9513,9514,9519,9524,9529,9534,9539,9543],{"id":14,"depth":189,"text":15},{"id":8147,"depth":189,"text":8148,"children":9515},[9516,9517,9518],{"id":8151,"depth":448,"text":8152},{"id":8189,"depth":448,"text":8190},{"id":8242,"depth":448,"text":8243},{"id":8281,"depth":189,"text":8282,"children":9520},[9521,9522,9523],{"id":8285,"depth":448,"text":8286},{"id":8353,"depth":448,"text":8354},{"id":8383,"depth":448,"text":8384},{"id":8464,"depth":189,"text":8465,"children":9525},[9526,9527,9528],{"id":8468,"depth":448,"text":8469},{"id":8481,"depth":448,"text":8482},{"id":8860,"depth":448,"text":8861},{"id":8917,"depth":189,"text":8918,"children":9530},[9531,9532,9533],{"id":8921,"depth":448,"text":8922},{"id":9003,"depth":448,"text":9004},{"id":9056,"depth":448,"text":9057},{"id":9077,"depth":189,"text":9078,"children":9535},[9536,9537,9538],{"id":9081,"depth":448,"text":9082},{"id":9202,"depth":448,"text":9203},{"id":9270,"depth":448,"text":9271},{"id":9341,"depth":189,"text":9342,"children":9540},[9541,9542],{"id":9345,"depth":448,"text":9346},{"id":9417,"depth":448,"text":9418},{"id":405,"depth":189,"text":406},"Apprenez a deployer votre application Docker sur un serveur VPS. Configuration, securite, gestion des conteneurs et mise en production etape par etape.","/images/posts/2026/03/deployer-une-application-docker-sur-un-serveur-vps-guide-complet-pas-a-pas.webp",{},"/posts/deployer-une-application-docker-sur-un-serveur-vps-guide-complet-pas-a-pas",{"title":8133,"description":9544},"posts/deployer-une-application-docker-sur-un-serveur-vps-guide-complet-pas-a-pas",[9551,9552,9553,9554,9555,2188,9556],"Docker","VPS","DevOps","Deployment","Container","Production","yvY0QGyBCyqP2tALm-QQArvkOYqg8zb4coyK5u-diHA",{"id":9559,"title":9560,"author":23,"body":9561,"date":8118,"description":10800,"extension":474,"image":10801,"meta":10802,"navigation":477,"path":10803,"readingTime":479,"seo":10804,"stem":10805,"tags":10806,"updatedAt":8118,"__hash__":10811},"posts/posts/guide-complet-comment-creer-un-projet-de-developpement-structure.md","Guide Complet : Comment Créer un Projet de Développement Structuré",{"type":9,"value":9562,"toc":10764},[9563,9566,9569,9573,9576,9602,9606,9609,9613,9643,9647,9659,9663,9666,9720,9724,9738,9742,9745,9751,9755,9819,9823,9826,9920,9924,10047,10051,10055,10062,10111,10127,10131,10134,10213,10217,10221,10267,10271,10324,10328,10461,10465,10468,10472,10492,10496,10502,10506,10510,10549,10553,10556,10671,10673,10676,10706,10710,10724,10727,10732,10755,10761],[4662,9564,9560],{"id":9565},"guide-complet-comment-créer-un-projet-de-développement-structuré",[17,9567,9568],{},"Débuter un nouveau projet de développement peut sembler intimidant, surtout lorsque l'on souhaite adopter les bonnes pratiques dès le départ. Dans ce guide, nous allons explorer les étapes essentielles pour créer un projet bien structuré, maintenable et évolutif.",[12,9570,9572],{"id":9571},"pourquoi-une-structure-de-projet-est-importante","Pourquoi une Structure de Projet est Importante ?",[17,9574,9575],{},"Une bonne organisation de projet offre plusieurs avantages :",[33,9577,9578,9584,9590,9596],{},[36,9579,9580,9583],{},[21,9581,9582],{},"Maintenabilité"," : Le code est plus facile à comprendre et à modifier",[36,9585,9586,9589],{},[21,9587,9588],{},"Collaboration"," : Les équipes travaillent plus efficacement ensemble",[36,9591,9592,9595],{},[21,9593,9594],{},"Évolutivité"," : Le projet peut grandir sans devenir chaotique",[36,9597,9598,9601],{},[21,9599,9600],{},"Débogage"," : Les problèmes sont plus faciles à identifier et résoudre",[12,9603,9605],{"id":9604},"étape-1-définir-les-objectifs-du-projet","Étape 1 : Définir les Objectifs du Projet",[17,9607,9608],{},"Avant d'écrire la première ligne de code, prenez le temps de clarifier :",[53,9610,9612],{"id":9611},"les-questions-clés","Les Questions Clés",[79,9614,9615,9621,9626,9632,9638],{},[36,9616,9617,9620],{},[21,9618,9619],{},"Quel est le but du projet ?"," (site vitrine, application web, API, etc.)",[36,9622,9623],{},[21,9624,9625],{},"Qui sont les utilisateurs cibles ?",[36,9627,9628,9631],{},[21,9629,9630],{},"Quelles fonctionnalités sont essentielles ?"," (MVP - Minimum Viable Product)",[36,9633,9634,9637],{},[21,9635,9636],{},"Quelles sont les contraintes techniques ?"," (hébergement, performance, sécurité)",[36,9639,9640],{},[21,9641,9642],{},"Quelle est la timeline prévue ?",[53,9644,9646],{"id":9645},"conseil-pro","Conseil Pro",[3099,9648,9649],{},[17,9650,9651,9652,665,9655,9658],{},"📌 Documentez ces réponses dans un fichier ",[109,9653,9654],{},"README.md",[109,9656,9657],{},"PROJECT_BRIEF.md"," à la racine de votre projet.",[12,9660,9662],{"id":9661},"étape-2-choisir-les-technologies-appropriées","Étape 2 : Choisir les Technologies Appropriées",[17,9664,9665],{},"Le choix des technologies dépend de vos besoins :",[1120,9667,9668,9678],{},[1123,9669,9670],{},[1126,9671,9672,9675],{},[1129,9673,9674],{},"Type de Projet",[1129,9676,9677],{},"Technologies Recommandées",[1136,9679,9680,9688,9696,9704,9712],{},[1126,9681,9682,9685],{},[1141,9683,9684],{},"Site vitrine",[1141,9686,9687],{},"HTML, CSS, JavaScript",[1126,9689,9690,9693],{},[1141,9691,9692],{},"Application web",[1141,9694,9695],{},"React, Vue, Angular + Backend",[1126,9697,9698,9701],{},[1141,9699,9700],{},"API REST",[1141,9702,9703],{},"Node.js, Python, PHP, Go",[1126,9705,9706,9709],{},[1141,9707,9708],{},"Mobile",[1141,9710,9711],{},"React Native, Flutter, Swift",[1126,9713,9714,9717],{},[1141,9715,9716],{},"Data/IA",[1141,9718,9719],{},"Python, Jupyter, TensorFlow",[53,9721,9723],{"id":9722},"vérifiez-toujours","Vérifiez Toujours",[33,9725,9726,9729,9732,9735],{},[36,9727,9728],{},"✅ La maturité de la technologie",[36,9730,9731],{},"✅ La communauté et le support",[36,9733,9734],{},"✅ La compatibilité avec votre hébergement",[36,9736,9737],{},"✅ Les compétences de votre équipe",[12,9739,9741],{"id":9740},"étape-3-structurer-les-fichiers-et-dossiers","Étape 3 : Structurer les Fichiers et Dossiers",[17,9743,9744],{},"Voici une structure de projet générique recommandée :",[102,9746,9749],{"className":9747,"code":9748,"language":107},[105],"mon-projet/\n├── .gitignore\n├── README.md\n├── LICENSE\n├── package.json (ou requirements.txt, composer.json...)\n├── src/\n│   ├── components/\n│   ├── pages/\n│   ├── utils/\n│   ├── assets/\n│   └── styles/\n├── public/\n│   ├── index.html\n│   └── favicon.ico\n├── tests/\n│   ├── unit/\n│   └── integration/\n├── docs/\n└── config/\n",[109,9750,9748],{"__ignoreMap":111},[53,9752,9754],{"id":9753},"description-des-dossiers-principaux","Description des Dossiers Principaux",[1120,9756,9757,9767],{},[1123,9758,9759],{},[1126,9760,9761,9764],{},[1129,9762,9763],{},"Dossier",[1129,9765,9766],{},"Purpose",[1136,9768,9769,9779,9789,9799,9809],{},[1126,9770,9771,9776],{},[1141,9772,9773],{},[109,9774,9775],{},"src/",[1141,9777,9778],{},"Code source principal de l'application",[1126,9780,9781,9786],{},[1141,9782,9783],{},[109,9784,9785],{},"public/",[1141,9787,9788],{},"Fichiers statiques accessibles publiquement",[1126,9790,9791,9796],{},[1141,9792,9793],{},[109,9794,9795],{},"tests/",[1141,9797,9798],{},"Tests unitaires et d'intégration",[1126,9800,9801,9806],{},[1141,9802,9803],{},[109,9804,9805],{},"docs/",[1141,9807,9808],{},"Documentation du projet",[1126,9810,9811,9816],{},[1141,9812,9813],{},[109,9814,9815],{},"config/",[1141,9817,9818],{},"Fichiers de configuration",[12,9820,9822],{"id":9821},"étape-4-initialiser-le-contrôle-de-version","Étape 4 : Initialiser le Contrôle de Version",[17,9824,9825],{},"Git est indispensable pour tout projet moderne :",[102,9827,9829],{"className":173,"code":9828,"language":175,"meta":111,"style":111},"# Initialiser un dépôt Git\ngit init\n\n# Créer un premier commit\ngit add .\ngit commit -m \"Initial commit: structure de base du projet\"\n\n# Créer une branche principale\ngit branch -M main\n\n# Ajouter un dépôt distant (optionnel)\ngit remote add origin https://github.com/votre-user/mon-projet.git\n",[109,9830,9831,9836,9844,9848,9853,9862,9874,9878,9883,9896,9900,9905],{"__ignoreMap":111},[179,9832,9833],{"class":181,"line":182},[179,9834,9835],{"class":185},"# Initialiser un dépôt Git\n",[179,9837,9838,9841],{"class":181,"line":189},[179,9839,9840],{"class":192},"git",[179,9842,9843],{"class":196}," init\n",[179,9845,9846],{"class":181,"line":448},[179,9847,1404],{"emptyLinePlaceholder":477},[179,9849,9850],{"class":181,"line":775},[179,9851,9852],{"class":185},"# Créer un premier commit\n",[179,9854,9855,9857,9859],{"class":181,"line":852},[179,9856,9840],{"class":192},[179,9858,203],{"class":196},[179,9860,9861],{"class":196}," .\n",[179,9863,9864,9866,9869,9871],{"class":181,"line":1351},[179,9865,9840],{"class":192},[179,9867,9868],{"class":196}," commit",[179,9870,8420],{"class":224},[179,9872,9873],{"class":196}," \"Initial commit: structure de base du projet\"\n",[179,9875,9876],{"class":181,"line":1363},[179,9877,1404],{"emptyLinePlaceholder":477},[179,9879,9880],{"class":181,"line":1381},[179,9881,9882],{"class":185},"# Créer une branche principale\n",[179,9884,9885,9887,9890,9893],{"class":181,"line":1401},[179,9886,9840],{"class":192},[179,9888,9889],{"class":196}," branch",[179,9891,9892],{"class":224}," -M",[179,9894,9895],{"class":196}," main\n",[179,9897,9898],{"class":181,"line":1407},[179,9899,1404],{"emptyLinePlaceholder":477},[179,9901,9902],{"class":181,"line":1418},[179,9903,9904],{"class":185},"# Ajouter un dépôt distant (optionnel)\n",[179,9906,9907,9909,9912,9914,9917],{"class":181,"line":1435},[179,9908,9840],{"class":192},[179,9910,9911],{"class":196}," remote",[179,9913,203],{"class":196},[179,9915,9916],{"class":196}," origin",[179,9918,9919],{"class":196}," https://github.com/votre-user/mon-projet.git\n",[53,9921,9923],{"id":9922},"fichier-gitignore-essentiel","Fichier .gitignore Essentiel",[102,9925,9929],{"className":9926,"code":9927,"language":9928,"meta":111,"style":111},"language-gitignore shiki shiki-themes github-light github-dark","# Dépendances\nnode_modules/\nvendor/\n__pycache__/\n\n# Fichiers d'environnement\n.env\n.env.local\n.env.production\n\n# Build et compilation\ndist/\nbuild/\n*.log\n\n# IDE et éditeurs\n.vscode/\n.idea/\n*.swp\n*.swo\n\n# Système d'exploitation\n.DS_Store\nThumbs.db\n","gitignore",[109,9930,9931,9936,9941,9946,9951,9955,9960,9965,9970,9975,9979,9984,9989,9994,9999,10003,10008,10013,10018,10023,10028,10032,10037,10042],{"__ignoreMap":111},[179,9932,9933],{"class":181,"line":182},[179,9934,9935],{},"# Dépendances\n",[179,9937,9938],{"class":181,"line":189},[179,9939,9940],{},"node_modules/\n",[179,9942,9943],{"class":181,"line":448},[179,9944,9945],{},"vendor/\n",[179,9947,9948],{"class":181,"line":775},[179,9949,9950],{},"__pycache__/\n",[179,9952,9953],{"class":181,"line":852},[179,9954,1404],{"emptyLinePlaceholder":477},[179,9956,9957],{"class":181,"line":1351},[179,9958,9959],{},"# Fichiers d'environnement\n",[179,9961,9962],{"class":181,"line":1363},[179,9963,9964],{},".env\n",[179,9966,9967],{"class":181,"line":1381},[179,9968,9969],{},".env.local\n",[179,9971,9972],{"class":181,"line":1401},[179,9973,9974],{},".env.production\n",[179,9976,9977],{"class":181,"line":1407},[179,9978,1404],{"emptyLinePlaceholder":477},[179,9980,9981],{"class":181,"line":1418},[179,9982,9983],{},"# Build et compilation\n",[179,9985,9986],{"class":181,"line":1435},[179,9987,9988],{},"dist/\n",[179,9990,9991],{"class":181,"line":1440},[179,9992,9993],{},"build/\n",[179,9995,9996],{"class":181,"line":1450},[179,9997,9998],{},"*.log\n",[179,10000,10001],{"class":181,"line":1483},[179,10002,1404],{"emptyLinePlaceholder":477},[179,10004,10005],{"class":181,"line":1503},[179,10006,10007],{},"# IDE et éditeurs\n",[179,10009,10010],{"class":181,"line":1533},[179,10011,10012],{},".vscode/\n",[179,10014,10015],{"class":181,"line":1557},[179,10016,10017],{},".idea/\n",[179,10019,10020],{"class":181,"line":1583},[179,10021,10022],{},"*.swp\n",[179,10024,10025],{"class":181,"line":1598},[179,10026,10027],{},"*.swo\n",[179,10029,10030],{"class":181,"line":1603},[179,10031,1404],{"emptyLinePlaceholder":477},[179,10033,10034],{"class":181,"line":1615},[179,10035,10036],{},"# Système d'exploitation\n",[179,10038,10039],{"class":181,"line":1629},[179,10040,10041],{},".DS_Store\n",[179,10043,10044],{"class":181,"line":1653},[179,10045,10046],{},"Thumbs.db\n",[12,10048,10050],{"id":10049},"étape-5-configurer-lenvironnement-de-développement","Étape 5 : Configurer l'Environnement de Développement",[53,10052,10054],{"id":10053},"variables-denvironnement","Variables d'Environnement",[17,10056,10057,10058,10061],{},"Créez un fichier ",[109,10059,10060],{},".env.example"," pour documenter les variables nécessaires :",[102,10063,10065],{"className":173,"code":10064,"language":175,"meta":111,"style":111},"# .env.example\nAPI_URL=https://api.example.com\nDATABASE_URL=postgresql://user:password@localhost:5432/dbname\nSECRET_KEY=votre-cle-secrete\nDEBUG=true\n",[109,10066,10067,10072,10082,10091,10101],{"__ignoreMap":111},[179,10068,10069],{"class":181,"line":182},[179,10070,10071],{"class":185},"# .env.example\n",[179,10073,10074,10077,10079],{"class":181,"line":189},[179,10075,10076],{"class":681},"API_URL",[179,10078,685],{"class":549},[179,10080,10081],{"class":196},"https://api.example.com\n",[179,10083,10084,10086,10088],{"class":181,"line":448},[179,10085,8874],{"class":681},[179,10087,685],{"class":549},[179,10089,10090],{"class":196},"postgresql://user:password@localhost:5432/dbname\n",[179,10092,10093,10096,10098],{"class":181,"line":775},[179,10094,10095],{"class":681},"SECRET_KEY",[179,10097,685],{"class":549},[179,10099,10100],{"class":196},"votre-cle-secrete\n",[179,10102,10103,10106,10108],{"class":181,"line":852},[179,10104,10105],{"class":681},"DEBUG",[179,10107,685],{"class":549},[179,10109,10110],{"class":196},"true\n",[3099,10112,10113],{},[17,10114,10115,10116,10119,10120,10122,10123,10126],{},"⚠️ ",[21,10117,10118],{},"Jamais"," de valeurs réelles dans ",[109,10121,10060],{}," et jamais de ",[109,10124,10125],{},".env"," dans Git !",[53,10128,10130],{"id":10129},"scripts-de-démarrage","Scripts de Démarrage",[17,10132,10133],{},"Configurez des scripts utiles dans votre gestionnaire de paquets :",[102,10135,10137],{"className":4843,"code":10136,"language":3783,"meta":111,"style":111},"{\n  \"scripts\": {\n    \"dev\": \"npm run start:dev\",\n    \"build\": \"npm run build:prod\",\n    \"test\": \"jest\",\n    \"lint\": \"eslint src/\",\n    \"format\": \"prettier --write src/\"\n  }\n}\n",[109,10138,10139,10143,10149,10160,10171,10183,10195,10205,10209],{"__ignoreMap":111},[179,10140,10141],{"class":181,"line":182},[179,10142,4851],{"class":681},[179,10144,10145,10147],{"class":181,"line":189},[179,10146,4881],{"class":224},[179,10148,4884],{"class":681},[179,10150,10151,10153,10155,10158],{"class":181,"line":448},[179,10152,4889],{"class":224},[179,10154,4251],{"class":681},[179,10156,10157],{"class":196},"\"npm run start:dev\"",[179,10159,4864],{"class":681},[179,10161,10162,10164,10166,10169],{"class":181,"line":775},[179,10163,4901],{"class":224},[179,10165,4251],{"class":681},[179,10167,10168],{"class":196},"\"npm run build:prod\"",[179,10170,4864],{"class":681},[179,10172,10173,10176,10178,10181],{"class":181,"line":852},[179,10174,10175],{"class":224},"    \"test\"",[179,10177,4251],{"class":681},[179,10179,10180],{"class":196},"\"jest\"",[179,10182,4864],{"class":681},[179,10184,10185,10188,10190,10193],{"class":181,"line":1351},[179,10186,10187],{"class":224},"    \"lint\"",[179,10189,4251],{"class":681},[179,10191,10192],{"class":196},"\"eslint src/\"",[179,10194,4864],{"class":681},[179,10196,10197,10200,10202],{"class":181,"line":1363},[179,10198,10199],{"class":224},"    \"format\"",[179,10201,4251],{"class":681},[179,10203,10204],{"class":196},"\"prettier --write src/\"\n",[179,10206,10207],{"class":181,"line":1381},[179,10208,4514],{"class":681},[179,10210,10211],{"class":181,"line":1401},[179,10212,3814],{"class":681},[12,10214,10216],{"id":10215},"étape-6-adopter-les-bonnes-pratiques-dès-le-départ","Étape 6 : Adopter les Bonnes Pratiques Dès le Départ",[53,10218,10220],{"id":10219},"convention-de-nommage","Convention de Nommage",[33,10222,10223,10237,10246,10255],{},[36,10224,10225,10228,10229,10232,10233,10236],{},[21,10226,10227],{},"Fichiers"," : kebab-case (",[109,10230,10231],{},"mon-fichier.js",") ou camelCase (",[109,10234,10235],{},"monFichier.js",")",[36,10238,10239,10242,10243,10236],{},[21,10240,10241],{},"Classes"," : PascalCase (",[109,10244,10245],{},"MaClasse",[36,10247,10248,10251,10252,10236],{},[21,10249,10250],{},"Constantes"," : UPPER_SNAKE_CASE (",[109,10253,10254],{},"MA_CONSTANTE",[36,10256,10257,10260,10261,5355,10264,10236],{},[21,10258,10259],{},"Fonctions/Variables"," : camelCase (",[109,10262,10263],{},"maFonction",[109,10265,10266],{},"maVariable",[53,10268,10270],{"id":10269},"commentaires-et-documentation","Commentaires et Documentation",[102,10272,10274],{"className":3719,"code":10273,"language":3715,"meta":111,"style":111},"// ❌ À éviter\nlet x = 10; // variable x\n\n// ✅ Préférable\nconst MAX_RETRY_ATTEMPTS = 10; // Nombre maximum de tentatives de reconnexion\n",[109,10275,10276,10281,10299,10303,10308],{"__ignoreMap":111},[179,10277,10278],{"class":181,"line":182},[179,10279,10280],{"class":185},"// ❌ À éviter\n",[179,10282,10283,10286,10289,10291,10293,10296],{"class":181,"line":189},[179,10284,10285],{"class":549},"let",[179,10287,10288],{"class":681}," x ",[179,10290,685],{"class":549},[179,10292,5439],{"class":224},[179,10294,10295],{"class":681},"; ",[179,10297,10298],{"class":185},"// variable x\n",[179,10300,10301],{"class":181,"line":448},[179,10302,1404],{"emptyLinePlaceholder":477},[179,10304,10305],{"class":181,"line":775},[179,10306,10307],{"class":185},"// ✅ Préférable\n",[179,10309,10310,10312,10315,10317,10319,10321],{"class":181,"line":852},[179,10311,3823],{"class":549},[179,10313,10314],{"class":224}," MAX_RETRY_ATTEMPTS",[179,10316,3752],{"class":549},[179,10318,5439],{"class":224},[179,10320,10295],{"class":681},[179,10322,10323],{"class":185},"// Nombre maximum de tentatives de reconnexion\n",[53,10325,10327],{"id":10326},"gestion-des-erreurs","Gestion des Erreurs",[102,10329,10331],{"className":3719,"code":10330,"language":3715,"meta":111,"style":111},"// Mauvaise pratique\ntry {\n  doSomething();\n} catch (e) {\n  console.log(e);\n}\n\n// Bonne pratique\ntry {\n  await doSomething();\n} catch (error) {\n  logger.error('Échec de l\\'opération', { error, context: 'doSomething' });\n  throw new CustomError('OPERATION_FAILED', error);\n}\n",[109,10332,10333,10338,10345,10352,10363,10373,10377,10381,10386,10392,10402,10411,10438,10457],{"__ignoreMap":111},[179,10334,10335],{"class":181,"line":182},[179,10336,10337],{"class":185},"// Mauvaise pratique\n",[179,10339,10340,10343],{"class":181,"line":189},[179,10341,10342],{"class":549},"try",[179,10344,3892],{"class":681},[179,10346,10347,10350],{"class":181,"line":448},[179,10348,10349],{"class":192},"  doSomething",[179,10351,3786],{"class":681},[179,10353,10354,10357,10360],{"class":181,"line":775},[179,10355,10356],{"class":681},"} ",[179,10358,10359],{"class":549},"catch",[179,10361,10362],{"class":681}," (e) {\n",[179,10364,10365,10368,10370],{"class":181,"line":852},[179,10366,10367],{"class":681},"  console.",[179,10369,3858],{"class":192},[179,10371,10372],{"class":681},"(e);\n",[179,10374,10375],{"class":181,"line":1351},[179,10376,3814],{"class":681},[179,10378,10379],{"class":181,"line":1363},[179,10380,1404],{"emptyLinePlaceholder":477},[179,10382,10383],{"class":181,"line":1381},[179,10384,10385],{"class":185},"// Bonne pratique\n",[179,10387,10388,10390],{"class":181,"line":1401},[179,10389,10342],{"class":549},[179,10391,3892],{"class":681},[179,10393,10394,10397,10400],{"class":181,"line":1407},[179,10395,10396],{"class":549},"  await",[179,10398,10399],{"class":192}," doSomething",[179,10401,3786],{"class":681},[179,10403,10404,10406,10408],{"class":181,"line":1418},[179,10405,10356],{"class":681},[179,10407,10359],{"class":549},[179,10409,10410],{"class":681}," (error) {\n",[179,10412,10413,10416,10419,10421,10424,10427,10430,10433,10436],{"class":181,"line":1435},[179,10414,10415],{"class":681},"  logger.",[179,10417,10418],{"class":192},"error",[179,10420,3761],{"class":681},[179,10422,10423],{"class":196},"'Échec de l",[179,10425,10426],{"class":224},"\\'",[179,10428,10429],{"class":196},"opération'",[179,10431,10432],{"class":681},", { error, context: ",[179,10434,10435],{"class":196},"'doSomething'",[179,10437,7058],{"class":681},[179,10439,10440,10443,10446,10449,10451,10454],{"class":181,"line":1440},[179,10441,10442],{"class":549},"  throw",[179,10444,10445],{"class":549}," new",[179,10447,10448],{"class":192}," CustomError",[179,10450,3761],{"class":681},[179,10452,10453],{"class":196},"'OPERATION_FAILED'",[179,10455,10456],{"class":681},", error);\n",[179,10458,10459],{"class":181,"line":1450},[179,10460,3814],{"class":681},[12,10462,10464],{"id":10463},"étape-7-mettre-en-place-les-tests","Étape 7 : Mettre en Place les Tests",[17,10466,10467],{},"Les tests sont cruciaux pour la qualité du code :",[53,10469,10471],{"id":10470},"types-de-tests-à-inclure","Types de Tests à Inclure",[79,10473,10474,10480,10486],{},[36,10475,10476,10479],{},[21,10477,10478],{},"Tests Unitaires"," : Testent des fonctions isolées",[36,10481,10482,10485],{},[21,10483,10484],{},"Tests d'Intégration"," : Testent l'interaction entre composants",[36,10487,10488,10491],{},[21,10489,10490],{},"Tests End-to-End (E2E)"," : Simulent le comportement utilisateur",[53,10493,10495],{"id":10494},"exemple-de-structure-de-tests","Exemple de Structure de Tests",[102,10497,10500],{"className":10498,"code":10499,"language":107},[105],"tests/\n├── unit/\n│   ├── utils.test.js\n│   └── components.test.js\n├── integration/\n│   └── api.test.js\n└── e2e/\n    └── user-flow.test.js\n",[109,10501,10499],{"__ignoreMap":111},[12,10503,10505],{"id":10504},"étape-8-préparer-le-déploiement","Étape 8 : Préparer le Déploiement",[53,10507,10509],{"id":10508},"checklist-de-pré-déploiement","Checklist de Pré-Déploiement",[33,10511,10513,10519,10525,10531,10537,10543],{"className":10512},[7345],[36,10514,10516,10518],{"className":10515},[7349],[7351,10517],{"disabled":477,"type":7353}," Tous les tests passent",[36,10520,10522,10524],{"className":10521},[7349],[7351,10523],{"disabled":477,"type":7353}," Le code est linté et formaté",[36,10526,10528,10530],{"className":10527},[7349],[7351,10529],{"disabled":477,"type":7353}," La documentation est à jour",[36,10532,10534,10536],{"className":10533},[7349],[7351,10535],{"disabled":477,"type":7353}," Les variables d'environnement de production sont configurées",[36,10538,10540,10542],{"className":10539},[7349],[7351,10541],{"disabled":477,"type":7353}," Les secrets ne sont pas dans le code",[36,10544,10546,10548],{"className":10545},[7349],[7351,10547],{"disabled":477,"type":7353}," Un plan de rollback est prévu",[53,10550,10552],{"id":10551},"cicd-de-base","CI/CD de Base",[17,10554,10555],{},"Envisagez d'automatiser avec GitHub Actions, GitLab CI, ou Jenkins :",[102,10557,10559],{"className":4955,"code":10558,"language":4951,"meta":111,"style":111},"# .github/workflows/ci.yml (exemple GitHub Actions)\nname: CI\non: [push, pull_request]\njobs:\n  test:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v2\n      - run: npm install\n      - run: npm test\n      - run: npm run lint\n",[109,10560,10561,10566,10575,10594,10601,10608,10618,10625,10637,10649,10660],{"__ignoreMap":111},[179,10562,10563],{"class":181,"line":182},[179,10564,10565],{"class":185},"# .github/workflows/ci.yml (exemple GitHub Actions)\n",[179,10567,10568,10570,10572],{"class":181,"line":189},[179,10569,3833],{"class":4053},[179,10571,4251],{"class":681},[179,10573,10574],{"class":196},"CI\n",[179,10576,10577,10580,10583,10586,10588,10591],{"class":181,"line":448},[179,10578,10579],{"class":224},"on",[179,10581,10582],{"class":681},": [",[179,10584,10585],{"class":196},"push",[179,10587,5355],{"class":681},[179,10589,10590],{"class":196},"pull_request",[179,10592,10593],{"class":681},"]\n",[179,10595,10596,10599],{"class":181,"line":775},[179,10597,10598],{"class":4053},"jobs",[179,10600,4966],{"class":681},[179,10602,10603,10606],{"class":181,"line":852},[179,10604,10605],{"class":4053},"  test",[179,10607,4966],{"class":681},[179,10609,10610,10613,10615],{"class":181,"line":1351},[179,10611,10612],{"class":4053},"    runs-on",[179,10614,4251],{"class":681},[179,10616,10617],{"class":196},"ubuntu-latest\n",[179,10619,10620,10623],{"class":181,"line":1363},[179,10621,10622],{"class":4053},"    steps",[179,10624,4966],{"class":681},[179,10626,10627,10629,10632,10634],{"class":181,"line":1381},[179,10628,8560],{"class":681},[179,10630,10631],{"class":4053},"uses",[179,10633,4251],{"class":681},[179,10635,10636],{"class":196},"actions/checkout@v2\n",[179,10638,10639,10641,10644,10646],{"class":181,"line":1401},[179,10640,8560],{"class":681},[179,10642,10643],{"class":4053},"run",[179,10645,4251],{"class":681},[179,10647,10648],{"class":196},"npm install\n",[179,10650,10651,10653,10655,10657],{"class":181,"line":1407},[179,10652,8560],{"class":681},[179,10654,10643],{"class":4053},[179,10656,4251],{"class":681},[179,10658,10659],{"class":196},"npm test\n",[179,10661,10662,10664,10666,10668],{"class":181,"line":1418},[179,10663,8560],{"class":681},[179,10665,10643],{"class":4053},[179,10667,4251],{"class":681},[179,10669,10670],{"class":196},"npm run lint\n",[12,10672,406],{"id":405},[17,10674,10675],{},"Créer un projet bien structuré demande un investissement initial, mais cela paie rapidement :",[33,10677,10678,10685,10692,10699],{},[36,10679,10680,10681,10684],{},"🎯 ",[21,10682,10683],{},"Moins de bugs"," grâce à une organisation claire",[36,10686,10687,10688,10691],{},"⚡ ",[21,10689,10690],{},"Développement plus rapide"," avec des conventions établies",[36,10693,10694,10695,10698],{},"🤝 ",[21,10696,10697],{},"Meilleure collaboration"," en équipe",[36,10700,10701,10702,10705],{},"📈 ",[21,10703,10704],{},"Évolution facilitée"," quand le projet grandit",[53,10707,10709],{"id":10708},"prochaines-étapes","Prochaines Étapes",[79,10711,10712,10715,10718,10721],{},[36,10713,10714],{},"Appliquez ces principes à votre prochain projet",[36,10716,10717],{},"Adaptez la structure à vos besoins spécifiques",[36,10719,10720],{},"Documentez vos propres conventions d'équipe",[36,10722,10723],{},"Revoyez régulièrement l'organisation pour l'améliorer",[10725,10726],"hr",{},[17,10728,10729],{},[21,10730,10731],{},"📚 Ressources Utiles :",[33,10733,10734,10741,10748],{},[36,10735,10736],{},[730,10737,10740],{"href":10738,"rel":10739},"https://github.com/features/code-security",[734],"GitHub Best Practices",[36,10742,10743],{},[730,10744,10747],{"href":10745,"rel":10746},"https://12factor.net/",[734],"12 Factor App",[36,10749,10750],{},[730,10751,10754],{"href":10752,"rel":10753},"https://blog.cleancoder.com/",[734],"Clean Code Principles",[17,10756,10757,10760],{},[21,10758,10759],{},"💡 Besoin d'aide ?"," Rejoignez la communauté Learn'in pour échanger avec d'autres développeurs !",[438,10762,10763],{},"html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .s9eBZ, html code.shiki .s9eBZ{--shiki-default:#22863A;--shiki-dark:#85E89D}",{"title":111,"searchDepth":189,"depth":189,"links":10765},[10766,10767,10771,10774,10777,10780,10784,10789,10793,10797],{"id":9571,"depth":189,"text":9572},{"id":9604,"depth":189,"text":9605,"children":10768},[10769,10770],{"id":9611,"depth":448,"text":9612},{"id":9645,"depth":448,"text":9646},{"id":9661,"depth":189,"text":9662,"children":10772},[10773],{"id":9722,"depth":448,"text":9723},{"id":9740,"depth":189,"text":9741,"children":10775},[10776],{"id":9753,"depth":448,"text":9754},{"id":9821,"depth":189,"text":9822,"children":10778},[10779],{"id":9922,"depth":448,"text":9923},{"id":10049,"depth":189,"text":10050,"children":10781},[10782,10783],{"id":10053,"depth":448,"text":10054},{"id":10129,"depth":448,"text":10130},{"id":10215,"depth":189,"text":10216,"children":10785},[10786,10787,10788],{"id":10219,"depth":448,"text":10220},{"id":10269,"depth":448,"text":10270},{"id":10326,"depth":448,"text":10327},{"id":10463,"depth":189,"text":10464,"children":10790},[10791,10792],{"id":10470,"depth":448,"text":10471},{"id":10494,"depth":448,"text":10495},{"id":10504,"depth":189,"text":10505,"children":10794},[10795,10796],{"id":10508,"depth":448,"text":10509},{"id":10551,"depth":448,"text":10552},{"id":405,"depth":189,"text":406,"children":10798},[10799],{"id":10708,"depth":448,"text":10709},"Apprenez à créer un projet de développement bien structuré. Étapes, organisation, outils et bonnes pratiques pour démarrer sur de bonnes bases.","/images/posts/2026/03/guide-complet-comment-creer-un-projet-de-developpement-structure.webp",{},"/posts/guide-complet-comment-creer-un-projet-de-developpement-structure",{"title":9560,"description":10800},"posts/guide-complet-comment-creer-un-projet-de-developpement-structure",[10807,7456,10808,3608,10809,10810],"projet","organisation","tutoriel","structure","TtwiNiLuyrmHuXkMuvTDRKPZEtJSUgXRqeuaMtvpr6g",{"id":10813,"title":10814,"author":23,"body":10815,"date":8118,"description":12385,"extension":474,"image":12386,"meta":12387,"navigation":477,"path":12388,"readingTime":479,"seo":12389,"stem":12390,"tags":12391,"updatedAt":8118,"__hash__":12396},"posts/posts/maitriser-nginx-installation-configuration-et-bonnes-pratiques.md","Maîtriser Nginx : Installation, Configuration et Bonnes Pratiques",{"type":9,"value":10816,"toc":12343},[10817,10820,10823,10826,10830,10833,10865,10869,10871,10963,10967,11043,11047,11111,11114,11121,11127,11131,11138,11223,11227,11230,11234,11240,11311,11315,11377,11381,11385,11433,11437,11567,11571,11574,11578,11657,11661,11740,11744,11747,11826,11830,11834,11882,11886,11910,11914,11947,11951,11955,11973,11977,12024,12028,12061,12065,12089,12093,12209,12212,12216,12256,12260,12263,12267,12303,12305,12308,12311,12313,12318,12341],[4662,10818,10814],{"id":10819},"maîtriser-nginx-installation-configuration-et-bonnes-pratiques",[17,10821,10822],{},"Nginx (prononcé \"Engine-X\") est l'un des serveurs web les plus populaires au monde. Connu pour ses performances exceptionnelles et sa faible consommation de ressources, il est devenu un choix privilégié pour héberger des sites web à fort trafic.",[17,10824,10825],{},"Dans ce guide, nous allons explorer l'installation, la configuration et les meilleures pratiques pour exploiter pleinement Nginx.",[12,10827,10829],{"id":10828},"pourquoi-choisir-nginx","Pourquoi Choisir Nginx ?",[17,10831,10832],{},"Nginx se distingue par plusieurs avantages majeurs :",[33,10834,10835,10841,10847,10853,10859],{},[36,10836,10837,10840],{},[21,10838,10839],{},"Performance élevée"," : Architecture événementielle permettant de gérer des milliers de connexions simultanées",[36,10842,10843,10846],{},[21,10844,10845],{},"Faible consommation mémoire"," : Beaucoup plus léger que Apache dans la plupart des cas",[36,10848,10849,10852],{},[21,10850,10851],{},"Reverse proxy intégré"," : Idéal pour la mise en place de load balancing",[36,10854,10855,10858],{},[21,10856,10857],{},"Serveur de cache"," : Améliore significativement les temps de réponse",[36,10860,10861,10864],{},[21,10862,10863],{},"Configuration simple"," : Syntaxe claire et facile à comprendre",[12,10866,10868],{"id":10867},"installation-de-nginx","Installation de Nginx",[53,10870,7528],{"id":7527},[102,10872,10874],{"className":173,"code":10873,"language":175,"meta":111,"style":111},"# Mettre à jour les paquets\nsudo apt update\n\n# Installer Nginx\nsudo apt install nginx\n\n# Vérifier l'installation\nnginx -v\n\n# Démarrer le service\nsudo systemctl start nginx\n\n# Activer au démarrage\nsudo systemctl enable nginx\n",[109,10875,10876,10881,10889,10893,10898,10909,10913,10918,10925,10929,10934,10944,10948,10953],{"__ignoreMap":111},[179,10877,10878],{"class":181,"line":182},[179,10879,10880],{"class":185},"# Mettre à jour les paquets\n",[179,10882,10883,10885,10887],{"class":181,"line":189},[179,10884,567],{"class":192},[179,10886,621],{"class":196},[179,10888,624],{"class":196},[179,10890,10891],{"class":181,"line":448},[179,10892,1404],{"emptyLinePlaceholder":477},[179,10894,10895],{"class":181,"line":775},[179,10896,10897],{"class":185},"# Installer Nginx\n",[179,10899,10900,10902,10904,10906],{"class":181,"line":852},[179,10901,567],{"class":192},[179,10903,621],{"class":196},[179,10905,573],{"class":196},[179,10907,10908],{"class":196}," nginx\n",[179,10910,10911],{"class":181,"line":1351},[179,10912,1404],{"emptyLinePlaceholder":477},[179,10914,10915],{"class":181,"line":1363},[179,10916,10917],{"class":185},"# Vérifier l'installation\n",[179,10919,10920,10923],{"class":181,"line":1381},[179,10921,10922],{"class":192},"nginx",[179,10924,595],{"class":224},[179,10926,10927],{"class":181,"line":1401},[179,10928,1404],{"emptyLinePlaceholder":477},[179,10930,10931],{"class":181,"line":1407},[179,10932,10933],{"class":185},"# Démarrer le service\n",[179,10935,10936,10938,10940,10942],{"class":181,"line":1418},[179,10937,567],{"class":192},[179,10939,7611],{"class":196},[179,10941,7614],{"class":196},[179,10943,10908],{"class":196},[179,10945,10946],{"class":181,"line":1435},[179,10947,1404],{"emptyLinePlaceholder":477},[179,10949,10950],{"class":181,"line":1440},[179,10951,10952],{"class":185},"# Activer au démarrage\n",[179,10954,10955,10957,10959,10961],{"class":181,"line":1450},[179,10956,567],{"class":192},[179,10958,7611],{"class":196},[179,10960,7625],{"class":196},[179,10962,10908],{"class":196},[53,10964,10966],{"id":10965},"sur-centosrhel","Sur CentOS/RHEL",[102,10968,10970],{"className":173,"code":10969,"language":175,"meta":111,"style":111},"# Ajouter le repository EPEL\nsudo yum install epel-release\n\n# Installer Nginx\nsudo yum install nginx\n\n# Démarrer le service\nsudo systemctl start nginx\n\n# Activer au démarrage\nsudo systemctl enable nginx\n",[109,10971,10972,10977,10989,10993,10997,11007,11011,11015,11025,11029,11033],{"__ignoreMap":111},[179,10973,10974],{"class":181,"line":182},[179,10975,10976],{"class":185},"# Ajouter le repository EPEL\n",[179,10978,10979,10981,10984,10986],{"class":181,"line":189},[179,10980,567],{"class":192},[179,10982,10983],{"class":196}," yum",[179,10985,573],{"class":196},[179,10987,10988],{"class":196}," epel-release\n",[179,10990,10991],{"class":181,"line":448},[179,10992,1404],{"emptyLinePlaceholder":477},[179,10994,10995],{"class":181,"line":775},[179,10996,10897],{"class":185},[179,10998,10999,11001,11003,11005],{"class":181,"line":852},[179,11000,567],{"class":192},[179,11002,10983],{"class":196},[179,11004,573],{"class":196},[179,11006,10908],{"class":196},[179,11008,11009],{"class":181,"line":1351},[179,11010,1404],{"emptyLinePlaceholder":477},[179,11012,11013],{"class":181,"line":1363},[179,11014,10933],{"class":185},[179,11016,11017,11019,11021,11023],{"class":181,"line":1381},[179,11018,567],{"class":192},[179,11020,7611],{"class":196},[179,11022,7614],{"class":196},[179,11024,10908],{"class":196},[179,11026,11027],{"class":181,"line":1401},[179,11028,1404],{"emptyLinePlaceholder":477},[179,11030,11031],{"class":181,"line":1407},[179,11032,10952],{"class":185},[179,11034,11035,11037,11039,11041],{"class":181,"line":1418},[179,11036,567],{"class":192},[179,11038,7611],{"class":196},[179,11040,7625],{"class":196},[179,11042,10908],{"class":196},[53,11044,11046],{"id":11045},"sur-macos-avec-homebrew","Sur macOS (avec Homebrew)",[102,11048,11050],{"className":173,"code":11049,"language":175,"meta":111,"style":111},"# Installer Homebrew si nécessaire\n/bin/bash -c \"$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)\"\n\n# Installer Nginx\nbrew install nginx\n\n# Démarrer le service\nbrew services start nginx\n",[109,11051,11052,11057,11075,11079,11083,11092,11096,11100],{"__ignoreMap":111},[179,11053,11054],{"class":181,"line":182},[179,11055,11056],{"class":185},"# Installer Homebrew si nécessaire\n",[179,11058,11059,11062,11065,11068,11070,11072],{"class":181,"line":189},[179,11060,11061],{"class":192},"/bin/bash",[179,11063,11064],{"class":224}," -c",[179,11066,11067],{"class":196}," \"$(",[179,11069,540],{"class":192},[179,11071,543],{"class":224},[179,11073,11074],{"class":196}," https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)\"\n",[179,11076,11077],{"class":181,"line":448},[179,11078,1404],{"emptyLinePlaceholder":477},[179,11080,11081],{"class":181,"line":775},[179,11082,10897],{"class":185},[179,11084,11085,11088,11090],{"class":181,"line":852},[179,11086,11087],{"class":192},"brew",[179,11089,573],{"class":196},[179,11091,10908],{"class":196},[179,11093,11094],{"class":181,"line":1351},[179,11095,1404],{"emptyLinePlaceholder":477},[179,11097,11098],{"class":181,"line":1363},[179,11099,10933],{"class":185},[179,11101,11102,11104,11107,11109],{"class":181,"line":1381},[179,11103,11087],{"class":192},[179,11105,11106],{"class":196}," services",[179,11108,7614],{"class":196},[179,11110,10908],{"class":196},[12,11112,11113],{"id":7637},"Structure de Configuration",[17,11115,11116,11117,11120],{},"La configuration de Nginx se trouve généralement dans ",[109,11118,11119],{},"/etc/nginx/",". Voici la structure typique :",[102,11122,11125],{"className":11123,"code":11124,"language":107},[105],"/etc/nginx/\n├── nginx.conf          # Configuration principale\n├── conf.d/             # Configurations supplémentaires\n├── sites-available/    # Sites disponibles (Debian/Ubuntu)\n├── sites-enabled/      # Sites activés (Debian/Ubuntu)\n└── ssl/                # Certificats SSL\n",[109,11126,11124],{"__ignoreMap":111},[53,11128,11130],{"id":11129},"fichier-de-configuration-principal","Fichier de Configuration Principal",[17,11132,11133,11134,11137],{},"Le fichier ",[109,11135,11136],{},"nginx.conf"," contient la configuration globale :",[102,11139,11142],{"className":11140,"code":11141,"language":10922,"meta":111,"style":111},"language-nginx shiki shiki-themes github-light github-dark","user www-data;\nworker_processes auto;\npid /run/nginx.pid;\n\nevents {\n    worker_connections 1024;\n}\n\nhttp {\n    include /etc/nginx/mime.types;\n    default_type application/octet-stream;\n\n    sendfile on;\n    keepalive_timeout 65;\n\n    include /etc/nginx/conf.d/*.conf;\n}\n",[109,11143,11144,11149,11154,11159,11163,11168,11173,11177,11181,11186,11191,11196,11200,11205,11210,11214,11219],{"__ignoreMap":111},[179,11145,11146],{"class":181,"line":182},[179,11147,11148],{},"user www-data;\n",[179,11150,11151],{"class":181,"line":189},[179,11152,11153],{},"worker_processes auto;\n",[179,11155,11156],{"class":181,"line":448},[179,11157,11158],{},"pid /run/nginx.pid;\n",[179,11160,11161],{"class":181,"line":775},[179,11162,1404],{"emptyLinePlaceholder":477},[179,11164,11165],{"class":181,"line":852},[179,11166,11167],{},"events {\n",[179,11169,11170],{"class":181,"line":1351},[179,11171,11172],{},"    worker_connections 1024;\n",[179,11174,11175],{"class":181,"line":1363},[179,11176,3814],{},[179,11178,11179],{"class":181,"line":1381},[179,11180,1404],{"emptyLinePlaceholder":477},[179,11182,11183],{"class":181,"line":1401},[179,11184,11185],{},"http {\n",[179,11187,11188],{"class":181,"line":1407},[179,11189,11190],{},"    include /etc/nginx/mime.types;\n",[179,11192,11193],{"class":181,"line":1418},[179,11194,11195],{},"    default_type application/octet-stream;\n",[179,11197,11198],{"class":181,"line":1435},[179,11199,1404],{"emptyLinePlaceholder":477},[179,11201,11202],{"class":181,"line":1440},[179,11203,11204],{},"    sendfile on;\n",[179,11206,11207],{"class":181,"line":1450},[179,11208,11209],{},"    keepalive_timeout 65;\n",[179,11211,11212],{"class":181,"line":1483},[179,11213,1404],{"emptyLinePlaceholder":477},[179,11215,11216],{"class":181,"line":1503},[179,11217,11218],{},"    include /etc/nginx/conf.d/*.conf;\n",[179,11220,11221],{"class":181,"line":1533},[179,11222,3814],{},[12,11224,11226],{"id":11225},"configuration-dun-serveur-virtuel","Configuration d'un Serveur Virtuel",[17,11228,11229],{},"Un serveur virtuel permet d'héberger plusieurs sites sur un même serveur.",[53,11231,11233],{"id":11232},"configuration-de-base","Configuration de Base",[17,11235,11236,11237,642],{},"Créez un fichier dans ",[109,11238,11239],{},"/etc/nginx/sites-available/monsite.conf",[102,11241,11243],{"className":11140,"code":11242,"language":10922,"meta":111,"style":111},"server {\n    listen 80;\n    server_name monsite.com www.monsite.com;\n    root /var/www/monsite;\n    index index.html index.htm;\n\n    location / {\n        try_files $uri $uri/ =404;\n    }\n\n    # Logs\n    access_log /var/log/nginx/monsite_access.log;\n    error_log /var/log/nginx/monsite_error.log;\n}\n",[109,11244,11245,11250,11255,11260,11265,11270,11274,11279,11284,11288,11292,11297,11302,11307],{"__ignoreMap":111},[179,11246,11247],{"class":181,"line":182},[179,11248,11249],{},"server {\n",[179,11251,11252],{"class":181,"line":189},[179,11253,11254],{},"    listen 80;\n",[179,11256,11257],{"class":181,"line":448},[179,11258,11259],{},"    server_name monsite.com www.monsite.com;\n",[179,11261,11262],{"class":181,"line":775},[179,11263,11264],{},"    root /var/www/monsite;\n",[179,11266,11267],{"class":181,"line":852},[179,11268,11269],{},"    index index.html index.htm;\n",[179,11271,11272],{"class":181,"line":1351},[179,11273,1404],{"emptyLinePlaceholder":477},[179,11275,11276],{"class":181,"line":1363},[179,11277,11278],{},"    location / {\n",[179,11280,11281],{"class":181,"line":1381},[179,11282,11283],{},"        try_files $uri $uri/ =404;\n",[179,11285,11286],{"class":181,"line":1401},[179,11287,5320],{},[179,11289,11290],{"class":181,"line":1407},[179,11291,1404],{"emptyLinePlaceholder":477},[179,11293,11294],{"class":181,"line":1418},[179,11295,11296],{},"    # Logs\n",[179,11298,11299],{"class":181,"line":1435},[179,11300,11301],{},"    access_log /var/log/nginx/monsite_access.log;\n",[179,11303,11304],{"class":181,"line":1440},[179,11305,11306],{},"    error_log /var/log/nginx/monsite_error.log;\n",[179,11308,11309],{"class":181,"line":1450},[179,11310,3814],{},[53,11312,11314],{"id":11313},"activer-le-site","Activer le Site",[102,11316,11318],{"className":173,"code":11317,"language":175,"meta":111,"style":111},"# Créer un lien symbolique vers sites-enabled\nsudo ln -s /etc/nginx/sites-available/monsite.conf /etc/nginx/sites-enabled/\n\n# Tester la configuration\nsudo nginx -t\n\n# Recharger Nginx\nsudo systemctl reload nginx\n",[109,11319,11320,11325,11340,11344,11349,11358,11362,11367],{"__ignoreMap":111},[179,11321,11322],{"class":181,"line":182},[179,11323,11324],{"class":185},"# Créer un lien symbolique vers sites-enabled\n",[179,11326,11327,11329,11332,11334,11337],{"class":181,"line":189},[179,11328,567],{"class":192},[179,11330,11331],{"class":196}," ln",[179,11333,8412],{"class":224},[179,11335,11336],{"class":196}," /etc/nginx/sites-available/monsite.conf",[179,11338,11339],{"class":196}," /etc/nginx/sites-enabled/\n",[179,11341,11342],{"class":181,"line":448},[179,11343,1404],{"emptyLinePlaceholder":477},[179,11345,11346],{"class":181,"line":775},[179,11347,11348],{"class":185},"# Tester la configuration\n",[179,11350,11351,11353,11356],{"class":181,"line":852},[179,11352,567],{"class":192},[179,11354,11355],{"class":196}," nginx",[179,11357,7718],{"class":224},[179,11359,11360],{"class":181,"line":1351},[179,11361,1404],{"emptyLinePlaceholder":477},[179,11363,11364],{"class":181,"line":1363},[179,11365,11366],{"class":185},"# Recharger Nginx\n",[179,11368,11369,11371,11373,11375],{"class":181,"line":1381},[179,11370,567],{"class":192},[179,11372,7611],{"class":196},[179,11374,7735],{"class":196},[179,11376,10908],{"class":196},[12,11378,11380],{"id":11379},"configuration-https-avec-ssltls","Configuration HTTPS avec SSL/TLS",[53,11382,11384],{"id":11383},"obtenir-un-certificat-lets-encrypt","Obtenir un Certificat Let's Encrypt",[102,11386,11388],{"className":173,"code":11387,"language":175,"meta":111,"style":111},"# Installer Certbot\nsudo apt install certbot python3-certbot-nginx\n\n# Obtenir un certificat\nsudo certbot --nginx -d monsite.com -d www.monsite.com\n",[109,11389,11390,11394,11407,11411,11415],{"__ignoreMap":111},[179,11391,11392],{"class":181,"line":182},[179,11393,9017],{"class":185},[179,11395,11396,11398,11400,11402,11404],{"class":181,"line":189},[179,11397,567],{"class":192},[179,11399,621],{"class":196},[179,11401,573],{"class":196},[179,11403,8070],{"class":196},[179,11405,11406],{"class":196}," python3-certbot-nginx\n",[179,11408,11409],{"class":181,"line":448},[179,11410,1404],{"emptyLinePlaceholder":477},[179,11412,11413],{"class":181,"line":775},[179,11414,9039],{"class":185},[179,11416,11417,11419,11421,11423,11425,11428,11430],{"class":181,"line":852},[179,11418,567],{"class":192},[179,11420,8070],{"class":196},[179,11422,9047],{"class":224},[179,11424,9050],{"class":224},[179,11426,11427],{"class":196}," monsite.com",[179,11429,9050],{"class":224},[179,11431,11432],{"class":196}," www.monsite.com\n",[53,11434,11436],{"id":11435},"configuration-manuelle-ssl","Configuration Manuelle SSL",[102,11438,11440],{"className":11140,"code":11439,"language":10922,"meta":111,"style":111},"server {\n    listen 443 ssl http2;\n    server_name monsite.com;\n\n    ssl_certificate /etc/nginx/ssl/monsite.crt;\n    ssl_certificate_key /etc/nginx/ssl/monsite.key;\n\n    # Paramètres SSL recommandés\n    ssl_protocols TLSv1.2 TLSv1.3;\n    ssl_ciphers HIGH:!aNULL:!MD5;\n    ssl_prefer_server_ciphers on;\n    ssl_session_cache shared:SSL:10m;\n    ssl_session_timeout 10m;\n\n    root /var/www/monsite;\n    index index.html;\n\n    location / {\n        try_files $uri $uri/ =404;\n    }\n}\n\n# Redirection HTTP vers HTTPS\nserver {\n    listen 80;\n    server_name monsite.com;\n    return 301 https://$server_name$request_uri;\n}\n",[109,11441,11442,11446,11451,11456,11460,11465,11470,11474,11479,11484,11489,11494,11499,11504,11508,11512,11517,11521,11525,11529,11533,11537,11541,11546,11550,11554,11558,11563],{"__ignoreMap":111},[179,11443,11444],{"class":181,"line":182},[179,11445,11249],{},[179,11447,11448],{"class":181,"line":189},[179,11449,11450],{},"    listen 443 ssl http2;\n",[179,11452,11453],{"class":181,"line":448},[179,11454,11455],{},"    server_name monsite.com;\n",[179,11457,11458],{"class":181,"line":775},[179,11459,1404],{"emptyLinePlaceholder":477},[179,11461,11462],{"class":181,"line":852},[179,11463,11464],{},"    ssl_certificate /etc/nginx/ssl/monsite.crt;\n",[179,11466,11467],{"class":181,"line":1351},[179,11468,11469],{},"    ssl_certificate_key /etc/nginx/ssl/monsite.key;\n",[179,11471,11472],{"class":181,"line":1363},[179,11473,1404],{"emptyLinePlaceholder":477},[179,11475,11476],{"class":181,"line":1381},[179,11477,11478],{},"    # Paramètres SSL recommandés\n",[179,11480,11481],{"class":181,"line":1401},[179,11482,11483],{},"    ssl_protocols TLSv1.2 TLSv1.3;\n",[179,11485,11486],{"class":181,"line":1407},[179,11487,11488],{},"    ssl_ciphers HIGH:!aNULL:!MD5;\n",[179,11490,11491],{"class":181,"line":1418},[179,11492,11493],{},"    ssl_prefer_server_ciphers on;\n",[179,11495,11496],{"class":181,"line":1435},[179,11497,11498],{},"    ssl_session_cache shared:SSL:10m;\n",[179,11500,11501],{"class":181,"line":1440},[179,11502,11503],{},"    ssl_session_timeout 10m;\n",[179,11505,11506],{"class":181,"line":1450},[179,11507,1404],{"emptyLinePlaceholder":477},[179,11509,11510],{"class":181,"line":1483},[179,11511,11264],{},[179,11513,11514],{"class":181,"line":1503},[179,11515,11516],{},"    index index.html;\n",[179,11518,11519],{"class":181,"line":1533},[179,11520,1404],{"emptyLinePlaceholder":477},[179,11522,11523],{"class":181,"line":1557},[179,11524,11278],{},[179,11526,11527],{"class":181,"line":1583},[179,11528,11283],{},[179,11530,11531],{"class":181,"line":1598},[179,11532,5320],{},[179,11534,11535],{"class":181,"line":1603},[179,11536,3814],{},[179,11538,11539],{"class":181,"line":1615},[179,11540,1404],{"emptyLinePlaceholder":477},[179,11542,11543],{"class":181,"line":1629},[179,11544,11545],{},"# Redirection HTTP vers HTTPS\n",[179,11547,11548],{"class":181,"line":1653},[179,11549,11249],{},[179,11551,11552],{"class":181,"line":1686},[179,11553,11254],{},[179,11555,11556],{"class":181,"line":1709},[179,11557,11455],{},[179,11559,11560],{"class":181,"line":1720},[179,11561,11562],{},"    return 301 https://$server_name$request_uri;\n",[179,11564,11565],{"class":181,"line":1741},[179,11566,3814],{},[12,11568,11570],{"id":11569},"nginx-comme-reverse-proxy","Nginx comme Reverse Proxy",[17,11572,11573],{},"Nginx excelle en tant que reverse proxy pour des applications backend.",[53,11575,11577],{"id":11576},"proxy-vers-une-application-nodejs","Proxy vers une Application Node.js",[102,11579,11581],{"className":11140,"code":11580,"language":10922,"meta":111,"style":111},"server {\n    listen 80;\n    server_name api.monsite.com;\n\n    location / {\n        proxy_pass http://localhost:3000;\n        proxy_http_version 1.1;\n        proxy_set_header Upgrade $http_upgrade;\n        proxy_set_header Connection 'upgrade';\n        proxy_set_header Host $host;\n        proxy_set_header X-Real-IP $remote_addr;\n        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n        proxy_set_header X-Forwarded-Proto $scheme;\n        proxy_cache_bypass $http_upgrade;\n    }\n}\n",[109,11582,11583,11587,11591,11596,11600,11604,11609,11614,11619,11624,11629,11634,11639,11644,11649,11653],{"__ignoreMap":111},[179,11584,11585],{"class":181,"line":182},[179,11586,11249],{},[179,11588,11589],{"class":181,"line":189},[179,11590,11254],{},[179,11592,11593],{"class":181,"line":448},[179,11594,11595],{},"    server_name api.monsite.com;\n",[179,11597,11598],{"class":181,"line":775},[179,11599,1404],{"emptyLinePlaceholder":477},[179,11601,11602],{"class":181,"line":852},[179,11603,11278],{},[179,11605,11606],{"class":181,"line":1351},[179,11607,11608],{},"        proxy_pass http://localhost:3000;\n",[179,11610,11611],{"class":181,"line":1363},[179,11612,11613],{},"        proxy_http_version 1.1;\n",[179,11615,11616],{"class":181,"line":1381},[179,11617,11618],{},"        proxy_set_header Upgrade $http_upgrade;\n",[179,11620,11621],{"class":181,"line":1401},[179,11622,11623],{},"        proxy_set_header Connection 'upgrade';\n",[179,11625,11626],{"class":181,"line":1407},[179,11627,11628],{},"        proxy_set_header Host $host;\n",[179,11630,11631],{"class":181,"line":1418},[179,11632,11633],{},"        proxy_set_header X-Real-IP $remote_addr;\n",[179,11635,11636],{"class":181,"line":1435},[179,11637,11638],{},"        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n",[179,11640,11641],{"class":181,"line":1440},[179,11642,11643],{},"        proxy_set_header X-Forwarded-Proto $scheme;\n",[179,11645,11646],{"class":181,"line":1450},[179,11647,11648],{},"        proxy_cache_bypass $http_upgrade;\n",[179,11650,11651],{"class":181,"line":1483},[179,11652,5320],{},[179,11654,11655],{"class":181,"line":1503},[179,11656,3814],{},[53,11658,11660],{"id":11659},"proxy-vers-une-application-php-fpm","Proxy vers une Application PHP-FPM",[102,11662,11664],{"className":11140,"code":11663,"language":10922,"meta":111,"style":111},"server {\n    listen 80;\n    server_name monsite.com;\n    root /var/www/monsite;\n    index index.php index.html;\n\n    location / {\n        try_files $uri $uri/ =404;\n    }\n\n    location ~ \\.php$ {\n        include snippets/fastcgi-php.conf;\n        fastcgi_pass unix:/run/php/php-fpm.sock;\n        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;\n        include fastcgi_params;\n    }\n}\n",[109,11665,11666,11670,11674,11678,11682,11687,11691,11695,11699,11703,11707,11712,11717,11722,11727,11732,11736],{"__ignoreMap":111},[179,11667,11668],{"class":181,"line":182},[179,11669,11249],{},[179,11671,11672],{"class":181,"line":189},[179,11673,11254],{},[179,11675,11676],{"class":181,"line":448},[179,11677,11455],{},[179,11679,11680],{"class":181,"line":775},[179,11681,11264],{},[179,11683,11684],{"class":181,"line":852},[179,11685,11686],{},"    index index.php index.html;\n",[179,11688,11689],{"class":181,"line":1351},[179,11690,1404],{"emptyLinePlaceholder":477},[179,11692,11693],{"class":181,"line":1363},[179,11694,11278],{},[179,11696,11697],{"class":181,"line":1381},[179,11698,11283],{},[179,11700,11701],{"class":181,"line":1401},[179,11702,5320],{},[179,11704,11705],{"class":181,"line":1407},[179,11706,1404],{"emptyLinePlaceholder":477},[179,11708,11709],{"class":181,"line":1418},[179,11710,11711],{},"    location ~ \\.php$ {\n",[179,11713,11714],{"class":181,"line":1435},[179,11715,11716],{},"        include snippets/fastcgi-php.conf;\n",[179,11718,11719],{"class":181,"line":1440},[179,11720,11721],{},"        fastcgi_pass unix:/run/php/php-fpm.sock;\n",[179,11723,11724],{"class":181,"line":1450},[179,11725,11726],{},"        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;\n",[179,11728,11729],{"class":181,"line":1483},[179,11730,11731],{},"        include fastcgi_params;\n",[179,11733,11734],{"class":181,"line":1503},[179,11735,5320],{},[179,11737,11738],{"class":181,"line":1533},[179,11739,3814],{},[12,11741,11743],{"id":11742},"load-balancing","Load Balancing",[17,11745,11746],{},"Nginx permet de répartir la charge entre plusieurs serveurs backend.",[102,11748,11750],{"className":11140,"code":11749,"language":10922,"meta":111,"style":111},"upstream backend_servers {\n    least_conn;\n    server 192.168.1.10:80 weight=3;\n    server 192.168.1.11:80 weight=2;\n    server 192.168.1.12:80 backup;\n}\n\nserver {\n    listen 80;\n    server_name monsite.com;\n\n    location / {\n        proxy_pass http://backend_servers;\n        proxy_set_header Host $host;\n        proxy_set_header X-Real-IP $remote_addr;\n    }\n}\n",[109,11751,11752,11757,11762,11767,11772,11777,11781,11785,11789,11793,11797,11801,11805,11810,11814,11818,11822],{"__ignoreMap":111},[179,11753,11754],{"class":181,"line":182},[179,11755,11756],{},"upstream backend_servers {\n",[179,11758,11759],{"class":181,"line":189},[179,11760,11761],{},"    least_conn;\n",[179,11763,11764],{"class":181,"line":448},[179,11765,11766],{},"    server 192.168.1.10:80 weight=3;\n",[179,11768,11769],{"class":181,"line":775},[179,11770,11771],{},"    server 192.168.1.11:80 weight=2;\n",[179,11773,11774],{"class":181,"line":852},[179,11775,11776],{},"    server 192.168.1.12:80 backup;\n",[179,11778,11779],{"class":181,"line":1351},[179,11780,3814],{},[179,11782,11783],{"class":181,"line":1363},[179,11784,1404],{"emptyLinePlaceholder":477},[179,11786,11787],{"class":181,"line":1381},[179,11788,11249],{},[179,11790,11791],{"class":181,"line":1401},[179,11792,11254],{},[179,11794,11795],{"class":181,"line":1407},[179,11796,11455],{},[179,11798,11799],{"class":181,"line":1418},[179,11800,1404],{"emptyLinePlaceholder":477},[179,11802,11803],{"class":181,"line":1435},[179,11804,11278],{},[179,11806,11807],{"class":181,"line":1440},[179,11808,11809],{},"        proxy_pass http://backend_servers;\n",[179,11811,11812],{"class":181,"line":1450},[179,11813,11628],{},[179,11815,11816],{"class":181,"line":1483},[179,11817,11633],{},[179,11819,11820],{"class":181,"line":1503},[179,11821,5320],{},[179,11823,11824],{"class":181,"line":1533},[179,11825,3814],{},[12,11827,11829],{"id":11828},"optimisation-des-performances","Optimisation des Performances",[53,11831,11833],{"id":11832},"activer-la-compression-gzip","Activer la Compression Gzip",[102,11835,11837],{"className":11140,"code":11836,"language":10922,"meta":111,"style":111},"http {\n    gzip on;\n    gzip_vary on;\n    gzip_min_length 1024;\n    gzip_proxied expired no-cache no-store private auth;\n    gzip_types text/plain text/css text/xml text/javascript \n               application/x-javascript application/xml application/javascript;\n    gzip_disable \"MSIE [1-6]\\.\";\n}\n",[109,11838,11839,11843,11848,11853,11858,11863,11868,11873,11878],{"__ignoreMap":111},[179,11840,11841],{"class":181,"line":182},[179,11842,11185],{},[179,11844,11845],{"class":181,"line":189},[179,11846,11847],{},"    gzip on;\n",[179,11849,11850],{"class":181,"line":448},[179,11851,11852],{},"    gzip_vary on;\n",[179,11854,11855],{"class":181,"line":775},[179,11856,11857],{},"    gzip_min_length 1024;\n",[179,11859,11860],{"class":181,"line":852},[179,11861,11862],{},"    gzip_proxied expired no-cache no-store private auth;\n",[179,11864,11865],{"class":181,"line":1351},[179,11866,11867],{},"    gzip_types text/plain text/css text/xml text/javascript \n",[179,11869,11870],{"class":181,"line":1363},[179,11871,11872],{},"               application/x-javascript application/xml application/javascript;\n",[179,11874,11875],{"class":181,"line":1381},[179,11876,11877],{},"    gzip_disable \"MSIE [1-6]\\.\";\n",[179,11879,11880],{"class":181,"line":1401},[179,11881,3814],{},[53,11883,11885],{"id":11884},"mise-en-cache-du-navigateur","Mise en Cache du Navigateur",[102,11887,11889],{"className":11140,"code":11888,"language":10922,"meta":111,"style":111},"location ~* \\.(jpg|jpeg|png|gif|ico|css|js|pdf|txt)$ {\n    expires 30d;\n    add_header Cache-Control \"public, immutable\";\n}\n",[109,11890,11891,11896,11901,11906],{"__ignoreMap":111},[179,11892,11893],{"class":181,"line":182},[179,11894,11895],{},"location ~* \\.(jpg|jpeg|png|gif|ico|css|js|pdf|txt)$ {\n",[179,11897,11898],{"class":181,"line":189},[179,11899,11900],{},"    expires 30d;\n",[179,11902,11903],{"class":181,"line":448},[179,11904,11905],{},"    add_header Cache-Control \"public, immutable\";\n",[179,11907,11908],{"class":181,"line":775},[179,11909,3814],{},[53,11911,11913],{"id":11912},"augmenter-les-limites","Augmenter les Limites",[102,11915,11917],{"className":11140,"code":11916,"language":10922,"meta":111,"style":111},"http {\n    client_max_body_size 100M;\n    client_body_buffer_size 128k;\n    client_header_buffer_size 1k;\n    large_client_header_buffers 4 16k;\n}\n",[109,11918,11919,11923,11928,11933,11938,11943],{"__ignoreMap":111},[179,11920,11921],{"class":181,"line":182},[179,11922,11185],{},[179,11924,11925],{"class":181,"line":189},[179,11926,11927],{},"    client_max_body_size 100M;\n",[179,11929,11930],{"class":181,"line":448},[179,11931,11932],{},"    client_body_buffer_size 128k;\n",[179,11934,11935],{"class":181,"line":775},[179,11936,11937],{},"    client_header_buffer_size 1k;\n",[179,11939,11940],{"class":181,"line":852},[179,11941,11942],{},"    large_client_header_buffers 4 16k;\n",[179,11944,11945],{"class":181,"line":1351},[179,11946,3814],{},[12,11948,11950],{"id":11949},"sécurité-nginx","Sécurité Nginx",[53,11952,11954],{"id":11953},"masquer-la-version-de-nginx","Masquer la Version de Nginx",[102,11956,11958],{"className":11140,"code":11957,"language":10922,"meta":111,"style":111},"http {\n    server_tokens off;\n}\n",[109,11959,11960,11964,11969],{"__ignoreMap":111},[179,11961,11962],{"class":181,"line":182},[179,11963,11185],{},[179,11965,11966],{"class":181,"line":189},[179,11967,11968],{},"    server_tokens off;\n",[179,11970,11971],{"class":181,"line":448},[179,11972,3814],{},[53,11974,11976],{"id":11975},"protéger-contre-les-attaques-ddos","Protéger contre les Attaques DDoS",[102,11978,11980],{"className":11140,"code":11979,"language":10922,"meta":111,"style":111},"http {\n    limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s;\n    \n    server {\n        location / {\n            limit_req zone=one burst=20 nodelay;\n        }\n    }\n}\n",[109,11981,11982,11986,11991,11996,12001,12006,12011,12016,12020],{"__ignoreMap":111},[179,11983,11984],{"class":181,"line":182},[179,11985,11185],{},[179,11987,11988],{"class":181,"line":189},[179,11989,11990],{},"    limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s;\n",[179,11992,11993],{"class":181,"line":448},[179,11994,11995],{},"    \n",[179,11997,11998],{"class":181,"line":775},[179,11999,12000],{},"    server {\n",[179,12002,12003],{"class":181,"line":852},[179,12004,12005],{},"        location / {\n",[179,12007,12008],{"class":181,"line":1351},[179,12009,12010],{},"            limit_req zone=one burst=20 nodelay;\n",[179,12012,12013],{"class":181,"line":1363},[179,12014,12015],{},"        }\n",[179,12017,12018],{"class":181,"line":1381},[179,12019,5320],{},[179,12021,12022],{"class":181,"line":1401},[179,12023,3814],{},[53,12025,12027],{"id":12026},"headers-de-sécurité","Headers de Sécurité",[102,12029,12031],{"className":11140,"code":12030,"language":10922,"meta":111,"style":111},"server {\n    add_header X-Frame-Options \"SAMEORIGIN\" always;\n    add_header X-Content-Type-Options \"nosniff\" always;\n    add_header X-XSS-Protection \"1; mode=block\" always;\n    add_header Referrer-Policy \"strict-origin-when-cross-origin\" always;\n}\n",[109,12032,12033,12037,12042,12047,12052,12057],{"__ignoreMap":111},[179,12034,12035],{"class":181,"line":182},[179,12036,11249],{},[179,12038,12039],{"class":181,"line":189},[179,12040,12041],{},"    add_header X-Frame-Options \"SAMEORIGIN\" always;\n",[179,12043,12044],{"class":181,"line":448},[179,12045,12046],{},"    add_header X-Content-Type-Options \"nosniff\" always;\n",[179,12048,12049],{"class":181,"line":775},[179,12050,12051],{},"    add_header X-XSS-Protection \"1; mode=block\" always;\n",[179,12053,12054],{"class":181,"line":852},[179,12055,12056],{},"    add_header Referrer-Policy \"strict-origin-when-cross-origin\" always;\n",[179,12058,12059],{"class":181,"line":1351},[179,12060,3814],{},[53,12062,12064],{"id":12063},"restreindre-laccès-à-certains-endpoints","Restreindre l'Accès à Certains Endpoints",[102,12066,12068],{"className":11140,"code":12067,"language":10922,"meta":111,"style":111},"location /admin {\n    allow 192.168.1.0/24;\n    deny all;\n}\n",[109,12069,12070,12075,12080,12085],{"__ignoreMap":111},[179,12071,12072],{"class":181,"line":182},[179,12073,12074],{},"location /admin {\n",[179,12076,12077],{"class":181,"line":189},[179,12078,12079],{},"    allow 192.168.1.0/24;\n",[179,12081,12082],{"class":181,"line":448},[179,12083,12084],{},"    deny all;\n",[179,12086,12087],{"class":181,"line":775},[179,12088,3814],{},[12,12090,12092],{"id":12091},"commandes-utiles","Commandes Utiles",[102,12094,12096],{"className":173,"code":12095,"language":175,"meta":111,"style":111},"# Tester la configuration\nsudo nginx -t\n\n# Recharger sans interruption\nsudo systemctl reload nginx\n\n# Redémarrer complètement\nsudo systemctl restart nginx\n\n# Vérifier le statut\nsudo systemctl status nginx\n\n# Voir les logs d'erreur\nsudo tail -f /var/log/nginx/error.log\n\n# Voir les logs d'accès\nsudo tail -f /var/log/nginx/access.log\n",[109,12097,12098,12102,12110,12114,12119,12129,12133,12138,12148,12152,12157,12167,12171,12176,12189,12193,12198],{"__ignoreMap":111},[179,12099,12100],{"class":181,"line":182},[179,12101,11348],{"class":185},[179,12103,12104,12106,12108],{"class":181,"line":189},[179,12105,567],{"class":192},[179,12107,11355],{"class":196},[179,12109,7718],{"class":224},[179,12111,12112],{"class":181,"line":448},[179,12113,1404],{"emptyLinePlaceholder":477},[179,12115,12116],{"class":181,"line":775},[179,12117,12118],{"class":185},"# Recharger sans interruption\n",[179,12120,12121,12123,12125,12127],{"class":181,"line":852},[179,12122,567],{"class":192},[179,12124,7611],{"class":196},[179,12126,7735],{"class":196},[179,12128,10908],{"class":196},[179,12130,12131],{"class":181,"line":1351},[179,12132,1404],{"emptyLinePlaceholder":477},[179,12134,12135],{"class":181,"line":1363},[179,12136,12137],{"class":185},"# Redémarrer complètement\n",[179,12139,12140,12142,12144,12146],{"class":181,"line":1381},[179,12141,567],{"class":192},[179,12143,7611],{"class":196},[179,12145,9156],{"class":196},[179,12147,10908],{"class":196},[179,12149,12150],{"class":181,"line":1401},[179,12151,1404],{"emptyLinePlaceholder":477},[179,12153,12154],{"class":181,"line":1407},[179,12155,12156],{"class":185},"# Vérifier le statut\n",[179,12158,12159,12161,12163,12165],{"class":181,"line":1418},[179,12160,567],{"class":192},[179,12162,7611],{"class":196},[179,12164,7568],{"class":196},[179,12166,10908],{"class":196},[179,12168,12169],{"class":181,"line":1435},[179,12170,1404],{"emptyLinePlaceholder":477},[179,12172,12173],{"class":181,"line":1440},[179,12174,12175],{"class":185},"# Voir les logs d'erreur\n",[179,12177,12178,12180,12183,12186],{"class":181,"line":1450},[179,12179,567],{"class":192},[179,12181,12182],{"class":196}," tail",[179,12184,12185],{"class":224}," -f",[179,12187,12188],{"class":196}," /var/log/nginx/error.log\n",[179,12190,12191],{"class":181,"line":1483},[179,12192,1404],{"emptyLinePlaceholder":477},[179,12194,12195],{"class":181,"line":1503},[179,12196,12197],{"class":185},"# Voir les logs d'accès\n",[179,12199,12200,12202,12204,12206],{"class":181,"line":1533},[179,12201,567],{"class":192},[179,12203,12182],{"class":196},[179,12205,12185],{"class":224},[179,12207,12208],{"class":196}," /var/log/nginx/access.log\n",[12,12210,12211],{"id":310},"Dépannage Courant",[53,12213,12215],{"id":12214},"problème-permission-denied","Problème : \"Permission Denied\"",[102,12217,12219],{"className":173,"code":12218,"language":175,"meta":111,"style":111},"# Vérifier les permissions des fichiers\nsudo chown -R www-data:www-data /var/www/monsite\nsudo chmod -R 755 /var/www/monsite\n",[109,12220,12221,12226,12242],{"__ignoreMap":111},[179,12222,12223],{"class":181,"line":182},[179,12224,12225],{"class":185},"# Vérifier les permissions des fichiers\n",[179,12227,12228,12230,12233,12236,12239],{"class":181,"line":189},[179,12229,567],{"class":192},[179,12231,12232],{"class":196}," chown",[179,12234,12235],{"class":224}," -R",[179,12237,12238],{"class":196}," www-data:www-data",[179,12240,12241],{"class":196}," /var/www/monsite\n",[179,12243,12244,12246,12249,12251,12254],{"class":181,"line":448},[179,12245,567],{"class":192},[179,12247,12248],{"class":196}," chmod",[179,12250,12235],{"class":224},[179,12252,12253],{"class":224}," 755",[179,12255,12241],{"class":196},[53,12257,12259],{"id":12258},"problème-502-bad-gateway","Problème : \"502 Bad Gateway\"",[17,12261,12262],{},"Vérifiez que votre application backend est en cours d'exécution et accessible sur le port configuré.",[53,12264,12266],{"id":12265},"problème-configuration-non-appliquée","Problème : Configuration Non Appliquée",[102,12268,12270],{"className":173,"code":12269,"language":175,"meta":111,"style":111},"# Toujours tester avant de recharger\nsudo nginx -t\n\n# Vérifier les liens symboliques\nls -la /etc/nginx/sites-enabled/\n",[109,12271,12272,12277,12285,12289,12294],{"__ignoreMap":111},[179,12273,12274],{"class":181,"line":182},[179,12275,12276],{"class":185},"# Toujours tester avant de recharger\n",[179,12278,12279,12281,12283],{"class":181,"line":189},[179,12280,567],{"class":192},[179,12282,11355],{"class":196},[179,12284,7718],{"class":224},[179,12286,12287],{"class":181,"line":448},[179,12288,1404],{"emptyLinePlaceholder":477},[179,12290,12291],{"class":181,"line":775},[179,12292,12293],{"class":185},"# Vérifier les liens symboliques\n",[179,12295,12296,12298,12301],{"class":181,"line":852},[179,12297,3062],{"class":192},[179,12299,12300],{"class":224}," -la",[179,12302,11339],{"class":196},[12,12304,406],{"id":405},[17,12306,12307],{},"Nginx est un outil puissant et polyvalent qui mérite sa place dans votre stack technique. Que vous l'utilisiez comme serveur web, reverse proxy ou load balancer, une bonne compréhension de sa configuration vous permettra d'optimiser les performances et la sécurité de vos applications.",[17,12309,12310],{},"N'hésitez pas à consulter la documentation officielle pour explorer des fonctionnalités plus avancées comme le caching, le streaming ou les modules dynamiques.",[10725,12312],{},[17,12314,12315],{},[21,12316,12317],{},"Ressources Utiles :",[33,12319,12320,12327,12334],{},[36,12321,12322],{},[730,12323,12326],{"href":12324,"rel":12325},"https://nginx.org/en/docs/",[734],"Documentation Officielle Nginx",[36,12328,12329],{},[730,12330,12333],{"href":12331,"rel":12332},"https://www.nginx.com/resources/library/",[734],"Nginx Library",[36,12335,12336],{},[730,12337,12340],{"href":12338,"rel":12339},"https://ssl-config.mozilla.org/",[734],"Mozilla SSL Configuration Generator",[438,12342,440],{},{"title":111,"searchDepth":189,"depth":189,"links":12344},[12345,12346,12351,12354,12358,12362,12366,12367,12372,12378,12379,12384],{"id":10828,"depth":189,"text":10829},{"id":10867,"depth":189,"text":10868,"children":12347},[12348,12349,12350],{"id":7527,"depth":448,"text":7528},{"id":10965,"depth":448,"text":10966},{"id":11045,"depth":448,"text":11046},{"id":7637,"depth":189,"text":11113,"children":12352},[12353],{"id":11129,"depth":448,"text":11130},{"id":11225,"depth":189,"text":11226,"children":12355},[12356,12357],{"id":11232,"depth":448,"text":11233},{"id":11313,"depth":448,"text":11314},{"id":11379,"depth":189,"text":11380,"children":12359},[12360,12361],{"id":11383,"depth":448,"text":11384},{"id":11435,"depth":448,"text":11436},{"id":11569,"depth":189,"text":11570,"children":12363},[12364,12365],{"id":11576,"depth":448,"text":11577},{"id":11659,"depth":448,"text":11660},{"id":11742,"depth":189,"text":11743},{"id":11828,"depth":189,"text":11829,"children":12368},[12369,12370,12371],{"id":11832,"depth":448,"text":11833},{"id":11884,"depth":448,"text":11885},{"id":11912,"depth":448,"text":11913},{"id":11949,"depth":189,"text":11950,"children":12373},[12374,12375,12376,12377],{"id":11953,"depth":448,"text":11954},{"id":11975,"depth":448,"text":11976},{"id":12026,"depth":448,"text":12027},{"id":12063,"depth":448,"text":12064},{"id":12091,"depth":189,"text":12092},{"id":310,"depth":189,"text":12211,"children":12380},[12381,12382,12383],{"id":12214,"depth":448,"text":12215},{"id":12258,"depth":448,"text":12259},{"id":12265,"depth":448,"text":12266},{"id":405,"depth":189,"text":406},"Découvrez comment installer et configurer Nginx. Guide complet sur les serveurs virtuels, la sécurité, le reverse proxy et l'optimisation des performances web.","/images/posts/2026/03/maitriser-nginx-installation-configuration-et-bonnes-pratiques.webp",{},"/posts/maitriser-nginx-installation-configuration-et-bonnes-pratiques",{"title":10814,"description":12385},"posts/maitriser-nginx-installation-configuration-et-bonnes-pratiques",[10922,12392,7455,12393,12394,2592,12395,6383],"serveur","configuration","devops","security","EW1CcVYqtVpoOv-elKZLMcYWEToWhBo6PK0RlBWVKzQ",{"id":12398,"title":12399,"author":12400,"body":12401,"date":12638,"description":12639,"extension":474,"image":12640,"meta":12641,"navigation":477,"path":12642,"readingTime":479,"seo":12643,"stem":12644,"tags":12645,"updatedAt":12638,"__hash__":12649},"posts/posts/comprendre-les-cles-privees-et-publiques-en-cryptographie.md","Comprendre les Clés Privées et Publiques en Cryptographie","Auteur",{"type":9,"value":12402,"toc":12626},[12403,12405,12408,12412,12415,12429,12432,12436,12440,12446,12449,12453,12459,12462,12466,12520,12523,12554,12558,12618,12620,12623],[12,12404,15],{"id":14},[17,12406,12407],{},"La cryptographie à clé publique, aussi appelée cryptographie asymétrique, est un pilier fondamental de la sécurité numérique moderne. Elle repose sur l'utilisation de deux clés distinctes mais mathématiquement liées : une clé privée et une clé publique.",[12,12409,12411],{"id":12410},"quest-ce-quune-paire-de-clés","Qu'est-ce qu'une Paire de Clés ?",[17,12413,12414],{},"Une paire de clés cryptographiques se compose de :",[33,12416,12417,12423],{},[36,12418,12419,12422],{},[21,12420,12421],{},"Clé publique"," : Peut être partagée librement avec n'importe qui",[36,12424,12425,12428],{},[21,12426,12427],{},"Clé privée"," : Doit rester secrète et connue uniquement par son propriétaire",[17,12430,12431],{},"Ces deux clés sont générées ensemble et sont mathématiquement liées, mais il est pratiquement impossible de déduire la clé privée à partir de la clé publique.",[12,12433,12435],{"id":12434},"comment-ça-fonctionne","Comment Ça Fonctionne ?",[53,12437,12439],{"id":12438},"chiffrement-avec-la-clé-publique","Chiffrement avec la Clé Publique",[102,12441,12444],{"className":12442,"code":12443,"language":107},[105],"Message clair → [Chiffrement avec clé publique] → Message chiffré → [Déchiffrement avec clé privée] → Message clair\n",[109,12445,12443],{"__ignoreMap":111},[17,12447,12448],{},"Seul le détenteur de la clé privée peut déchiffrer le message.",[53,12450,12452],{"id":12451},"signature-numérique-avec-la-clé-privée","Signature Numérique avec la Clé Privée",[102,12454,12457],{"className":12455,"code":12456,"language":107},[105],"Document → [Signature avec clé privée] → Signature → [Vérification avec clé publique] → Authentifié\n",[109,12458,12456],{"__ignoreMap":111},[17,12460,12461],{},"Cela permet de prouver l'authenticité et l'intégrité d'un document.",[12,12463,12465],{"id":12464},"cas-dusage-courants","Cas d'Usage Courants",[1120,12467,12468,12478],{},[1123,12469,12470],{},[1126,12471,12472,12475],{},[1129,12473,12474],{},"Application",[1129,12476,12477],{},"Utilisation",[1136,12479,12480,12488,12496,12504,12512],{},[1126,12481,12482,12485],{},[1141,12483,12484],{},"SSH",[1141,12486,12487],{},"Authentification sécurisée aux serveurs",[1126,12489,12490,12493],{},[1141,12491,12492],{},"SSL/TLS",[1141,12494,12495],{},"Sécurisation des communications web",[1126,12497,12498,12501],{},[1141,12499,12500],{},"Bitcoin/Crypto",[1141,12502,12503],{},"Gestion des portefeuilles numériques",[1126,12505,12506,12509],{},[1141,12507,12508],{},"PGP/GPG",[1141,12510,12511],{},"Chiffrement des emails",[1126,12513,12514,12517],{},[1141,12515,12516],{},"JWT",[1141,12518,12519],{},"Authentification API",[12,12521,12522],{"id":147},"Bonnes Pratiques de Sécurité",[79,12524,12525,12530,12536,12542,12548],{},[36,12526,12527],{},[21,12528,12529],{},"Jamais partager votre clé privée",[36,12531,12532,12535],{},[21,12533,12534],{},"Utiliser des phrases de passe fortes"," pour protéger vos clés",[36,12537,12538,12541],{},[21,12539,12540],{},"Sauvegarder vos clés"," dans un endroit sécurisé",[36,12543,12544,12547],{},[21,12545,12546],{},"Renouveler régulièrement"," vos paires de clés",[36,12549,12550,12553],{},[21,12551,12552],{},"Utiliser des algorithmes modernes"," (RSA 2048+, ECDSA, Ed25519)",[12,12555,12557],{"id":12556},"exemple-de-génération-de-clés-ssh","Exemple de Génération de Clés (SSH)",[102,12559,12561],{"className":173,"code":12560,"language":175,"meta":111,"style":111},"# Générer une nouvelle paire de clés\nssh-keygen -t ed25519 -C \"votre@email.com\"\n\n# Afficher la clé publique\ncat ~/.ssh/id_ed25519.pub\n\n# Ajouter la clé à un serveur\nssh-copy-id utilisateur@serveur.com\n",[109,12562,12563,12568,12585,12589,12594,12602,12606,12611],{"__ignoreMap":111},[179,12564,12565],{"class":181,"line":182},[179,12566,12567],{"class":185},"# Générer une nouvelle paire de clés\n",[179,12569,12570,12573,12576,12579,12582],{"class":181,"line":189},[179,12571,12572],{"class":192},"ssh-keygen",[179,12574,12575],{"class":224}," -t",[179,12577,12578],{"class":196}," ed25519",[179,12580,12581],{"class":224}," -C",[179,12583,12584],{"class":196}," \"votre@email.com\"\n",[179,12586,12587],{"class":181,"line":448},[179,12588,1404],{"emptyLinePlaceholder":477},[179,12590,12591],{"class":181,"line":775},[179,12592,12593],{"class":185},"# Afficher la clé publique\n",[179,12595,12596,12599],{"class":181,"line":852},[179,12597,12598],{"class":192},"cat",[179,12600,12601],{"class":196}," ~/.ssh/id_ed25519.pub\n",[179,12603,12604],{"class":181,"line":1351},[179,12605,1404],{"emptyLinePlaceholder":477},[179,12607,12608],{"class":181,"line":1363},[179,12609,12610],{"class":185},"# Ajouter la clé à un serveur\n",[179,12612,12613,12616],{"class":181,"line":1381},[179,12614,12615],{"class":192},"ssh-copy-id",[179,12617,1986],{"class":196},[12,12619,406],{"id":405},[17,12621,12622],{},"La compréhension des clés privées et publiques est essentielle pour naviguer dans l'univers de la sécurité numérique. Que ce soit pour protéger vos communications, authentifier vos accès ou sécuriser vos actifs numériques, ces concepts fondamentaux sont au cœur de la confiance numérique moderne.",[438,12624,12625],{},"html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":111,"searchDepth":189,"depth":189,"links":12627},[12628,12629,12630,12634,12635,12636,12637],{"id":14,"depth":189,"text":15},{"id":12410,"depth":189,"text":12411},{"id":12434,"depth":189,"text":12435,"children":12631},[12632,12633],{"id":12438,"depth":448,"text":12439},{"id":12451,"depth":448,"text":12452},{"id":12464,"depth":189,"text":12465},{"id":147,"depth":189,"text":12522},{"id":12556,"depth":189,"text":12557},{"id":405,"depth":189,"text":406},"2026-03-28","Clés privées et publiques : découvrez la cryptographie asymétrique, son fonctionnement et son rôle dans la sécurité numérique moderne.","/images/posts/2026/03/comprendre-les-cles-privees-et-publiques-en-cryptographie.webp",{},"/posts/comprendre-les-cles-privees-et-publiques-en-cryptographie",{"title":12399,"description":12639},"posts/comprendre-les-cles-privees-et-publiques-en-cryptographie",[12646,2885,12647,7459,12648],"cryptographie","clés","blockchain","b2bLUrW6DGTWJyAOJffH1eYM0lxqqVyclP6eJ3bn7CM",{"id":12651,"title":12652,"author":12400,"body":12653,"date":12638,"description":14491,"extension":474,"image":14492,"meta":14493,"navigation":477,"path":14494,"readingTime":479,"seo":14495,"stem":14496,"tags":14497,"updatedAt":12638,"__hash__":14502},"posts/posts/comprendre-websocket-communication-en-temps-reel-pour-le-web.md","Comprendre WebSocket : Communication en Temps Réel pour le Web",{"type":9,"value":12654,"toc":14462},[12655,12657,12660,12664,12668,12674,12685,12689,12715,12719,12723,12726,12819,12822,12883,12887,12894,12898,12902,13183,13187,13490,13492,13496,13663,13667,13786,13790,13932,13935,13939,14146,14150,14300,14304,14350,14354,14422,14424,14427,14431,14456,14459],[12,12656,15],{"id":14},[17,12658,12659],{},"WebSocket est un protocole de communication qui permet une connexion bidirectionnelle et persistante entre un client et un serveur. Contrairement au protocole HTTP traditionnel, WebSocket offre une communication en temps réel idéale pour les applications comme les chats, les jeux en ligne, ou les tableaux de bord en direct.",[12,12661,12663],{"id":12662},"pourquoi-utiliser-websocket","Pourquoi Utiliser WebSocket ?",[53,12665,12667],{"id":12666},"les-limites-du-http-traditionnel","Les Limites du HTTP Traditionnel",[17,12669,12670,12671,642],{},"Le protocole HTTP fonctionne sur un modèle ",[21,12672,12673],{},"requête-réponse",[33,12675,12676,12679,12682],{},[36,12677,12678],{},"Le client doit initier chaque demande",[36,12680,12681],{},"Le serveur ne peut pas envoyer de données spontanément",[36,12683,12684],{},"Nécessite des requêtes répétées (polling) pour les mises à jour",[53,12686,12688],{"id":12687},"les-avantages-de-websocket","Les Avantages de WebSocket",[33,12690,12691,12697,12703,12709],{},[36,12692,12693,12696],{},[21,12694,12695],{},"Communication bidirectionnelle"," : Client et serveur peuvent envoyer des données à tout moment",[36,12698,12699,12702],{},[21,12700,12701],{},"Connexion persistante"," : Une seule connexion pour toute la session",[36,12704,12705,12708],{},[21,12706,12707],{},"Faible latence"," : Pas de surcharge d'en-têtes HTTP à chaque échange",[36,12710,12711,12714],{},[21,12712,12713],{},"Efficacité"," : Idéal pour les applications en temps réel",[12,12716,12718],{"id":12717},"comment-fonctionne-websocket","Comment Fonctionne WebSocket ?",[53,12720,12722],{"id":12721},"le-handshake-initial","Le Handshake Initial",[17,12724,12725],{},"La connexion WebSocket commence par une requête HTTP spéciale :",[102,12727,12729],{"className":3719,"code":12728,"language":3715,"meta":111,"style":111},"// Requête du client\nGET /chat HTTP/1.1\nHost: example.com\nUpgrade: websocket\nConnection: Upgrade\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\nSec-WebSocket-Version: 13\n",[109,12730,12731,12736,12756,12764,12772,12780,12801],{"__ignoreMap":111},[179,12732,12733],{"class":181,"line":182},[179,12734,12735],{"class":185},"// Requête du client\n",[179,12737,12738,12741,12744,12747,12750,12753],{"class":181,"line":189},[179,12739,12740],{"class":224},"GET",[179,12742,12743],{"class":549}," /",[179,12745,12746],{"class":681},"chat ",[179,12748,12749],{"class":224},"HTTP",[179,12751,12752],{"class":549},"/",[179,12754,12755],{"class":224},"1.1\n",[179,12757,12758,12761],{"class":181,"line":448},[179,12759,12760],{"class":192},"Host",[179,12762,12763],{"class":681},": example.com\n",[179,12765,12766,12769],{"class":181,"line":775},[179,12767,12768],{"class":192},"Upgrade",[179,12770,12771],{"class":681},": websocket\n",[179,12773,12774,12777],{"class":181,"line":852},[179,12775,12776],{"class":192},"Connection",[179,12778,12779],{"class":681},": Upgrade\n",[179,12781,12782,12785,12787,12790,12792,12795,12798],{"class":181,"line":1351},[179,12783,12784],{"class":681},"Sec",[179,12786,5100],{"class":549},[179,12788,12789],{"class":681},"WebSocket",[179,12791,5100],{"class":549},[179,12793,12794],{"class":192},"Key",[179,12796,12797],{"class":681},": dGhlIHNhbXBsZSBub25jZQ",[179,12799,12800],{"class":549},"==\n",[179,12802,12803,12805,12807,12809,12811,12814,12816],{"class":181,"line":1363},[179,12804,12784],{"class":681},[179,12806,5100],{"class":549},[179,12808,12789],{"class":681},[179,12810,5100],{"class":549},[179,12812,12813],{"class":192},"Version",[179,12815,4251],{"class":681},[179,12817,12818],{"class":224},"13\n",[17,12820,12821],{},"Le serveur répond avec une confirmation :",[102,12823,12825],{"className":3719,"code":12824,"language":3715,"meta":111,"style":111},"// Réponse du serveur\nHTTP/1.1 101 Switching Protocols\nUpgrade: websocket\nConnection: Upgrade\nSec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\n",[109,12826,12827,12832,12847,12853,12859],{"__ignoreMap":111},[179,12828,12829],{"class":181,"line":182},[179,12830,12831],{"class":185},"// Réponse du serveur\n",[179,12833,12834,12836,12838,12841,12844],{"class":181,"line":189},[179,12835,12749],{"class":224},[179,12837,12752],{"class":549},[179,12839,12840],{"class":224},"1.1",[179,12842,12843],{"class":224}," 101",[179,12845,12846],{"class":681}," Switching Protocols\n",[179,12848,12849,12851],{"class":181,"line":448},[179,12850,12768],{"class":192},[179,12852,12771],{"class":681},[179,12854,12855,12857],{"class":181,"line":775},[179,12856,12776],{"class":192},[179,12858,12779],{"class":681},[179,12860,12861,12863,12865,12867,12869,12872,12875,12877,12880],{"class":181,"line":852},[179,12862,12784],{"class":681},[179,12864,5100],{"class":549},[179,12866,12789],{"class":681},[179,12868,5100],{"class":549},[179,12870,12871],{"class":192},"Accept",[179,12873,12874],{"class":681},": s3pPLMBiTxaQ9kYGzzhZRbK",[179,12876,5753],{"class":549},[179,12878,12879],{"class":681},"xOo",[179,12881,12882],{"class":549},"=\n",[53,12884,12886],{"id":12885},"une-fois-la-connexion-établie","Une Fois la Connexion Établie",[17,12888,12889,12890,12893],{},"Après le handshake, les deux parties peuvent envoyer des ",[21,12891,12892],{},"frames"," de données librement sans surcharge HTTP.",[12,12895,12897],{"id":12896},"utilisation-de-websocket-en-javascript","Utilisation de WebSocket en JavaScript",[53,12899,12901],{"id":12900},"côté-client-navigateur","Côté Client (Navigateur)",[102,12903,12905],{"className":3719,"code":12904,"language":3715,"meta":111,"style":111},"// Créer une connexion WebSocket\nconst socket = new WebSocket('ws://example.com:8080');\n\n// Événement : connexion ouverte\nsocket.onopen = function(event) {\n    console.log('Connexion établie');\n    socket.send('Bonjour serveur !');\n};\n\n// Événement : réception de message\nsocket.onmessage = function(event) {\n    console.log('Message reçu:', event.data);\n};\n\n// Événement : erreur\nsocket.onerror = function(event) {\n    console.error('Erreur WebSocket:', event);\n};\n\n// Événement : connexion fermée\nsocket.onclose = function(event) {\n    console.log('Connexion fermée');\n};\n\n// Envoyer des données\nsocket.send(JSON.stringify({ type: 'message', content: 'Hello' }));\n\n// Fermer la connexion\nsocket.close();\n",[109,12906,12907,12912,12933,12937,12942,12961,12975,12990,12995,12999,13004,13021,13035,13039,13043,13048,13065,13079,13083,13087,13092,13109,13122,13126,13130,13135,13165,13169,13174],{"__ignoreMap":111},[179,12908,12909],{"class":181,"line":182},[179,12910,12911],{"class":185},"// Créer une connexion WebSocket\n",[179,12913,12914,12916,12919,12921,12923,12926,12928,12931],{"class":181,"line":189},[179,12915,3823],{"class":549},[179,12917,12918],{"class":224}," socket",[179,12920,3752],{"class":549},[179,12922,10445],{"class":549},[179,12924,12925],{"class":192}," WebSocket",[179,12927,3761],{"class":681},[179,12929,12930],{"class":196},"'ws://example.com:8080'",[179,12932,3767],{"class":681},[179,12934,12935],{"class":181,"line":448},[179,12936,1404],{"emptyLinePlaceholder":477},[179,12938,12939],{"class":181,"line":775},[179,12940,12941],{"class":185},"// Événement : connexion ouverte\n",[179,12943,12944,12947,12950,12952,12954,12956,12959],{"class":181,"line":852},[179,12945,12946],{"class":681},"socket.",[179,12948,12949],{"class":192},"onopen",[179,12951,3752],{"class":549},[179,12953,3735],{"class":549},[179,12955,3761],{"class":681},[179,12957,12958],{"class":3802},"event",[179,12960,4489],{"class":681},[179,12962,12963,12966,12968,12970,12973],{"class":181,"line":1351},[179,12964,12965],{"class":681},"    console.",[179,12967,3858],{"class":192},[179,12969,3761],{"class":681},[179,12971,12972],{"class":196},"'Connexion établie'",[179,12974,3767],{"class":681},[179,12976,12977,12980,12983,12985,12988],{"class":181,"line":1363},[179,12978,12979],{"class":681},"    socket.",[179,12981,12982],{"class":192},"send",[179,12984,3761],{"class":681},[179,12986,12987],{"class":196},"'Bonjour serveur !'",[179,12989,3767],{"class":681},[179,12991,12992],{"class":181,"line":1381},[179,12993,12994],{"class":681},"};\n",[179,12996,12997],{"class":181,"line":1401},[179,12998,1404],{"emptyLinePlaceholder":477},[179,13000,13001],{"class":181,"line":1407},[179,13002,13003],{"class":185},"// Événement : réception de message\n",[179,13005,13006,13008,13011,13013,13015,13017,13019],{"class":181,"line":1418},[179,13007,12946],{"class":681},[179,13009,13010],{"class":192},"onmessage",[179,13012,3752],{"class":549},[179,13014,3735],{"class":549},[179,13016,3761],{"class":681},[179,13018,12958],{"class":3802},[179,13020,4489],{"class":681},[179,13022,13023,13025,13027,13029,13032],{"class":181,"line":1435},[179,13024,12965],{"class":681},[179,13026,3858],{"class":192},[179,13028,3761],{"class":681},[179,13030,13031],{"class":196},"'Message reçu:'",[179,13033,13034],{"class":681},", event.data);\n",[179,13036,13037],{"class":181,"line":1440},[179,13038,12994],{"class":681},[179,13040,13041],{"class":181,"line":1450},[179,13042,1404],{"emptyLinePlaceholder":477},[179,13044,13045],{"class":181,"line":1483},[179,13046,13047],{"class":185},"// Événement : erreur\n",[179,13049,13050,13052,13055,13057,13059,13061,13063],{"class":181,"line":1503},[179,13051,12946],{"class":681},[179,13053,13054],{"class":192},"onerror",[179,13056,3752],{"class":549},[179,13058,3735],{"class":549},[179,13060,3761],{"class":681},[179,13062,12958],{"class":3802},[179,13064,4489],{"class":681},[179,13066,13067,13069,13071,13073,13076],{"class":181,"line":1533},[179,13068,12965],{"class":681},[179,13070,10418],{"class":192},[179,13072,3761],{"class":681},[179,13074,13075],{"class":196},"'Erreur WebSocket:'",[179,13077,13078],{"class":681},", event);\n",[179,13080,13081],{"class":181,"line":1557},[179,13082,12994],{"class":681},[179,13084,13085],{"class":181,"line":1583},[179,13086,1404],{"emptyLinePlaceholder":477},[179,13088,13089],{"class":181,"line":1598},[179,13090,13091],{"class":185},"// Événement : connexion fermée\n",[179,13093,13094,13096,13099,13101,13103,13105,13107],{"class":181,"line":1603},[179,13095,12946],{"class":681},[179,13097,13098],{"class":192},"onclose",[179,13100,3752],{"class":549},[179,13102,3735],{"class":549},[179,13104,3761],{"class":681},[179,13106,12958],{"class":3802},[179,13108,4489],{"class":681},[179,13110,13111,13113,13115,13117,13120],{"class":181,"line":1615},[179,13112,12965],{"class":681},[179,13114,3858],{"class":192},[179,13116,3761],{"class":681},[179,13118,13119],{"class":196},"'Connexion fermée'",[179,13121,3767],{"class":681},[179,13123,13124],{"class":181,"line":1629},[179,13125,12994],{"class":681},[179,13127,13128],{"class":181,"line":1653},[179,13129,1404],{"emptyLinePlaceholder":477},[179,13131,13132],{"class":181,"line":1686},[179,13133,13134],{"class":185},"// Envoyer des données\n",[179,13136,13137,13139,13141,13143,13145,13147,13150,13153,13156,13159,13162],{"class":181,"line":1709},[179,13138,12946],{"class":681},[179,13140,12982],{"class":192},[179,13142,3761],{"class":681},[179,13144,4840],{"class":224},[179,13146,436],{"class":681},[179,13148,13149],{"class":192},"stringify",[179,13151,13152],{"class":681},"({ type: ",[179,13154,13155],{"class":196},"'message'",[179,13157,13158],{"class":681},", content: ",[179,13160,13161],{"class":196},"'Hello'",[179,13163,13164],{"class":681}," }));\n",[179,13166,13167],{"class":181,"line":1720},[179,13168,1404],{"emptyLinePlaceholder":477},[179,13170,13171],{"class":181,"line":1741},[179,13172,13173],{"class":185},"// Fermer la connexion\n",[179,13175,13176,13178,13181],{"class":181,"line":1746},[179,13177,12946],{"class":681},[179,13179,13180],{"class":192},"close",[179,13182,3786],{"class":681},[53,13184,13186],{"id":13185},"côté-serveur-nodejs-avec-ws","Côté Serveur (Node.js avec ws)",[102,13188,13190],{"className":3719,"code":13189,"language":3715,"meta":111,"style":111},"const WebSocket = require('ws');\nconst wss = new WebSocket.Server({ port: 8080 });\n\nwss.on('connection', function connection(ws) {\n    console.log('Nouveau client connecté');\n    \n    // Recevoir des messages\n    ws.on('message', function incoming(data) {\n        console.log('Message reçu:', data);\n        \n        // Envoyer une réponse\n        ws.send(JSON.stringify({\n            type: 'response',\n            message: 'Message reçu avec succès'\n        }));\n    });\n    \n    // Gérer la déconnexion\n    ws.on('close', function() {\n        console.log('Client déconnecté');\n    });\n    \n    // Envoyer un message de bienvenue\n    ws.send(JSON.stringify({\n        type: 'welcome',\n        message: 'Bienvenue sur le serveur WebSocket'\n    }));\n});\n\nconsole.log('Serveur WebSocket démarré sur le port 8080');\n",[109,13191,13192,13209,13234,13238,13263,13276,13280,13285,13309,13323,13328,13333,13350,13360,13368,13373,13378,13382,13387,13404,13417,13421,13425,13430,13446,13456,13464,13469,13473,13477],{"__ignoreMap":111},[179,13193,13194,13196,13198,13200,13202,13204,13207],{"class":181,"line":182},[179,13195,3823],{"class":549},[179,13197,12925],{"class":224},[179,13199,3752],{"class":549},[179,13201,6756],{"class":192},[179,13203,3761],{"class":681},[179,13205,13206],{"class":196},"'ws'",[179,13208,3767],{"class":681},[179,13210,13211,13213,13216,13218,13220,13223,13226,13229,13232],{"class":181,"line":189},[179,13212,3823],{"class":549},[179,13214,13215],{"class":224}," wss",[179,13217,3752],{"class":549},[179,13219,10445],{"class":549},[179,13221,13222],{"class":681}," WebSocket.",[179,13224,13225],{"class":192},"Server",[179,13227,13228],{"class":681},"({ port: ",[179,13230,13231],{"class":224},"8080",[179,13233,7058],{"class":681},[179,13235,13236],{"class":181,"line":448},[179,13237,1404],{"emptyLinePlaceholder":477},[179,13239,13240,13243,13245,13247,13250,13252,13254,13256,13258,13261],{"class":181,"line":775},[179,13241,13242],{"class":681},"wss.",[179,13244,10579],{"class":192},[179,13246,3761],{"class":681},[179,13248,13249],{"class":196},"'connection'",[179,13251,5355],{"class":681},[179,13253,3953],{"class":549},[179,13255,1669],{"class":192},[179,13257,3761],{"class":681},[179,13259,13260],{"class":3802},"ws",[179,13262,4489],{"class":681},[179,13264,13265,13267,13269,13271,13274],{"class":181,"line":852},[179,13266,12965],{"class":681},[179,13268,3858],{"class":192},[179,13270,3761],{"class":681},[179,13272,13273],{"class":196},"'Nouveau client connecté'",[179,13275,3767],{"class":681},[179,13277,13278],{"class":181,"line":1351},[179,13279,11995],{"class":681},[179,13281,13282],{"class":181,"line":1363},[179,13283,13284],{"class":185},"    // Recevoir des messages\n",[179,13286,13287,13290,13292,13294,13296,13298,13300,13303,13305,13307],{"class":181,"line":1381},[179,13288,13289],{"class":681},"    ws.",[179,13291,10579],{"class":192},[179,13293,3761],{"class":681},[179,13295,13155],{"class":196},[179,13297,5355],{"class":681},[179,13299,3953],{"class":549},[179,13301,13302],{"class":192}," incoming",[179,13304,3761],{"class":681},[179,13306,6779],{"class":3802},[179,13308,4489],{"class":681},[179,13310,13311,13314,13316,13318,13320],{"class":181,"line":1401},[179,13312,13313],{"class":681},"        console.",[179,13315,3858],{"class":192},[179,13317,3761],{"class":681},[179,13319,13031],{"class":196},[179,13321,13322],{"class":681},", data);\n",[179,13324,13325],{"class":181,"line":1407},[179,13326,13327],{"class":681},"        \n",[179,13329,13330],{"class":181,"line":1418},[179,13331,13332],{"class":185},"        // Envoyer une réponse\n",[179,13334,13335,13338,13340,13342,13344,13346,13348],{"class":181,"line":1435},[179,13336,13337],{"class":681},"        ws.",[179,13339,12982],{"class":192},[179,13341,3761],{"class":681},[179,13343,4840],{"class":224},[179,13345,436],{"class":681},[179,13347,13149],{"class":192},[179,13349,7260],{"class":681},[179,13351,13352,13355,13358],{"class":181,"line":1440},[179,13353,13354],{"class":681},"            type: ",[179,13356,13357],{"class":196},"'response'",[179,13359,4864],{"class":681},[179,13361,13362,13365],{"class":181,"line":1450},[179,13363,13364],{"class":681},"            message: ",[179,13366,13367],{"class":196},"'Message reçu avec succès'\n",[179,13369,13370],{"class":181,"line":1483},[179,13371,13372],{"class":681},"        }));\n",[179,13374,13375],{"class":181,"line":1503},[179,13376,13377],{"class":681},"    });\n",[179,13379,13380],{"class":181,"line":1533},[179,13381,11995],{"class":681},[179,13383,13384],{"class":181,"line":1557},[179,13385,13386],{"class":185},"    // Gérer la déconnexion\n",[179,13388,13389,13391,13393,13395,13398,13400,13402],{"class":181,"line":1583},[179,13390,13289],{"class":681},[179,13392,10579],{"class":192},[179,13394,3761],{"class":681},[179,13396,13397],{"class":196},"'close'",[179,13399,5355],{"class":681},[179,13401,3953],{"class":549},[179,13403,3741],{"class":681},[179,13405,13406,13408,13410,13412,13415],{"class":181,"line":1598},[179,13407,13313],{"class":681},[179,13409,3858],{"class":192},[179,13411,3761],{"class":681},[179,13413,13414],{"class":196},"'Client déconnecté'",[179,13416,3767],{"class":681},[179,13418,13419],{"class":181,"line":1603},[179,13420,13377],{"class":681},[179,13422,13423],{"class":181,"line":1615},[179,13424,11995],{"class":681},[179,13426,13427],{"class":181,"line":1629},[179,13428,13429],{"class":185},"    // Envoyer un message de bienvenue\n",[179,13431,13432,13434,13436,13438,13440,13442,13444],{"class":181,"line":1653},[179,13433,13289],{"class":681},[179,13435,12982],{"class":192},[179,13437,3761],{"class":681},[179,13439,4840],{"class":224},[179,13441,436],{"class":681},[179,13443,13149],{"class":192},[179,13445,7260],{"class":681},[179,13447,13448,13451,13454],{"class":181,"line":1686},[179,13449,13450],{"class":681},"        type: ",[179,13452,13453],{"class":196},"'welcome'",[179,13455,4864],{"class":681},[179,13457,13458,13461],{"class":181,"line":1709},[179,13459,13460],{"class":681},"        message: ",[179,13462,13463],{"class":196},"'Bienvenue sur le serveur WebSocket'\n",[179,13465,13466],{"class":181,"line":1720},[179,13467,13468],{"class":681},"    }));\n",[179,13470,13471],{"class":181,"line":1741},[179,13472,6732],{"class":681},[179,13474,13475],{"class":181,"line":1746},[179,13476,1404],{"emptyLinePlaceholder":477},[179,13478,13479,13481,13483,13485,13488],{"class":181,"line":1758},[179,13480,3855],{"class":681},[179,13482,3858],{"class":192},[179,13484,3761],{"class":681},[179,13486,13487],{"class":196},"'Serveur WebSocket démarré sur le port 8080'",[179,13489,3767],{"class":681},[12,13491,12465],{"id":12464},[53,13493,13495],{"id":13494},"_1-application-de-chat-en-temps-réel","1. Application de Chat en Temps Réel",[102,13497,13499],{"className":3719,"code":13498,"language":3715,"meta":111,"style":111},"// Envoi d'un message\nfunction sendMessage(userId, message) {\n    socket.send(JSON.stringify({\n        type: 'chat_message',\n        userId: userId,\n        content: message,\n        timestamp: new Date().toISOString()\n    }));\n}\n\n// Réception des messages\nsocket.onmessage = function(event) {\n    const data = JSON.parse(event.data);\n    if (data.type === 'chat_message') {\n        displayMessage(data.content, data.userId);\n    }\n};\n",[109,13500,13501,13506,13525,13541,13550,13555,13560,13578,13582,13586,13590,13595,13611,13631,13647,13655,13659],{"__ignoreMap":111},[179,13502,13503],{"class":181,"line":182},[179,13504,13505],{"class":185},"// Envoi d'un message\n",[179,13507,13508,13510,13513,13515,13518,13520,13523],{"class":181,"line":189},[179,13509,3953],{"class":549},[179,13511,13512],{"class":192}," sendMessage",[179,13514,3761],{"class":681},[179,13516,13517],{"class":3802},"userId",[179,13519,5355],{"class":681},[179,13521,13522],{"class":3802},"message",[179,13524,4489],{"class":681},[179,13526,13527,13529,13531,13533,13535,13537,13539],{"class":181,"line":448},[179,13528,12979],{"class":681},[179,13530,12982],{"class":192},[179,13532,3761],{"class":681},[179,13534,4840],{"class":224},[179,13536,436],{"class":681},[179,13538,13149],{"class":192},[179,13540,7260],{"class":681},[179,13542,13543,13545,13548],{"class":181,"line":775},[179,13544,13450],{"class":681},[179,13546,13547],{"class":196},"'chat_message'",[179,13549,4864],{"class":681},[179,13551,13552],{"class":181,"line":852},[179,13553,13554],{"class":681},"        userId: userId,\n",[179,13556,13557],{"class":181,"line":1351},[179,13558,13559],{"class":681},"        content: message,\n",[179,13561,13562,13565,13568,13571,13573,13576],{"class":181,"line":1363},[179,13563,13564],{"class":681},"        timestamp: ",[179,13566,13567],{"class":549},"new",[179,13569,13570],{"class":192}," Date",[179,13572,5559],{"class":681},[179,13574,13575],{"class":192},"toISOString",[179,13577,5565],{"class":681},[179,13579,13580],{"class":181,"line":1381},[179,13581,13468],{"class":681},[179,13583,13584],{"class":181,"line":1401},[179,13585,3814],{"class":681},[179,13587,13588],{"class":181,"line":1407},[179,13589,1404],{"emptyLinePlaceholder":477},[179,13591,13592],{"class":181,"line":1418},[179,13593,13594],{"class":185},"// Réception des messages\n",[179,13596,13597,13599,13601,13603,13605,13607,13609],{"class":181,"line":1435},[179,13598,12946],{"class":681},[179,13600,13010],{"class":192},[179,13602,3752],{"class":549},[179,13604,3735],{"class":549},[179,13606,3761],{"class":681},[179,13608,12958],{"class":3802},[179,13610,4489],{"class":681},[179,13612,13613,13616,13618,13620,13623,13625,13628],{"class":181,"line":1440},[179,13614,13615],{"class":549},"    const",[179,13617,1666],{"class":224},[179,13619,3752],{"class":549},[179,13621,13622],{"class":224}," JSON",[179,13624,436],{"class":681},[179,13626,13627],{"class":192},"parse",[179,13629,13630],{"class":681},"(event.data);\n",[179,13632,13633,13636,13639,13642,13645],{"class":181,"line":1450},[179,13634,13635],{"class":549},"    if",[179,13637,13638],{"class":681}," (data.type ",[179,13640,13641],{"class":549},"===",[179,13643,13644],{"class":196}," 'chat_message'",[179,13646,4489],{"class":681},[179,13648,13649,13652],{"class":181,"line":1483},[179,13650,13651],{"class":192},"        displayMessage",[179,13653,13654],{"class":681},"(data.content, data.userId);\n",[179,13656,13657],{"class":181,"line":1503},[179,13658,5320],{"class":681},[179,13660,13661],{"class":181,"line":1533},[179,13662,12994],{"class":681},[53,13664,13666],{"id":13665},"_2-tableau-de-bord-en-direct","2. Tableau de Bord en Direct",[102,13668,13670],{"className":3719,"code":13669,"language":3715,"meta":111,"style":111},"// Souscription aux mises à jour\nsocket.send(JSON.stringify({\n    type: 'subscribe',\n    channel: 'metrics'\n}));\n\n// Réception des données en temps réel\nsocket.onmessage = function(event) {\n    const data = JSON.parse(event.data);\n    if (data.type === 'metrics_update') {\n        updateDashboard(data.metrics);\n    }\n};\n",[109,13671,13672,13677,13693,13703,13711,13716,13720,13725,13741,13757,13770,13778,13782],{"__ignoreMap":111},[179,13673,13674],{"class":181,"line":182},[179,13675,13676],{"class":185},"// Souscription aux mises à jour\n",[179,13678,13679,13681,13683,13685,13687,13689,13691],{"class":181,"line":189},[179,13680,12946],{"class":681},[179,13682,12982],{"class":192},[179,13684,3761],{"class":681},[179,13686,4840],{"class":224},[179,13688,436],{"class":681},[179,13690,13149],{"class":192},[179,13692,7260],{"class":681},[179,13694,13695,13698,13701],{"class":181,"line":448},[179,13696,13697],{"class":681},"    type: ",[179,13699,13700],{"class":196},"'subscribe'",[179,13702,4864],{"class":681},[179,13704,13705,13708],{"class":181,"line":775},[179,13706,13707],{"class":681},"    channel: ",[179,13709,13710],{"class":196},"'metrics'\n",[179,13712,13713],{"class":181,"line":852},[179,13714,13715],{"class":681},"}));\n",[179,13717,13718],{"class":181,"line":1351},[179,13719,1404],{"emptyLinePlaceholder":477},[179,13721,13722],{"class":181,"line":1363},[179,13723,13724],{"class":185},"// Réception des données en temps réel\n",[179,13726,13727,13729,13731,13733,13735,13737,13739],{"class":181,"line":1381},[179,13728,12946],{"class":681},[179,13730,13010],{"class":192},[179,13732,3752],{"class":549},[179,13734,3735],{"class":549},[179,13736,3761],{"class":681},[179,13738,12958],{"class":3802},[179,13740,4489],{"class":681},[179,13742,13743,13745,13747,13749,13751,13753,13755],{"class":181,"line":1401},[179,13744,13615],{"class":549},[179,13746,1666],{"class":224},[179,13748,3752],{"class":549},[179,13750,13622],{"class":224},[179,13752,436],{"class":681},[179,13754,13627],{"class":192},[179,13756,13630],{"class":681},[179,13758,13759,13761,13763,13765,13768],{"class":181,"line":1407},[179,13760,13635],{"class":549},[179,13762,13638],{"class":681},[179,13764,13641],{"class":549},[179,13766,13767],{"class":196}," 'metrics_update'",[179,13769,4489],{"class":681},[179,13771,13772,13775],{"class":181,"line":1418},[179,13773,13774],{"class":192},"        updateDashboard",[179,13776,13777],{"class":681},"(data.metrics);\n",[179,13779,13780],{"class":181,"line":1435},[179,13781,5320],{"class":681},[179,13783,13784],{"class":181,"line":1440},[179,13785,12994],{"class":681},[53,13787,13789],{"id":13788},"_3-jeu-multijoueur","3. Jeu Multijoueur",[102,13791,13793],{"className":3719,"code":13792,"language":3715,"meta":111,"style":111},"// Envoyer la position du joueur\nfunction sendPlayerPosition(x, y) {\n    socket.send(JSON.stringify({\n        type: 'player_move',\n        playerId: playerId,\n        position: { x, y }\n    }));\n}\n\n// Recevoir les positions des autres joueurs\nsocket.onmessage = function(event) {\n    const data = JSON.parse(event.data);\n    if (data.type === 'player_move') {\n        updatePlayerPosition(data.playerId, data.position);\n    }\n};\n",[109,13794,13795,13800,13819,13835,13844,13849,13854,13858,13862,13866,13871,13887,13903,13916,13924,13928],{"__ignoreMap":111},[179,13796,13797],{"class":181,"line":182},[179,13798,13799],{"class":185},"// Envoyer la position du joueur\n",[179,13801,13802,13804,13807,13809,13812,13814,13817],{"class":181,"line":189},[179,13803,3953],{"class":549},[179,13805,13806],{"class":192}," sendPlayerPosition",[179,13808,3761],{"class":681},[179,13810,13811],{"class":3802},"x",[179,13813,5355],{"class":681},[179,13815,13816],{"class":3802},"y",[179,13818,4489],{"class":681},[179,13820,13821,13823,13825,13827,13829,13831,13833],{"class":181,"line":448},[179,13822,12979],{"class":681},[179,13824,12982],{"class":192},[179,13826,3761],{"class":681},[179,13828,4840],{"class":224},[179,13830,436],{"class":681},[179,13832,13149],{"class":192},[179,13834,7260],{"class":681},[179,13836,13837,13839,13842],{"class":181,"line":775},[179,13838,13450],{"class":681},[179,13840,13841],{"class":196},"'player_move'",[179,13843,4864],{"class":681},[179,13845,13846],{"class":181,"line":852},[179,13847,13848],{"class":681},"        playerId: playerId,\n",[179,13850,13851],{"class":181,"line":1351},[179,13852,13853],{"class":681},"        position: { x, y }\n",[179,13855,13856],{"class":181,"line":1363},[179,13857,13468],{"class":681},[179,13859,13860],{"class":181,"line":1381},[179,13861,3814],{"class":681},[179,13863,13864],{"class":181,"line":1401},[179,13865,1404],{"emptyLinePlaceholder":477},[179,13867,13868],{"class":181,"line":1407},[179,13869,13870],{"class":185},"// Recevoir les positions des autres joueurs\n",[179,13872,13873,13875,13877,13879,13881,13883,13885],{"class":181,"line":1418},[179,13874,12946],{"class":681},[179,13876,13010],{"class":192},[179,13878,3752],{"class":549},[179,13880,3735],{"class":549},[179,13882,3761],{"class":681},[179,13884,12958],{"class":3802},[179,13886,4489],{"class":681},[179,13888,13889,13891,13893,13895,13897,13899,13901],{"class":181,"line":1435},[179,13890,13615],{"class":549},[179,13892,1666],{"class":224},[179,13894,3752],{"class":549},[179,13896,13622],{"class":224},[179,13898,436],{"class":681},[179,13900,13627],{"class":192},[179,13902,13630],{"class":681},[179,13904,13905,13907,13909,13911,13914],{"class":181,"line":1440},[179,13906,13635],{"class":549},[179,13908,13638],{"class":681},[179,13910,13641],{"class":549},[179,13912,13913],{"class":196}," 'player_move'",[179,13915,4489],{"class":681},[179,13917,13918,13921],{"class":181,"line":1450},[179,13919,13920],{"class":192},"        updatePlayerPosition",[179,13922,13923],{"class":681},"(data.playerId, data.position);\n",[179,13925,13926],{"class":181,"line":1483},[179,13927,5320],{"class":681},[179,13929,13930],{"class":181,"line":1503},[179,13931,12994],{"class":681},[12,13933,13934],{"id":3608},"Bonnes Pratiques",[53,13936,13938],{"id":13937},"_1-gérer-la-reconnexion","1. Gérer la Reconnexion",[102,13940,13942],{"className":3719,"code":13941,"language":3715,"meta":111,"style":111},"let socket;\nlet reconnectAttempts = 0;\nconst MAX_RECONNECT_ATTEMPTS = 5;\n\nfunction connect() {\n    socket = new WebSocket('ws://example.com:8080');\n    \n    socket.onopen = function() {\n        console.log('Connecté');\n        reconnectAttempts = 0;\n    };\n    \n    socket.onclose = function() {\n        console.log('Déconnecté');\n        if (reconnectAttempts \u003C MAX_RECONNECT_ATTEMPTS) {\n            reconnectAttempts++;\n            setTimeout(connect, 1000 * reconnectAttempts);\n        }\n    };\n}\n\nconnect();\n",[109,13943,13944,13951,13965,13979,13983,13992,14009,14013,14025,14038,14049,14054,14058,14070,14083,14097,14107,14123,14127,14131,14135,14139],{"__ignoreMap":111},[179,13945,13946,13948],{"class":181,"line":182},[179,13947,10285],{"class":549},[179,13949,13950],{"class":681}," socket;\n",[179,13952,13953,13955,13958,13960,13963],{"class":181,"line":189},[179,13954,10285],{"class":549},[179,13956,13957],{"class":681}," reconnectAttempts ",[179,13959,685],{"class":549},[179,13961,13962],{"class":224}," 0",[179,13964,3850],{"class":681},[179,13966,13967,13969,13972,13974,13977],{"class":181,"line":448},[179,13968,3823],{"class":549},[179,13970,13971],{"class":224}," MAX_RECONNECT_ATTEMPTS",[179,13973,3752],{"class":549},[179,13975,13976],{"class":224}," 5",[179,13978,3850],{"class":681},[179,13980,13981],{"class":181,"line":775},[179,13982,1404],{"emptyLinePlaceholder":477},[179,13984,13985,13987,13990],{"class":181,"line":852},[179,13986,3953],{"class":549},[179,13988,13989],{"class":192}," connect",[179,13991,3741],{"class":681},[179,13993,13994,13997,13999,14001,14003,14005,14007],{"class":181,"line":1351},[179,13995,13996],{"class":681},"    socket ",[179,13998,685],{"class":549},[179,14000,10445],{"class":549},[179,14002,12925],{"class":192},[179,14004,3761],{"class":681},[179,14006,12930],{"class":196},[179,14008,3767],{"class":681},[179,14010,14011],{"class":181,"line":1363},[179,14012,11995],{"class":681},[179,14014,14015,14017,14019,14021,14023],{"class":181,"line":1381},[179,14016,12979],{"class":681},[179,14018,12949],{"class":192},[179,14020,3752],{"class":549},[179,14022,3735],{"class":549},[179,14024,3741],{"class":681},[179,14026,14027,14029,14031,14033,14036],{"class":181,"line":1401},[179,14028,13313],{"class":681},[179,14030,3858],{"class":192},[179,14032,3761],{"class":681},[179,14034,14035],{"class":196},"'Connecté'",[179,14037,3767],{"class":681},[179,14039,14040,14043,14045,14047],{"class":181,"line":1407},[179,14041,14042],{"class":681},"        reconnectAttempts ",[179,14044,685],{"class":549},[179,14046,13962],{"class":224},[179,14048,3850],{"class":681},[179,14050,14051],{"class":181,"line":1418},[179,14052,14053],{"class":681},"    };\n",[179,14055,14056],{"class":181,"line":1435},[179,14057,11995],{"class":681},[179,14059,14060,14062,14064,14066,14068],{"class":181,"line":1440},[179,14061,12979],{"class":681},[179,14063,13098],{"class":192},[179,14065,3752],{"class":549},[179,14067,3735],{"class":549},[179,14069,3741],{"class":681},[179,14071,14072,14074,14076,14078,14081],{"class":181,"line":1450},[179,14073,13313],{"class":681},[179,14075,3858],{"class":192},[179,14077,3761],{"class":681},[179,14079,14080],{"class":196},"'Déconnecté'",[179,14082,3767],{"class":681},[179,14084,14085,14088,14091,14093,14095],{"class":181,"line":1483},[179,14086,14087],{"class":549},"        if",[179,14089,14090],{"class":681}," (reconnectAttempts ",[179,14092,4050],{"class":549},[179,14094,13971],{"class":224},[179,14096,4489],{"class":681},[179,14098,14099,14102,14105],{"class":181,"line":1503},[179,14100,14101],{"class":681},"            reconnectAttempts",[179,14103,14104],{"class":549},"++",[179,14106,3850],{"class":681},[179,14108,14109,14112,14115,14118,14120],{"class":181,"line":1533},[179,14110,14111],{"class":192},"            setTimeout",[179,14113,14114],{"class":681},"(connect, ",[179,14116,14117],{"class":224},"1000",[179,14119,3580],{"class":549},[179,14121,14122],{"class":681}," reconnectAttempts);\n",[179,14124,14125],{"class":181,"line":1557},[179,14126,12015],{"class":681},[179,14128,14129],{"class":181,"line":1583},[179,14130,14053],{"class":681},[179,14132,14133],{"class":181,"line":1598},[179,14134,3814],{"class":681},[179,14136,14137],{"class":181,"line":1603},[179,14138,1404],{"emptyLinePlaceholder":477},[179,14140,14141,14144],{"class":181,"line":1615},[179,14142,14143],{"class":192},"connect",[179,14145,3786],{"class":681},[53,14147,14149],{"id":14148},"_2-valider-les-données","2. Valider les Données",[102,14151,14153],{"className":3719,"code":14152,"language":3715,"meta":111,"style":111},"socket.onmessage = function(event) {\n    try {\n        const data = JSON.parse(event.data);\n        \n        // Valider le type de message\n        if (!data.type || !allowedTypes.includes(data.type)) {\n            console.error('Type de message invalide');\n            return;\n        }\n        \n        // Traiter le message\n        handleMessage(data);\n    } catch (error) {\n        console.error('Erreur de parsing:', error);\n    }\n};\n",[109,14154,14155,14171,14178,14195,14199,14204,14229,14243,14249,14253,14257,14262,14270,14279,14292,14296],{"__ignoreMap":111},[179,14156,14157,14159,14161,14163,14165,14167,14169],{"class":181,"line":182},[179,14158,12946],{"class":681},[179,14160,13010],{"class":192},[179,14162,3752],{"class":549},[179,14164,3735],{"class":549},[179,14166,3761],{"class":681},[179,14168,12958],{"class":3802},[179,14170,4489],{"class":681},[179,14172,14173,14176],{"class":181,"line":189},[179,14174,14175],{"class":549},"    try",[179,14177,3892],{"class":681},[179,14179,14180,14183,14185,14187,14189,14191,14193],{"class":181,"line":448},[179,14181,14182],{"class":549},"        const",[179,14184,1666],{"class":224},[179,14186,3752],{"class":549},[179,14188,13622],{"class":224},[179,14190,436],{"class":681},[179,14192,13627],{"class":192},[179,14194,13630],{"class":681},[179,14196,14197],{"class":181,"line":775},[179,14198,13327],{"class":681},[179,14200,14201],{"class":181,"line":852},[179,14202,14203],{"class":185},"        // Valider le type de message\n",[179,14205,14206,14208,14210,14212,14215,14218,14221,14224,14226],{"class":181,"line":1351},[179,14207,14087],{"class":549},[179,14209,1468],{"class":681},[179,14211,6687],{"class":549},[179,14213,14214],{"class":681},"data.type ",[179,14216,14217],{"class":549},"||",[179,14219,14220],{"class":549}," !",[179,14222,14223],{"class":681},"allowedTypes.",[179,14225,4002],{"class":192},[179,14227,14228],{"class":681},"(data.type)) {\n",[179,14230,14231,14234,14236,14238,14241],{"class":181,"line":1363},[179,14232,14233],{"class":681},"            console.",[179,14235,10418],{"class":192},[179,14237,3761],{"class":681},[179,14239,14240],{"class":196},"'Type de message invalide'",[179,14242,3767],{"class":681},[179,14244,14245,14247],{"class":181,"line":1381},[179,14246,5300],{"class":549},[179,14248,3850],{"class":681},[179,14250,14251],{"class":181,"line":1401},[179,14252,12015],{"class":681},[179,14254,14255],{"class":181,"line":1407},[179,14256,13327],{"class":681},[179,14258,14259],{"class":181,"line":1418},[179,14260,14261],{"class":185},"        // Traiter le message\n",[179,14263,14264,14267],{"class":181,"line":1435},[179,14265,14266],{"class":192},"        handleMessage",[179,14268,14269],{"class":681},"(data);\n",[179,14271,14272,14275,14277],{"class":181,"line":1440},[179,14273,14274],{"class":681},"    } ",[179,14276,10359],{"class":549},[179,14278,10410],{"class":681},[179,14280,14281,14283,14285,14287,14290],{"class":181,"line":1450},[179,14282,13313],{"class":681},[179,14284,10418],{"class":192},[179,14286,3761],{"class":681},[179,14288,14289],{"class":196},"'Erreur de parsing:'",[179,14291,10456],{"class":681},[179,14293,14294],{"class":181,"line":1483},[179,14295,5320],{"class":681},[179,14297,14298],{"class":181,"line":1503},[179,14299,12994],{"class":681},[53,14301,14303],{"id":14302},"_3-utiliser-wss-pour-la-production","3. Utiliser wss:// pour la Production",[102,14305,14307],{"className":3719,"code":14306,"language":3715,"meta":111,"style":111},"// Développement\nconst wsUrl = 'ws://localhost:8080';\n\n// Production (toujours utiliser wss://)\nconst wsUrl = 'wss://example.com:8080';\n",[109,14308,14309,14314,14328,14332,14337],{"__ignoreMap":111},[179,14310,14311],{"class":181,"line":182},[179,14312,14313],{"class":185},"// Développement\n",[179,14315,14316,14318,14321,14323,14326],{"class":181,"line":189},[179,14317,3823],{"class":549},[179,14319,14320],{"class":224}," wsUrl",[179,14322,3752],{"class":549},[179,14324,14325],{"class":196}," 'ws://localhost:8080'",[179,14327,3850],{"class":681},[179,14329,14330],{"class":181,"line":448},[179,14331,1404],{"emptyLinePlaceholder":477},[179,14333,14334],{"class":181,"line":775},[179,14335,14336],{"class":185},"// Production (toujours utiliser wss://)\n",[179,14338,14339,14341,14343,14345,14348],{"class":181,"line":852},[179,14340,3823],{"class":549},[179,14342,14320],{"class":224},[179,14344,3752],{"class":549},[179,14346,14347],{"class":196}," 'wss://example.com:8080'",[179,14349,3850],{"class":681},[12,14351,14353],{"id":14352},"websocket-vs-autres-technologies","WebSocket vs Autres Technologies",[1120,14355,14356,14369],{},[1123,14357,14358],{},[1126,14359,14360,14363,14366],{},[1129,14361,14362],{},"Technologie",[1129,14364,14365],{},"Type",[1129,14367,14368],{},"Cas d'Usage",[1136,14370,14371,14383,14396,14409],{},[1126,14372,14373,14377,14380],{},[1141,14374,14375],{},[21,14376,12789],{},[1141,14378,14379],{},"Bidirectionnel persistant",[1141,14381,14382],{},"Chat, jeux, temps réel",[1126,14384,14385,14390,14393],{},[1141,14386,14387],{},[21,14388,14389],{},"HTTP Polling",[1141,14391,14392],{},"Requête-réponse",[1141,14394,14395],{},"Mises à jour peu fréquentes",[1126,14397,14398,14403,14406],{},[1141,14399,14400],{},[21,14401,14402],{},"Server-Sent Events",[1141,14404,14405],{},"Unidirectionnel (serveur → client)",[1141,14407,14408],{},"Notifications, flux",[1126,14410,14411,14416,14419],{},[1141,14412,14413],{},[21,14414,14415],{},"WebRTC",[1141,14417,14418],{},"Pair-à-pair",[1141,14420,14421],{},"Vidéo, audio, P2P",[12,14423,406],{"id":405},[17,14425,14426],{},"WebSocket est un outil puissant pour créer des applications web en temps réel. Sa capacité à maintenir une connexion persistante et bidirectionnelle en fait le choix idéal pour de nombreux cas d'usage modernes.",[53,14428,14430],{"id":14429},"points-clés-à-retenir","Points Clés à Retenir",[33,14432,14433,14440,14443,14446,14449],{},[36,14434,14435,14436,14439],{},"✅ WebSocket permet une communication ",[21,14437,14438],{},"bidirectionnelle"," en temps réel",[36,14441,14442],{},"✅ Une seule connexion persistante réduit la latence",[36,14444,14445],{},"✅ Supporté nativement par les navigateurs modernes",[36,14447,14448],{},"✅ Nécessite une gestion appropriée des erreurs et reconnections",[36,14450,14451,14452,14455],{},"✅ Toujours utiliser ",[21,14453,14454],{},"wss://"," en production pour la sécurité",[17,14457,14458],{},"Prêt à intégrer WebSocket dans votre prochaine application ? 🚀",[438,14460,14461],{},"html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}",{"title":111,"searchDepth":189,"depth":189,"links":14463},[14464,14465,14469,14473,14477,14482,14487,14488],{"id":14,"depth":189,"text":15},{"id":12662,"depth":189,"text":12663,"children":14466},[14467,14468],{"id":12666,"depth":448,"text":12667},{"id":12687,"depth":448,"text":12688},{"id":12717,"depth":189,"text":12718,"children":14470},[14471,14472],{"id":12721,"depth":448,"text":12722},{"id":12885,"depth":448,"text":12886},{"id":12896,"depth":189,"text":12897,"children":14474},[14475,14476],{"id":12900,"depth":448,"text":12901},{"id":13185,"depth":448,"text":13186},{"id":12464,"depth":189,"text":12465,"children":14478},[14479,14480,14481],{"id":13494,"depth":448,"text":13495},{"id":13665,"depth":448,"text":13666},{"id":13788,"depth":448,"text":13789},{"id":3608,"depth":189,"text":13934,"children":14483},[14484,14485,14486],{"id":13937,"depth":448,"text":13938},{"id":14148,"depth":448,"text":14149},{"id":14302,"depth":448,"text":14303},{"id":14352,"depth":189,"text":14353},{"id":405,"depth":189,"text":406,"children":14489},[14490],{"id":14429,"depth":448,"text":14430},"Découvrez WebSocket, le protocole de communication bidirectionnelle pour des applications web en temps réel. Guide complet avec exemples en JavaScript.","/images/posts/2026/03/comprendre-websocket-communication-en-temps-reel-pour-le-web.webp",{},"/posts/comprendre-websocket-communication-en-temps-reel-pour-le-web",{"title":12652,"description":14491},"posts/comprendre-websocket-communication-en-temps-reel-pour-le-web",[14498,3715,14499,14500,7455,14501],"websocket","realtime","communication","api","g55ZnnzCAGcSOSHCRtFlMxYljm8uefOe7EMMewQs8B4",{"id":14504,"title":14505,"author":14506,"body":14507,"date":12638,"description":14879,"extension":474,"image":14880,"meta":14881,"navigation":477,"path":14882,"readingTime":479,"seo":14883,"stem":14884,"tags":14885,"updatedAt":12638,"__hash__":14886},"posts/posts/guide-pratique-de-ssh.md","Guide pratique de SSH","admin",{"type":9,"value":14508,"toc":14857},[14509,14512,14516,14519,14523,14525,14549,14551,14566,14570,14573,14591,14595,14598,14610,14613,14632,14636,14640,14657,14661,14672,14676,14693,14697,14703,14709,14711,14749,14752,14784,14788,14792,14821,14824,14849,14851,14854],[4662,14510,14505],{"id":14511},"guide-pratique-de-ssh",[12,14513,14515],{"id":14514},"quest-ce-que-ssh","Qu'est-ce que SSH ?",[17,14517,14518],{},"SSH (Secure Shell) est un protocole de réseau qui permet de se connecter de manière sécurisée à un serveur à distance. Il remplace des protocoles moins sécurisés comme Telnet et rlogin.",[12,14520,14522],{"id":14521},"installation-de-ssh","Installation de SSH",[53,14524,7528],{"id":7527},[102,14526,14528],{"className":173,"code":14527,"language":175,"meta":111,"style":111},"sudo apt update\nsudo apt install openssh-server\n",[109,14529,14530,14538],{"__ignoreMap":111},[179,14531,14532,14534,14536],{"class":181,"line":182},[179,14533,567],{"class":192},[179,14535,621],{"class":196},[179,14537,624],{"class":196},[179,14539,14540,14542,14544,14546],{"class":181,"line":189},[179,14541,567],{"class":192},[179,14543,621],{"class":196},[179,14545,573],{"class":196},[179,14547,14548],{"class":196}," openssh-server\n",[53,14550,10966],{"id":10965},[102,14552,14554],{"className":173,"code":14553,"language":175,"meta":111,"style":111},"sudo yum install openssh-server\n",[109,14555,14556],{"__ignoreMap":111},[179,14557,14558,14560,14562,14564],{"class":181,"line":182},[179,14559,567],{"class":192},[179,14561,10983],{"class":196},[179,14563,573],{"class":196},[179,14565,14548],{"class":196},[53,14567,14569],{"id":14568},"sur-macos","Sur macOS",[17,14571,14572],{},"SSH est pré-installé. Pour activer le serveur :",[102,14574,14576],{"className":173,"code":14575,"language":175,"meta":111,"style":111},"sudo systemsetup -setremotelogin on\n",[109,14577,14578],{"__ignoreMap":111},[179,14579,14580,14582,14585,14588],{"class":181,"line":182},[179,14581,567],{"class":192},[179,14583,14584],{"class":196}," systemsetup",[179,14586,14587],{"class":224}," -setremotelogin",[179,14589,14590],{"class":196}," on\n",[12,14592,14594],{"id":14593},"connexion-à-un-serveur-distant","Connexion à un serveur distant",[17,14596,14597],{},"La commande de base :",[102,14599,14601],{"className":173,"code":14600,"language":175,"meta":111,"style":111},"ssh username@hostname\n",[109,14602,14603],{"__ignoreMap":111},[179,14604,14605,14607],{"class":181,"line":182},[179,14606,2519],{"class":192},[179,14608,14609],{"class":196}," username@hostname\n",[17,14611,14612],{},"Exemples :",[102,14614,14616],{"className":173,"code":14615,"language":175,"meta":111,"style":111},"ssh user@192.168.1.100\nssh admin@monserveur.com\n",[109,14617,14618,14625],{"__ignoreMap":111},[179,14619,14620,14622],{"class":181,"line":182},[179,14621,2519],{"class":192},[179,14623,14624],{"class":196}," user@192.168.1.100\n",[179,14626,14627,14629],{"class":181,"line":189},[179,14628,2519],{"class":192},[179,14630,14631],{"class":196}," admin@monserveur.com\n",[12,14633,14635],{"id":14634},"gestion-des-clés-ssh","Gestion des clés SSH",[53,14637,14639],{"id":14638},"générer-une-paire-de-clés","Générer une paire de clés",[102,14641,14643],{"className":173,"code":14642,"language":175,"meta":111,"style":111},"ssh-keygen -t ed25519 -C \"votre@email.com\"\n",[109,14644,14645],{"__ignoreMap":111},[179,14646,14647,14649,14651,14653,14655],{"class":181,"line":182},[179,14648,12572],{"class":192},[179,14650,12575],{"class":224},[179,14652,12578],{"class":196},[179,14654,12581],{"class":224},[179,14656,12584],{"class":196},[53,14658,14660],{"id":14659},"copier-la-clé-publique-sur-le-serveur","Copier la clé publique sur le serveur",[102,14662,14664],{"className":173,"code":14663,"language":175,"meta":111,"style":111},"ssh-copy-id username@hostname\n",[109,14665,14666],{"__ignoreMap":111},[179,14667,14668,14670],{"class":181,"line":182},[179,14669,12615],{"class":192},[179,14671,14609],{"class":196},[53,14673,14675],{"id":14674},"utiliser-une-clé-spécifique","Utiliser une clé spécifique",[102,14677,14679],{"className":173,"code":14678,"language":175,"meta":111,"style":111},"ssh -i ~/.ssh/ma_clé id@serveur\n",[109,14680,14681],{"__ignoreMap":111},[179,14682,14683,14685,14687,14690],{"class":181,"line":182},[179,14684,2519],{"class":192},[179,14686,3506],{"class":224},[179,14688,14689],{"class":196}," ~/.ssh/ma_clé",[179,14691,14692],{"class":196}," id@serveur\n",[12,14694,14696],{"id":14695},"configuration-du-client-ssh","Configuration du client SSH",[17,14698,14699,14700,642],{},"Le fichier de configuration est ",[109,14701,14702],{},"~/.ssh/config",[102,14704,14707],{"className":14705,"code":14706,"language":107},[105],"Host monserveur\n    HostName 192.168.1.100\n    User utilisateur\n    Port 22\n    IdentityFile ~/.ssh/ma_clé\n",[109,14708,14706],{"__ignoreMap":111},[12,14710,148],{"id":147},[79,14712,14713,14728,14738,14743],{},[36,14714,14715,14718,14719,642,14722],{},[21,14716,14717],{},"Désactiver le mot de passe root"," : Éditez ",[109,14720,14721],{},"/etc/ssh/sshd_config",[102,14723,14726],{"className":14724,"code":14725,"language":107},[105],"PermitRootLogin no\nPasswordAuthentication no\n",[109,14727,14725],{"__ignoreMap":111},[36,14729,14730,642,14732],{},[21,14731,2540],{},[102,14733,14736],{"className":14734,"code":14735,"language":107},[105],"Port 2222\n",[109,14737,14735],{"__ignoreMap":111},[36,14739,14740,14742],{},[21,14741,3622],{}," plutôt que les mots de passe",[36,14744,14745,14748],{},[21,14746,14747],{},"Installer fail2ban"," pour protéger contre les attaques par force brute",[12,14750,14751],{"id":12091},"Commandes utiles",[33,14753,14754,14760,14766,14772,14778],{},[36,14755,14756,14759],{},[109,14757,14758],{},"ssh -X user@host"," : Forwarding X11 (GUI)",[36,14761,14762,14765],{},[109,14763,14764],{},"ssh -L 8080:localhost:80 user@host"," : Tunnel local",[36,14767,14768,14771],{},[109,14769,14770],{},"ssh -R 8080:localhost:80 user@host"," : Tunnel distant",[36,14773,14774,14777],{},[109,14775,14776],{},"scp fichier.txt user@host:/chemin/"," : Copie sécurisée",[36,14779,14780,14783],{},[109,14781,14782],{},"rsync -avz local/ user@host:remote/"," : Synchronisation",[12,14785,14787],{"id":14786},"dépannage","Dépannage",[53,14789,14791],{"id":14790},"problèmes-de-connexion","Problèmes de connexion",[102,14793,14795],{"className":173,"code":14794,"language":175,"meta":111,"style":111},"ssh -v user@host    # mode verbeux\nssh -vv user@host   # mode très verbeux\n",[109,14796,14797,14809],{"__ignoreMap":111},[179,14798,14799,14801,14803,14806],{"class":181,"line":182},[179,14800,2519],{"class":192},[179,14802,3463],{"class":224},[179,14804,14805],{"class":196}," user@host",[179,14807,14808],{"class":185},"    # mode verbeux\n",[179,14810,14811,14813,14816,14818],{"class":181,"line":189},[179,14812,2519],{"class":192},[179,14814,14815],{"class":224}," -vv",[179,14817,14805],{"class":196},[179,14819,14820],{"class":185},"   # mode très verbeux\n",[53,14822,1008],{"id":14823},"problèmes-de-permissions",[102,14825,14827],{"className":173,"code":14826,"language":175,"meta":111,"style":111},"chmod 700 ~/.ssh\nchmod 600 ~/.ssh/authorized_keys\n",[109,14828,14829,14839],{"__ignoreMap":111},[179,14830,14831,14833,14836],{"class":181,"line":182},[179,14832,2400],{"class":192},[179,14834,14835],{"class":224}," 700",[179,14837,14838],{"class":196}," ~/.ssh\n",[179,14840,14841,14843,14846],{"class":181,"line":189},[179,14842,2400],{"class":192},[179,14844,14845],{"class":224}," 600",[179,14847,14848],{"class":196}," ~/.ssh/authorized_keys\n",[12,14850,406],{"id":405},[17,14852,14853],{},"SSH est un outil essentiel pour tout administrateur système. En combinant l'authentification par clé et une configuration sécurisée, vous pouvez gérer vos serveurs à distance en toute sécurité.",[438,14855,14856],{},"html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}",{"title":111,"searchDepth":189,"depth":189,"links":14858},[14859,14860,14865,14866,14871,14872,14873,14874,14878],{"id":14514,"depth":189,"text":14515},{"id":14521,"depth":189,"text":14522,"children":14861},[14862,14863,14864],{"id":7527,"depth":448,"text":7528},{"id":10965,"depth":448,"text":10966},{"id":14568,"depth":448,"text":14569},{"id":14593,"depth":189,"text":14594},{"id":14634,"depth":189,"text":14635,"children":14867},[14868,14869,14870],{"id":14638,"depth":448,"text":14639},{"id":14659,"depth":448,"text":14660},{"id":14674,"depth":448,"text":14675},{"id":14695,"depth":189,"text":14696},{"id":147,"depth":189,"text":148},{"id":12091,"depth":189,"text":14751},{"id":14786,"depth":189,"text":14787,"children":14875},[14876,14877],{"id":14790,"depth":448,"text":14791},{"id":14823,"depth":448,"text":1008},{"id":405,"depth":189,"text":406},"Apprenez à utiliser SSH de manière sécurisée pour accéder à distance à vos serveurs Linux","/images/posts/2026/03/guide-pratique-de-ssh.webp",{},"/posts/guide-pratique-de-ssh",{"title":14505,"description":14879},"posts/guide-pratique-de-ssh",[2519,487,2592,486],"wy-THJK53AxRDSKutUYi7QcrJQDp8H3Ey8JsuI3_MXI",{"id":14888,"title":14889,"author":12400,"body":14890,"date":15004,"description":15005,"extension":474,"image":15006,"meta":15007,"navigation":477,"path":15008,"readingTime":479,"seo":15009,"stem":15010,"tags":15011,"updatedAt":15004,"__hash__":15014},"posts/posts/analyse-de-donnees-methodes-et-bonnes-pratiques.md","Analyse de données : Méthodes et bonnes pratiques",{"type":9,"value":14891,"toc":14992},[14892,14895,14898,14902,14905,14909,14913,14916,14920,14923,14927,14930,14934,14937,14939,14971,14973,14987,14989],[4662,14893,14889],{"id":14894},"analyse-de-données-méthodes-et-bonnes-pratiques",[17,14896,14897],{},"L'analyse de données est devenue une compétence essentielle dans presque tous les secteurs d'activité. Cette guide vous présente les méthodes fondamentales et les bonnes pratiques pour mener des analyses de données efficaces.",[12,14899,14901],{"id":14900},"quest-ce-que-lanalyse-de-données","Qu'est-ce que l'analyse de données ?",[17,14903,14904],{},"L'analyse de données est le processus d'examen, de nettoyage, de transformation et d'interprétation des données pour en extraire des informations utiles à la prise de décision.",[12,14906,14908],{"id":14907},"principales-méthodes-danalyse","Principales méthodes d'analyse",[53,14910,14912],{"id":14911},"_1-analyse-descriptive","1. Analyse descriptive",[17,14914,14915],{},"L'analyse descriptive summarize les caractéristiques principales d'un jeu de données.",[53,14917,14919],{"id":14918},"_2-analyse-exploratoire","2. Analyse exploratoire",[17,14921,14922],{},"Cette méthode identifie les relations entre les variables et met en évidence des tendances.",[53,14924,14926],{"id":14925},"_3-analyse-inférentielle","3. Analyse inférentielle",[17,14928,14929],{},"À partir d'un échantillon, l'analyse inférentielle permet de tirer des conclusions sur une population plus large.",[53,14931,14933],{"id":14932},"_4-analyse-prédictive","4. Analyse prédictive",[17,14935,14936],{},"En utilisant des modèles statistiques et d'apprentissage automatique, cette méthode prédit des résultats futurs.",[12,14938,3609],{"id":3608},[79,14940,14941,14947,14953,14959,14965],{},[36,14942,14943,14946],{},[21,14944,14945],{},"Définir clairement les objectifs"," avant de commencer l'analyse",[36,14948,14949,14952],{},[21,14950,14951],{},"Nettoyer les données"," de manière rigoureuse",[36,14954,14955,14958],{},[21,14956,14957],{},"Visualiser les données"," pour mieux comprendre les patterns",[36,14960,14961,14964],{},[21,14962,14963],{},"Documenter chaque étape"," du processus d'analyse",[36,14966,14967,14970],{},[21,14968,14969],{},"Valider les résultats"," avec des tests statistiques appropriés",[12,14972,6319],{"id":6318},[33,14974,14975,14978,14981,14984],{},[36,14976,14977],{},"Python (pandas, matplotlib, seaborn)",[36,14979,14980],{},"R pour l'analyse statistique",[36,14982,14983],{},"Tableau Power BI pour la visualisation",[36,14985,14986],{},"SQL pour l'extraction des données",[12,14988,406],{"id":405},[17,14990,14991],{},"L'analyse de données est un processus itératif qui requiert à la fois des compétences techniques et une compréhension métier. Maîtriser ces méthodes permet de transformer des données brutes en informations actionnables.",{"title":111,"searchDepth":189,"depth":189,"links":14993},[14994,14995,15001,15002,15003],{"id":14900,"depth":189,"text":14901},{"id":14907,"depth":189,"text":14908,"children":14996},[14997,14998,14999,15000],{"id":14911,"depth":448,"text":14912},{"id":14918,"depth":448,"text":14919},{"id":14925,"depth":448,"text":14926},{"id":14932,"depth":448,"text":14933},{"id":3608,"depth":189,"text":3609},{"id":6318,"depth":189,"text":6319},{"id":405,"depth":189,"text":406},"2026-03-26","Découvrez les méthodes d'analyse de données essentielles et les bonnes pratiques pour transformer vos données en insights exploitables.","/images/posts/2026/03/analyse-de-donnees-methodes-et-bonnes-pratiques.webp",{},"/posts/analyse-de-donnees-methodes-et-bonnes-pratiques",{"title":14889,"description":15005},"posts/analyse-de-donnees-methodes-et-bonnes-pratiques",[6779,15012,15013],"analyse","methodes","843JJ3yRQx9eaKmsi6uacI9ZjNlSGeF88Z4byN6IdoA",{"id":15016,"title":15017,"author":12400,"body":15018,"date":15004,"description":16135,"extension":474,"image":16136,"meta":16137,"navigation":477,"path":16138,"readingTime":479,"seo":16139,"stem":16140,"tags":16141,"updatedAt":15004,"__hash__":16143},"posts/posts/docker-conteneuriser-vos-applications-simplement.md","Docker : conteneuriser vos applications simplement",{"type":9,"value":15019,"toc":16110},[15020,15024,15033,15036,15040,15044,15076,15079,15083,15092,15096,15114,15118,15150,15153,15157,15315,15319,15395,15399,15402,15464,15468,15513,15518,15524,15527,15530,15534,15679,15683,15793,15797,15800,15866,15870,15873,15988,15990,15993,16060,16064,16102,16104,16107],[12,15021,15023],{"id":15022},"quest-ce-que-docker","Qu'est-ce que Docker ?",[17,15025,15026,15028,15029,15032],{},[21,15027,9551],{}," est une plateforme open source qui permet de créer, déployer et exécuter des applications dans des ",[21,15030,15031],{},"conteneurs",". Un conteneur embarque tout ce dont une application a besoin pour fonctionner : code, dépendances, bibliothèques et configuration système.",[17,15034,15035],{},"Contrairement aux machines virtuelles, les conteneurs partagent le noyau du système hôte, ce qui les rend beaucoup plus légers et rapides à démarrer.",[12,15037,15039],{"id":15038},"installation","Installation",[53,15041,15043],{"id":15042},"linux-ubuntudebian","Linux (Ubuntu/Debian)",[102,15045,15047],{"className":173,"code":15046,"language":175,"meta":111,"style":111},"curl -fsSL https://get.docker.com | sh\nsudo usermod -aG docker $USER\n",[109,15048,15049,15062],{"__ignoreMap":111},[179,15050,15051,15053,15055,15057,15059],{"class":181,"line":182},[179,15052,540],{"class":192},[179,15054,543],{"class":224},[179,15056,8308],{"class":196},[179,15058,550],{"class":549},[179,15060,15061],{"class":192}," sh\n",[179,15063,15064,15066,15069,15071,15073],{"class":181,"line":189},[179,15065,567],{"class":192},[179,15067,15068],{"class":196}," usermod",[179,15070,8274],{"class":224},[179,15072,8348],{"class":196},[179,15074,15075],{"class":681}," $USER\n",[17,15077,15078],{},"Déconnectez-vous puis reconnectez-vous pour appliquer les permissions.",[53,15080,15082],{"id":15081},"macos-et-windows","macOS et Windows",[17,15084,15085,15086,15091],{},"Téléchargez et installez ",[730,15087,15090],{"href":15088,"rel":15089},"https://www.docker.com/products/docker-desktop/",[734],"Docker Desktop"," depuis le site officiel.",[53,15093,15095],{"id":15094},"vérifier-linstallation","Vérifier l'installation",[102,15097,15098],{"className":173,"code":8360,"language":175,"meta":111,"style":111},[109,15099,15100,15106],{"__ignoreMap":111},[179,15101,15102,15104],{"class":181,"line":182},[179,15103,8367],{"class":192},[179,15105,8370],{"class":224},[179,15107,15108,15110,15112],{"class":181,"line":189},[179,15109,8367],{"class":192},[179,15111,8377],{"class":196},[179,15113,8380],{"class":196},[12,15115,15117],{"id":15116},"concepts-clés","Concepts clés",[33,15119,15120,15126,15132,15138,15144],{},[36,15121,15122,15125],{},[21,15123,15124],{},"Image"," : un modèle en lecture seule contenant l'application et ses dépendances",[36,15127,15128,15131],{},[21,15129,15130],{},"Conteneur"," : une instance en cours d'exécution d'une image",[36,15133,15134,15137],{},[21,15135,15136],{},"Dockerfile"," : un fichier de recette pour construire une image",[36,15139,15140,15143],{},[21,15141,15142],{},"Registry"," : un dépôt d'images (ex : Docker Hub)",[36,15145,15146,15149],{},[21,15147,15148],{},"Volume"," : un espace de stockage persistant pour les données",[12,15151,15152],{"id":9081},"Commandes essentielles",[53,15154,15156],{"id":15155},"gestion-des-conteneurs","Gestion des conteneurs",[102,15158,15160],{"className":173,"code":15159,"language":175,"meta":111,"style":111},"# Lancer un conteneur\ndocker run -d --name mon-app -p 8080:80 nginx\n\n# Lister les conteneurs en cours\ndocker ps\n\n# Lister tous les conteneurs (y compris arrêtés)\ndocker ps -a\n\n# Arrêter un conteneur\ndocker stop mon-app\n\n# Redémarrer un conteneur\ndocker start mon-app\n\n# Supprimer un conteneur\ndocker rm mon-app\n\n# Voir les logs\ndocker logs mon-app\n\n# Exécuter une commande dans un conteneur\ndocker exec -it mon-app bash\n",[109,15161,15162,15167,15188,15192,15197,15203,15207,15212,15221,15225,15230,15240,15244,15249,15257,15261,15266,15275,15279,15283,15291,15295,15300],{"__ignoreMap":111},[179,15163,15164],{"class":181,"line":182},[179,15165,15166],{"class":185},"# Lancer un conteneur\n",[179,15168,15169,15171,15173,15175,15178,15181,15183,15186],{"class":181,"line":189},[179,15170,8367],{"class":192},[179,15172,8377],{"class":196},[179,15174,9050],{"class":224},[179,15176,15177],{"class":224}," --name",[179,15179,15180],{"class":196}," mon-app",[179,15182,3486],{"class":224},[179,15184,15185],{"class":196}," 8080:80",[179,15187,10908],{"class":196},[179,15189,15190],{"class":181,"line":448},[179,15191,1404],{"emptyLinePlaceholder":477},[179,15193,15194],{"class":181,"line":775},[179,15195,15196],{"class":185},"# Lister les conteneurs en cours\n",[179,15198,15199,15201],{"class":181,"line":852},[179,15200,8367],{"class":192},[179,15202,9199],{"class":196},[179,15204,15205],{"class":181,"line":1351},[179,15206,1404],{"emptyLinePlaceholder":477},[179,15208,15209],{"class":181,"line":1363},[179,15210,15211],{"class":185},"# Lister tous les conteneurs (y compris arrêtés)\n",[179,15213,15214,15216,15219],{"class":181,"line":1381},[179,15215,8367],{"class":192},[179,15217,15218],{"class":196}," ps",[179,15220,9480],{"class":224},[179,15222,15223],{"class":181,"line":1401},[179,15224,1404],{"emptyLinePlaceholder":477},[179,15226,15227],{"class":181,"line":1407},[179,15228,15229],{"class":185},"# Arrêter un conteneur\n",[179,15231,15232,15234,15237],{"class":181,"line":1418},[179,15233,8367],{"class":192},[179,15235,15236],{"class":196}," stop",[179,15238,15239],{"class":196}," mon-app\n",[179,15241,15242],{"class":181,"line":1435},[179,15243,1404],{"emptyLinePlaceholder":477},[179,15245,15246],{"class":181,"line":1440},[179,15247,15248],{"class":185},"# Redémarrer un conteneur\n",[179,15250,15251,15253,15255],{"class":181,"line":1450},[179,15252,8367],{"class":192},[179,15254,7614],{"class":196},[179,15256,15239],{"class":196},[179,15258,15259],{"class":181,"line":1483},[179,15260,1404],{"emptyLinePlaceholder":477},[179,15262,15263],{"class":181,"line":1503},[179,15264,15265],{"class":185},"# Supprimer un conteneur\n",[179,15267,15268,15270,15273],{"class":181,"line":1533},[179,15269,8367],{"class":192},[179,15271,15272],{"class":196}," rm",[179,15274,15239],{"class":196},[179,15276,15277],{"class":181,"line":1557},[179,15278,1404],{"emptyLinePlaceholder":477},[179,15280,15281],{"class":181,"line":1583},[179,15282,9130],{"class":185},[179,15284,15285,15287,15289],{"class":181,"line":1598},[179,15286,8367],{"class":192},[179,15288,9137],{"class":196},[179,15290,15239],{"class":196},[179,15292,15293],{"class":181,"line":1603},[179,15294,1404],{"emptyLinePlaceholder":477},[179,15296,15297],{"class":181,"line":1615},[179,15298,15299],{"class":185},"# Exécuter une commande dans un conteneur\n",[179,15301,15302,15304,15307,15310,15312],{"class":181,"line":1629},[179,15303,8367],{"class":192},[179,15305,15306],{"class":196}," exec",[179,15308,15309],{"class":224}," -it",[179,15311,15180],{"class":196},[179,15313,15314],{"class":196}," bash\n",[53,15316,15318],{"id":15317},"gestion-des-images","Gestion des images",[102,15320,15322],{"className":173,"code":15321,"language":175,"meta":111,"style":111},"# Télécharger une image\ndocker pull node:22-alpine\n\n# Lister les images locales\ndocker images\n\n# Supprimer une image\ndocker rmi node:22-alpine\n\n# Construire une image depuis un Dockerfile\ndocker build -t mon-image:latest .\n",[109,15323,15324,15329,15339,15343,15348,15354,15358,15363,15372,15376,15381],{"__ignoreMap":111},[179,15325,15326],{"class":181,"line":182},[179,15327,15328],{"class":185},"# Télécharger une image\n",[179,15330,15331,15333,15336],{"class":181,"line":189},[179,15332,8367],{"class":192},[179,15334,15335],{"class":196}," pull",[179,15337,15338],{"class":196}," node:22-alpine\n",[179,15340,15341],{"class":181,"line":448},[179,15342,1404],{"emptyLinePlaceholder":477},[179,15344,15345],{"class":181,"line":775},[179,15346,15347],{"class":185},"# Lister les images locales\n",[179,15349,15350,15352],{"class":181,"line":852},[179,15351,8367],{"class":192},[179,15353,1580],{"class":196},[179,15355,15356],{"class":181,"line":1351},[179,15357,1404],{"emptyLinePlaceholder":477},[179,15359,15360],{"class":181,"line":1363},[179,15361,15362],{"class":185},"# Supprimer une image\n",[179,15364,15365,15367,15370],{"class":181,"line":1381},[179,15366,8367],{"class":192},[179,15368,15369],{"class":196}," rmi",[179,15371,15338],{"class":196},[179,15373,15374],{"class":181,"line":1401},[179,15375,1404],{"emptyLinePlaceholder":477},[179,15377,15378],{"class":181,"line":1407},[179,15379,15380],{"class":185},"# Construire une image depuis un Dockerfile\n",[179,15382,15383,15385,15388,15390,15393],{"class":181,"line":1418},[179,15384,8367],{"class":192},[179,15386,15387],{"class":196}," build",[179,15389,12575],{"class":224},[179,15391,15392],{"class":196}," mon-image:latest",[179,15394,9861],{"class":196},[12,15396,15398],{"id":15397},"écrire-un-dockerfile","Écrire un Dockerfile",[17,15400,15401],{},"Voici un exemple de Dockerfile pour une application Node.js :",[102,15403,15407],{"className":15404,"code":15405,"language":15406,"meta":111,"style":111},"language-dockerfile shiki shiki-themes github-light github-dark","FROM node:22-alpine\n\nWORKDIR /app\n\nCOPY package*.json ./\nRUN npm ci --only=production\n\nCOPY . .\n\nEXPOSE 3000\n\nCMD [\"node\", \"server.js\"]\n","dockerfile",[109,15408,15409,15414,15418,15423,15427,15432,15437,15441,15446,15450,15455,15459],{"__ignoreMap":111},[179,15410,15411],{"class":181,"line":182},[179,15412,15413],{},"FROM node:22-alpine\n",[179,15415,15416],{"class":181,"line":189},[179,15417,1404],{"emptyLinePlaceholder":477},[179,15419,15420],{"class":181,"line":448},[179,15421,15422],{},"WORKDIR /app\n",[179,15424,15425],{"class":181,"line":775},[179,15426,1404],{"emptyLinePlaceholder":477},[179,15428,15429],{"class":181,"line":852},[179,15430,15431],{},"COPY package*.json ./\n",[179,15433,15434],{"class":181,"line":1351},[179,15435,15436],{},"RUN npm ci --only=production\n",[179,15438,15439],{"class":181,"line":1363},[179,15440,1404],{"emptyLinePlaceholder":477},[179,15442,15443],{"class":181,"line":1381},[179,15444,15445],{},"COPY . .\n",[179,15447,15448],{"class":181,"line":1401},[179,15449,1404],{"emptyLinePlaceholder":477},[179,15451,15452],{"class":181,"line":1407},[179,15453,15454],{},"EXPOSE 3000\n",[179,15456,15457],{"class":181,"line":1418},[179,15458,1404],{"emptyLinePlaceholder":477},[179,15460,15461],{"class":181,"line":1435},[179,15462,15463],{},"CMD [\"node\", \"server.js\"]\n",[53,15465,15467],{"id":15466},"bonnes-pratiques-pour-le-dockerfile","Bonnes pratiques pour le Dockerfile",[33,15469,15470,15479,15489,15498,15507],{},[36,15471,15472,1468,15475,15478],{},[21,15473,15474],{},"Utilisez des images légères",[109,15476,15477],{},"alpine",") pour réduire la taille",[36,15480,15481,15484,15485,15488],{},[21,15482,15483],{},"Exploitez le cache"," en copiant ",[109,15486,15487],{},"package.json"," avant le code source",[36,15490,15491,15497],{},[21,15492,15493,15494],{},"Utilisez ",[109,15495,15496],{},".dockerignore"," pour exclure les fichiers inutiles",[36,15499,15500,15503,15504],{},[21,15501,15502],{},"Minimisez le nombre de couches"," en combinant les commandes ",[109,15505,15506],{},"RUN",[36,15508,15509,15512],{},[21,15510,15511],{},"N'exécutez pas en root"," — créez un utilisateur dédié",[17,15514,15515,15516,642],{},"Exemple de ",[109,15517,15496],{},[102,15519,15522],{"className":15520,"code":15521,"language":107},[105],"node_modules\n.git\n.env\n*.md\n",[109,15523,15521],{"__ignoreMap":111},[12,15525,15526],{"id":8459},"Docker Compose",[17,15528,15529],{},"Docker Compose permet de définir et gérer des applications multi-conteneurs via un fichier YAML.",[53,15531,15533],{"id":15532},"exemple-application-web-base-de-données","Exemple : application web + base de données",[102,15535,15537],{"className":4955,"code":15536,"language":4951,"meta":111,"style":111},"services:\n  app:\n    build: .\n    ports:\n      - \"3000:3000\"\n    environment:\n      - DATABASE_URL=postgres://user:pass@db:5432/mydb\n    depends_on:\n      - db\n\n  db:\n    image: postgres:16-alpine\n    environment:\n      POSTGRES_USER: user\n      POSTGRES_PASSWORD: pass\n      POSTGRES_DB: mydb\n    volumes:\n      - db-data:/var/lib/postgresql/data\n\nvolumes:\n  db-data:\n",[109,15538,15539,15545,15551,15559,15565,15572,15578,15585,15591,15598,15602,15608,15617,15623,15632,15642,15651,15657,15663,15667,15673],{"__ignoreMap":111},[179,15540,15541,15543],{"class":181,"line":182},[179,15542,8509],{"class":4053},[179,15544,4966],{"class":681},[179,15546,15547,15549],{"class":181,"line":189},[179,15548,8516],{"class":4053},[179,15550,4966],{"class":681},[179,15552,15553,15555,15557],{"class":181,"line":448},[179,15554,8523],{"class":4053},[179,15556,4251],{"class":681},[179,15558,5091],{"class":224},[179,15560,15561,15563],{"class":181,"line":775},[179,15562,8641],{"class":4053},[179,15564,4966],{"class":681},[179,15566,15567,15569],{"class":181,"line":852},[179,15568,8560],{"class":681},[179,15570,15571],{"class":196},"\"3000:3000\"\n",[179,15573,15574,15576],{"class":181,"line":1351},[179,15575,8553],{"class":4053},[179,15577,4966],{"class":681},[179,15579,15580,15582],{"class":181,"line":1363},[179,15581,8560],{"class":681},[179,15583,15584],{"class":196},"DATABASE_URL=postgres://user:pass@db:5432/mydb\n",[179,15586,15587,15589],{"class":181,"line":1381},[179,15588,8682],{"class":4053},[179,15590,4966],{"class":681},[179,15592,15593,15595],{"class":181,"line":1401},[179,15594,8560],{"class":681},[179,15596,15597],{"class":196},"db\n",[179,15599,15600],{"class":181,"line":1407},[179,15601,1404],{"emptyLinePlaceholder":477},[179,15603,15604,15606],{"class":181,"line":1418},[179,15605,8712],{"class":4053},[179,15607,4966],{"class":681},[179,15609,15610,15612,15614],{"class":181,"line":1435},[179,15611,8614],{"class":4053},[179,15613,4251],{"class":681},[179,15615,15616],{"class":196},"postgres:16-alpine\n",[179,15618,15619,15621],{"class":181,"line":1440},[179,15620,8553],{"class":4053},[179,15622,4966],{"class":681},[179,15624,15625,15628,15630],{"class":181,"line":1450},[179,15626,15627],{"class":4053},"      POSTGRES_USER",[179,15629,4251],{"class":681},[179,15631,8898],{"class":196},[179,15633,15634,15637,15639],{"class":181,"line":1483},[179,15635,15636],{"class":4053},"      POSTGRES_PASSWORD",[179,15638,4251],{"class":681},[179,15640,15641],{"class":196},"pass\n",[179,15643,15644,15647,15649],{"class":181,"line":1503},[179,15645,15646],{"class":4053},"      POSTGRES_DB",[179,15648,4251],{"class":681},[179,15650,5025],{"class":196},[179,15652,15653,15655],{"class":181,"line":1533},[179,15654,8589],{"class":4053},[179,15656,4966],{"class":681},[179,15658,15659,15661],{"class":181,"line":1557},[179,15660,8560],{"class":681},[179,15662,8782],{"class":196},[179,15664,15665],{"class":181,"line":1583},[179,15666,1404],{"emptyLinePlaceholder":477},[179,15668,15669,15671],{"class":181,"line":1598},[179,15670,8839],{"class":4053},[179,15672,4966],{"class":681},[179,15674,15675,15677],{"class":181,"line":1603},[179,15676,8855],{"class":4053},[179,15678,4966],{"class":681},[53,15680,15682],{"id":15681},"commandes-docker-compose","Commandes Docker Compose",[102,15684,15686],{"className":173,"code":15685,"language":175,"meta":111,"style":111},"# Démarrer les services\ndocker compose up -d\n\n# Voir l'état des services\ndocker compose ps\n\n# Voir les logs\ndocker compose logs -f\n\n# Arrêter les services\ndocker compose down\n\n# Reconstruire les images\ndocker compose build\n\n# Arrêter et supprimer les volumes\ndocker compose down -v\n",[109,15687,15688,15693,15704,15708,15713,15721,15725,15729,15739,15743,15748,15756,15760,15765,15773,15777,15782],{"__ignoreMap":111},[179,15689,15690],{"class":181,"line":182},[179,15691,15692],{"class":185},"# Démarrer les services\n",[179,15694,15695,15697,15700,15702],{"class":181,"line":189},[179,15696,8367],{"class":192},[179,15698,15699],{"class":196}," compose",[179,15701,9102],{"class":196},[179,15703,9105],{"class":224},[179,15705,15706],{"class":181,"line":448},[179,15707,1404],{"emptyLinePlaceholder":477},[179,15709,15710],{"class":181,"line":775},[179,15711,15712],{"class":185},"# Voir l'état des services\n",[179,15714,15715,15717,15719],{"class":181,"line":852},[179,15716,8367],{"class":192},[179,15718,15699],{"class":196},[179,15720,9199],{"class":196},[179,15722,15723],{"class":181,"line":1351},[179,15724,1404],{"emptyLinePlaceholder":477},[179,15726,15727],{"class":181,"line":1363},[179,15728,9130],{"class":185},[179,15730,15731,15733,15735,15737],{"class":181,"line":1381},[179,15732,8367],{"class":192},[179,15734,15699],{"class":196},[179,15736,9137],{"class":196},[179,15738,9140],{"class":224},[179,15740,15741],{"class":181,"line":1401},[179,15742,1404],{"emptyLinePlaceholder":477},[179,15744,15745],{"class":181,"line":1407},[179,15746,15747],{"class":185},"# Arrêter les services\n",[179,15749,15750,15752,15754],{"class":181,"line":1418},[179,15751,8367],{"class":192},[179,15753,15699],{"class":196},[179,15755,9121],{"class":196},[179,15757,15758],{"class":181,"line":1435},[179,15759,1404],{"emptyLinePlaceholder":477},[179,15761,15762],{"class":181,"line":1440},[179,15763,15764],{"class":185},"# Reconstruire les images\n",[179,15766,15767,15769,15771],{"class":181,"line":1450},[179,15768,8367],{"class":192},[179,15770,15699],{"class":196},[179,15772,9397],{"class":196},[179,15774,15775],{"class":181,"line":1483},[179,15776,1404],{"emptyLinePlaceholder":477},[179,15778,15779],{"class":181,"line":1503},[179,15780,15781],{"class":185},"# Arrêter et supprimer les volumes\n",[179,15783,15784,15786,15788,15791],{"class":181,"line":1533},[179,15785,8367],{"class":192},[179,15787,15699],{"class":196},[179,15789,15790],{"class":196}," down",[179,15792,595],{"class":224},[12,15794,15796],{"id":15795},"build-multi-stage","Build multi-stage",[17,15798,15799],{},"Le build multi-stage permet de créer des images finales plus légères en séparant les étapes de build et d'exécution :",[102,15801,15803],{"className":15404,"code":15802,"language":15406,"meta":111,"style":111},"# Étape 1 : Build\nFROM node:22-alpine AS builder\nWORKDIR /app\nCOPY package*.json ./\nRUN npm ci\nCOPY . .\nRUN npm run build\n\n# Étape 2 : Production\nFROM nginx:alpine\nCOPY --from=builder /app/dist /usr/share/nginx/html\nEXPOSE 80\nCMD [\"nginx\", \"-g\", \"daemon off;\"]\n",[109,15804,15805,15810,15815,15819,15823,15828,15832,15837,15841,15846,15851,15856,15861],{"__ignoreMap":111},[179,15806,15807],{"class":181,"line":182},[179,15808,15809],{},"# Étape 1 : Build\n",[179,15811,15812],{"class":181,"line":189},[179,15813,15814],{},"FROM node:22-alpine AS builder\n",[179,15816,15817],{"class":181,"line":448},[179,15818,15422],{},[179,15820,15821],{"class":181,"line":775},[179,15822,15431],{},[179,15824,15825],{"class":181,"line":852},[179,15826,15827],{},"RUN npm ci\n",[179,15829,15830],{"class":181,"line":1351},[179,15831,15445],{},[179,15833,15834],{"class":181,"line":1363},[179,15835,15836],{},"RUN npm run build\n",[179,15838,15839],{"class":181,"line":1381},[179,15840,1404],{"emptyLinePlaceholder":477},[179,15842,15843],{"class":181,"line":1401},[179,15844,15845],{},"# Étape 2 : Production\n",[179,15847,15848],{"class":181,"line":1407},[179,15849,15850],{},"FROM nginx:alpine\n",[179,15852,15853],{"class":181,"line":1418},[179,15854,15855],{},"COPY --from=builder /app/dist /usr/share/nginx/html\n",[179,15857,15858],{"class":181,"line":1435},[179,15859,15860],{},"EXPOSE 80\n",[179,15862,15863],{"class":181,"line":1440},[179,15864,15865],{},"CMD [\"nginx\", \"-g\", \"daemon off;\"]\n",[12,15867,15869],{"id":15868},"volumes-et-persistance","Volumes et persistance",[17,15871,15872],{},"Les données dans un conteneur sont éphémères. Pour persister les données, utilisez des volumes :",[102,15874,15876],{"className":173,"code":15875,"language":175,"meta":111,"style":111},"# Créer un volume nommé\ndocker volume create mes-donnees\n\n# Monter un volume dans un conteneur\ndocker run -d -v mes-donnees:/data mon-image\n\n# Monter un dossier local (bind mount)\ndocker run -d -v $(pwd)/config:/app/config mon-image\n\n# Lister les volumes\ndocker volume ls\n\n# Supprimer les volumes inutilisés\ndocker volume prune\n",[109,15877,15878,15883,15896,15900,15905,15921,15925,15930,15953,15957,15962,15971,15975,15980],{"__ignoreMap":111},[179,15879,15880],{"class":181,"line":182},[179,15881,15882],{"class":185},"# Créer un volume nommé\n",[179,15884,15885,15887,15890,15893],{"class":181,"line":189},[179,15886,8367],{"class":192},[179,15888,15889],{"class":196}," volume",[179,15891,15892],{"class":196}," create",[179,15894,15895],{"class":196}," mes-donnees\n",[179,15897,15898],{"class":181,"line":448},[179,15899,1404],{"emptyLinePlaceholder":477},[179,15901,15902],{"class":181,"line":775},[179,15903,15904],{"class":185},"# Monter un volume dans un conteneur\n",[179,15906,15907,15909,15911,15913,15915,15918],{"class":181,"line":852},[179,15908,8367],{"class":192},[179,15910,8377],{"class":196},[179,15912,9050],{"class":224},[179,15914,3463],{"class":224},[179,15916,15917],{"class":196}," mes-donnees:/data",[179,15919,15920],{"class":196}," mon-image\n",[179,15922,15923],{"class":181,"line":1351},[179,15924,1404],{"emptyLinePlaceholder":477},[179,15926,15927],{"class":181,"line":1363},[179,15928,15929],{"class":185},"# Monter un dossier local (bind mount)\n",[179,15931,15932,15934,15936,15938,15940,15943,15946,15948,15951],{"class":181,"line":1381},[179,15933,8367],{"class":192},[179,15935,8377],{"class":196},[179,15937,9050],{"class":224},[179,15939,3463],{"class":224},[179,15941,15942],{"class":681}," $(",[179,15944,15945],{"class":224},"pwd",[179,15947,10236],{"class":681},[179,15949,15950],{"class":196},"/config:/app/config",[179,15952,15920],{"class":196},[179,15954,15955],{"class":181,"line":1401},[179,15956,1404],{"emptyLinePlaceholder":477},[179,15958,15959],{"class":181,"line":1407},[179,15960,15961],{"class":185},"# Lister les volumes\n",[179,15963,15964,15966,15968],{"class":181,"line":1418},[179,15965,8367],{"class":192},[179,15967,15889],{"class":196},[179,15969,15970],{"class":196}," ls\n",[179,15972,15973],{"class":181,"line":1435},[179,15974,1404],{"emptyLinePlaceholder":477},[179,15976,15977],{"class":181,"line":1440},[179,15978,15979],{"class":185},"# Supprimer les volumes inutilisés\n",[179,15981,15982,15984,15986],{"class":181,"line":1450},[179,15983,8367],{"class":192},[179,15985,15889],{"class":196},[179,15987,9441],{"class":196},[12,15989,2189],{"id":2884},[17,15991,15992],{},"Docker crée un réseau isolé pour chaque groupe de conteneurs :",[102,15994,15996],{"className":173,"code":15995,"language":175,"meta":111,"style":111},"# Créer un réseau\ndocker network create mon-reseau\n\n# Lancer un conteneur sur ce réseau\ndocker run -d --network mon-reseau --name api mon-api\n\n# Les conteneurs sur le même réseau se trouvent par nom\n# Ex : depuis un autre conteneur, \"api\" résout vers l'IP du conteneur api\n",[109,15997,15998,16003,16015,16019,16024,16046,16050,16055],{"__ignoreMap":111},[179,15999,16000],{"class":181,"line":182},[179,16001,16002],{"class":185},"# Créer un réseau\n",[179,16004,16005,16007,16010,16012],{"class":181,"line":189},[179,16006,8367],{"class":192},[179,16008,16009],{"class":196}," network",[179,16011,15892],{"class":196},[179,16013,16014],{"class":196}," mon-reseau\n",[179,16016,16017],{"class":181,"line":448},[179,16018,1404],{"emptyLinePlaceholder":477},[179,16020,16021],{"class":181,"line":775},[179,16022,16023],{"class":185},"# Lancer un conteneur sur ce réseau\n",[179,16025,16026,16028,16030,16032,16035,16038,16040,16043],{"class":181,"line":852},[179,16027,8367],{"class":192},[179,16029,8377],{"class":196},[179,16031,9050],{"class":224},[179,16033,16034],{"class":224}," --network",[179,16036,16037],{"class":196}," mon-reseau",[179,16039,15177],{"class":224},[179,16041,16042],{"class":196}," api",[179,16044,16045],{"class":196}," mon-api\n",[179,16047,16048],{"class":181,"line":1351},[179,16049,1404],{"emptyLinePlaceholder":477},[179,16051,16052],{"class":181,"line":1363},[179,16053,16054],{"class":185},"# Les conteneurs sur le même réseau se trouvent par nom\n",[179,16056,16057],{"class":181,"line":1381},[179,16058,16059],{"class":185},"# Ex : depuis un autre conteneur, \"api\" résout vers l'IP du conteneur api\n",[12,16061,16063],{"id":16062},"commandes-de-nettoyage","Commandes de nettoyage",[102,16065,16067],{"className":173,"code":16066,"language":175,"meta":111,"style":111},"# Supprimer les conteneurs arrêtés, images inutilisées, volumes orphelins\ndocker system prune -a\n\n# Voir l'espace disque utilisé par Docker\ndocker system df\n",[109,16068,16069,16074,16084,16088,16093],{"__ignoreMap":111},[179,16070,16071],{"class":181,"line":182},[179,16072,16073],{"class":185},"# Supprimer les conteneurs arrêtés, images inutilisées, volumes orphelins\n",[179,16075,16076,16078,16080,16082],{"class":181,"line":189},[179,16077,8367],{"class":192},[179,16079,1369],{"class":196},[179,16081,9477],{"class":196},[179,16083,9480],{"class":224},[179,16085,16086],{"class":181,"line":448},[179,16087,1404],{"emptyLinePlaceholder":477},[179,16089,16090],{"class":181,"line":775},[179,16091,16092],{"class":185},"# Voir l'espace disque utilisé par Docker\n",[179,16094,16095,16097,16099],{"class":181,"line":852},[179,16096,8367],{"class":192},[179,16098,1369],{"class":196},[179,16100,16101],{"class":196}," df\n",[12,16103,406],{"id":405},[17,16105,16106],{},"Docker simplifie le déploiement et garantit que votre application fonctionne de manière identique partout — en développement, en test et en production. Avec Docker Compose, vous pouvez orchestrer facilement des architectures multi-services. C'est un outil indispensable dans la boîte à outils de tout développeur moderne.",[438,16108,16109],{},"html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .s9eBZ, html code.shiki .s9eBZ{--shiki-default:#22863A;--shiki-dark:#85E89D}",{"title":111,"searchDepth":189,"depth":189,"links":16111},[16112,16113,16118,16119,16123,16126,16130,16131,16132,16133,16134],{"id":15022,"depth":189,"text":15023},{"id":15038,"depth":189,"text":15039,"children":16114},[16115,16116,16117],{"id":15042,"depth":448,"text":15043},{"id":15081,"depth":448,"text":15082},{"id":15094,"depth":448,"text":15095},{"id":15116,"depth":189,"text":15117},{"id":9081,"depth":189,"text":15152,"children":16120},[16121,16122],{"id":15155,"depth":448,"text":15156},{"id":15317,"depth":448,"text":15318},{"id":15397,"depth":189,"text":15398,"children":16124},[16125],{"id":15466,"depth":448,"text":15467},{"id":8459,"depth":189,"text":15526,"children":16127},[16128,16129],{"id":15532,"depth":448,"text":15533},{"id":15681,"depth":448,"text":15682},{"id":15795,"depth":189,"text":15796},{"id":15868,"depth":189,"text":15869},{"id":2884,"depth":189,"text":2189},{"id":16062,"depth":189,"text":16063},{"id":405,"depth":189,"text":406},"Apprenez à utiliser Docker pour conteneuriser vos applications : installation, commandes essentielles, Dockerfile, Docker Compose et bonnes pratiques.","/images/posts/2026/03/docker-conteneuriser-vos-applications-simplement.webp",{},"/posts/docker-conteneuriser-vos-applications-simplement",{"title":15017,"description":16135},"posts/docker-conteneuriser-vos-applications-simplement",[8367,12394,16142,10809],"conteneurisation","syzzIo6U5Kgbc2SXg852N7aA2a4V94Hb36mb2v8QxVk",{"id":16145,"title":16146,"author":12400,"body":16147,"date":15004,"description":17916,"extension":474,"image":17917,"meta":17918,"navigation":477,"path":17919,"readingTime":479,"seo":17920,"stem":17921,"tags":17922,"updatedAt":15004,"__hash__":17926},"posts/posts/fzf-le-fuzzy-finder-qui-booste-votre-productivite-en-terminal.md","fzf : le fuzzy finder qui booste votre productivité en terminal",{"type":9,"value":16148,"toc":17876},[16149,16153,16159,16162,16164,16166,16223,16227,16261,16264,16295,16297,16308,16312,16316,16322,16331,16338,16342,16401,16405,16408,16468,16472,16479,16523,16527,16547,16551,16620,16624,16628,16687,16691,16766,16770,16819,16823,16826,16830,16890,16894,16923,16927,16967,16971,16980,17045,17049,17053,17113,17117,17150,17154,17253,17257,17290,17294,17301,17439,17443,17487,17491,17494,17779,17783,17786,17868,17870,17873],[12,16150,16152],{"id":16151},"quest-ce-que-fzf","Qu'est-ce que fzf ?",[17,16154,16155,16158],{},[21,16156,16157],{},"fzf"," (fuzzy finder) est un outil en ligne de commande ultra-rapide qui permet de rechercher de manière interactive et floue dans n'importe quelle liste : fichiers, historique de commandes, processus, branches Git, et bien plus encore.",[17,16160,16161],{},"Écrit en Go, fzf est léger, sans dépendance et s'intègre parfaitement dans n'importe quel workflow terminal.",[12,16163,15039],{"id":15038},[53,16165,2188],{"id":2592},[102,16167,16169],{"className":173,"code":16168,"language":175,"meta":111,"style":111},"# Ubuntu/Debian\nsudo apt install fzf\n\n# Depuis Git (dernière version)\ngit clone --depth 1 https://github.com/junegunn/fzf.git ~/.fzf\n~/.fzf/install\n",[109,16170,16171,16176,16187,16191,16196,16215],{"__ignoreMap":111},[179,16172,16173],{"class":181,"line":182},[179,16174,16175],{"class":185},"# Ubuntu/Debian\n",[179,16177,16178,16180,16182,16184],{"class":181,"line":189},[179,16179,567],{"class":192},[179,16181,621],{"class":196},[179,16183,573],{"class":196},[179,16185,16186],{"class":196}," fzf\n",[179,16188,16189],{"class":181,"line":448},[179,16190,1404],{"emptyLinePlaceholder":477},[179,16192,16193],{"class":181,"line":775},[179,16194,16195],{"class":185},"# Depuis Git (dernière version)\n",[179,16197,16198,16200,16203,16206,16209,16212],{"class":181,"line":852},[179,16199,9840],{"class":192},[179,16201,16202],{"class":196}," clone",[179,16204,16205],{"class":224}," --depth",[179,16207,16208],{"class":224}," 1",[179,16210,16211],{"class":196}," https://github.com/junegunn/fzf.git",[179,16213,16214],{"class":196}," ~/.fzf\n",[179,16216,16217,16220],{"class":181,"line":1351},[179,16218,16219],{"class":549},"~",[179,16221,16222],{"class":681},"/.fzf/install\n",[53,16224,16226],{"id":16225},"macos","macOS",[102,16228,16230],{"className":173,"code":16229,"language":175,"meta":111,"style":111},"brew install fzf\n\n# Installer les raccourcis clavier et l'auto-complétion\n$(brew --prefix)/opt/fzf/install\n",[109,16231,16232,16240,16244,16249],{"__ignoreMap":111},[179,16233,16234,16236,16238],{"class":181,"line":182},[179,16235,11087],{"class":192},[179,16237,573],{"class":196},[179,16239,16186],{"class":196},[179,16241,16242],{"class":181,"line":189},[179,16243,1404],{"emptyLinePlaceholder":477},[179,16245,16246],{"class":181,"line":448},[179,16247,16248],{"class":185},"# Installer les raccourcis clavier et l'auto-complétion\n",[179,16250,16251,16253,16255,16258],{"class":181,"line":775},[179,16252,3541],{"class":681},[179,16254,11087],{"class":192},[179,16256,16257],{"class":224}," --prefix",[179,16259,16260],{"class":681},")/opt/fzf/install\n",[53,16262,16263],{"id":2593},"Windows",[102,16265,16269],{"className":16266,"code":16267,"language":16268,"meta":111,"style":111},"language-powershell shiki shiki-themes github-light github-dark","# Avec Scoop\nscoop install fzf\n\n# Avec Chocolatey\nchoco install fzf\n","powershell",[109,16270,16271,16276,16281,16285,16290],{"__ignoreMap":111},[179,16272,16273],{"class":181,"line":182},[179,16274,16275],{},"# Avec Scoop\n",[179,16277,16278],{"class":181,"line":189},[179,16279,16280],{},"scoop install fzf\n",[179,16282,16283],{"class":181,"line":448},[179,16284,1404],{"emptyLinePlaceholder":477},[179,16286,16287],{"class":181,"line":775},[179,16288,16289],{},"# Avec Chocolatey\n",[179,16291,16292],{"class":181,"line":852},[179,16293,16294],{},"choco install fzf\n",[53,16296,15095],{"id":15094},[102,16298,16300],{"className":173,"code":16299,"language":175,"meta":111,"style":111},"fzf --version\n",[109,16301,16302],{"__ignoreMap":111},[179,16303,16304,16306],{"class":181,"line":182},[179,16305,16157],{"class":192},[179,16307,8370],{"class":224},[12,16309,16311],{"id":16310},"utilisation-de-base","Utilisation de base",[53,16313,16315],{"id":16314},"recherche-interactive-de-fichiers","Recherche interactive de fichiers",[17,16317,16318,16319,16321],{},"Lancez simplement ",[109,16320,16157],{}," dans un répertoire :",[102,16323,16325],{"className":173,"code":16324,"language":175,"meta":111,"style":111},"fzf\n",[109,16326,16327],{"__ignoreMap":111},[179,16328,16329],{"class":181,"line":182},[179,16330,16324],{"class":192},[17,16332,16333,16334,16337],{},"Tapez quelques caractères — fzf filtre les résultats en temps réel grâce à la recherche floue. Appuyez sur ",[21,16335,16336],{},"Entrée"," pour sélectionner.",[53,16339,16341],{"id":16340},"ouvrir-un-fichier-trouvé","Ouvrir un fichier trouvé",[102,16343,16345],{"className":173,"code":16344,"language":175,"meta":111,"style":111},"# Ouvrir avec vim\nvim $(fzf)\n\n# Ouvrir avec code (VS Code)\ncode $(fzf)\n\n# Afficher le contenu\ncat $(fzf)\n",[109,16346,16347,16352,16363,16367,16372,16382,16386,16391],{"__ignoreMap":111},[179,16348,16349],{"class":181,"line":182},[179,16350,16351],{"class":185},"# Ouvrir avec vim\n",[179,16353,16354,16357,16359,16361],{"class":181,"line":189},[179,16355,16356],{"class":192},"vim",[179,16358,15942],{"class":681},[179,16360,16157],{"class":192},[179,16362,1480],{"class":681},[179,16364,16365],{"class":181,"line":448},[179,16366,1404],{"emptyLinePlaceholder":477},[179,16368,16369],{"class":181,"line":775},[179,16370,16371],{"class":185},"# Ouvrir avec code (VS Code)\n",[179,16373,16374,16376,16378,16380],{"class":181,"line":852},[179,16375,109],{"class":192},[179,16377,15942],{"class":681},[179,16379,16157],{"class":192},[179,16381,1480],{"class":681},[179,16383,16384],{"class":181,"line":1351},[179,16385,1404],{"emptyLinePlaceholder":477},[179,16387,16388],{"class":181,"line":1363},[179,16389,16390],{"class":185},"# Afficher le contenu\n",[179,16392,16393,16395,16397,16399],{"class":181,"line":1381},[179,16394,12598],{"class":192},[179,16396,15942],{"class":681},[179,16398,16157],{"class":192},[179,16400,1480],{"class":681},[53,16402,16404],{"id":16403},"recherche-dans-un-pipe","Recherche dans un pipe",[17,16406,16407],{},"fzf peut filtrer n'importe quelle entrée standard :",[102,16409,16411],{"className":173,"code":16410,"language":175,"meta":111,"style":111},"# Filtrer la liste des processus\nps aux | fzf\n\n# Filtrer les paquets installés\ndpkg -l | fzf\n\n# Filtrer les variables d'environnement\nenv | fzf\n",[109,16412,16413,16418,16430,16434,16439,16450,16454,16459],{"__ignoreMap":111},[179,16414,16415],{"class":181,"line":182},[179,16416,16417],{"class":185},"# Filtrer la liste des processus\n",[179,16419,16420,16423,16426,16428],{"class":181,"line":189},[179,16421,16422],{"class":192},"ps",[179,16424,16425],{"class":196}," aux",[179,16427,550],{"class":549},[179,16429,16186],{"class":192},[179,16431,16432],{"class":181,"line":448},[179,16433,1404],{"emptyLinePlaceholder":477},[179,16435,16436],{"class":181,"line":775},[179,16437,16438],{"class":185},"# Filtrer les paquets installés\n",[179,16440,16441,16444,16446,16448],{"class":181,"line":852},[179,16442,16443],{"class":192},"dpkg",[179,16445,3437],{"class":224},[179,16447,550],{"class":549},[179,16449,16186],{"class":192},[179,16451,16452],{"class":181,"line":1351},[179,16453,1404],{"emptyLinePlaceholder":477},[179,16455,16456],{"class":181,"line":1363},[179,16457,16458],{"class":185},"# Filtrer les variables d'environnement\n",[179,16460,16461,16464,16466],{"class":181,"line":1381},[179,16462,16463],{"class":192},"env",[179,16465,550],{"class":549},[179,16467,16186],{"class":192},[12,16469,16471],{"id":16470},"raccourcis-clavier-intégrés","Raccourcis clavier intégrés",[17,16473,16474,16475,16478],{},"Après l'installation complète (",[109,16476,16477],{},"fzf/install","), trois raccourcis sont disponibles dans votre shell :",[1120,16480,16481,16491],{},[1123,16482,16483],{},[1126,16484,16485,16488],{},[1129,16486,16487],{},"Raccourci",[1129,16489,16490],{},"Action",[1136,16492,16493,16503,16513],{},[1126,16494,16495,16500],{},[1141,16496,16497],{},[109,16498,16499],{},"Ctrl+T",[1141,16501,16502],{},"Rechercher un fichier et insérer son chemin",[1126,16504,16505,16510],{},[1141,16506,16507],{},[109,16508,16509],{},"Ctrl+R",[1141,16511,16512],{},"Rechercher dans l'historique des commandes",[1126,16514,16515,16520],{},[1141,16516,16517],{},[109,16518,16519],{},"Alt+C",[1141,16521,16522],{},"Rechercher un dossier et y accéder (cd)",[53,16524,16526],{"id":16525},"ctrlr-lhistorique-surpuissant","Ctrl+R : l'historique surpuissant",[102,16528,16530],{"className":173,"code":16529,"language":175,"meta":111,"style":111},"# Appuyez sur Ctrl+R puis tapez quelques mots\n# fzf filtre votre historique en temps réel\n# Beaucoup plus pratique que le Ctrl+R classique de bash\n",[109,16531,16532,16537,16542],{"__ignoreMap":111},[179,16533,16534],{"class":181,"line":182},[179,16535,16536],{"class":185},"# Appuyez sur Ctrl+R puis tapez quelques mots\n",[179,16538,16539],{"class":181,"line":189},[179,16540,16541],{"class":185},"# fzf filtre votre historique en temps réel\n",[179,16543,16544],{"class":181,"line":448},[179,16545,16546],{"class":185},"# Beaucoup plus pratique que le Ctrl+R classique de bash\n",[12,16548,16550],{"id":16549},"navigation-dans-fzf","Navigation dans fzf",[1120,16552,16553,16562],{},[1123,16554,16555],{},[1126,16556,16557,16560],{},[1129,16558,16559],{},"Touche",[1129,16561,16490],{},[1136,16563,16564,16578,16587,16600,16610],{},[1126,16565,16566,16575],{},[1141,16567,16568,16571,16572],{},[109,16569,16570],{},"↑"," / ",[109,16573,16574],{},"↓",[1141,16576,16577],{},"Naviguer dans les résultats",[1126,16579,16580,16584],{},[1141,16581,16582],{},[109,16583,16336],{},[1141,16585,16586],{},"Sélectionner",[1126,16588,16589,16597],{},[1141,16590,16591,16571,16594],{},[109,16592,16593],{},"Esc",[109,16595,16596],{},"Ctrl+C",[1141,16598,16599],{},"Annuler",[1126,16601,16602,16607],{},[1141,16603,16604],{},[109,16605,16606],{},"Tab",[1141,16608,16609],{},"Sélection multiple (mode multi)",[1126,16611,16612,16617],{},[1141,16613,16614],{},[109,16615,16616],{},"Shift+Tab",[1141,16618,16619],{},"Désélectionner",[12,16621,16623],{"id":16622},"options-et-personnalisation","Options et personnalisation",[53,16625,16627],{"id":16626},"prévisualisation-de-fichiers","Prévisualisation de fichiers",[102,16629,16631],{"className":173,"code":16630,"language":175,"meta":111,"style":111},"# Prévisualiser le contenu des fichiers avec cat\nfzf --preview 'cat {}'\n\n# Prévisualiser avec coloration syntaxique (bat)\nfzf --preview 'bat --color=always {}'\n\n# Limiter la hauteur de la prévisualisation\nfzf --preview 'bat --color=always {}' --preview-window=right:60%\n",[109,16632,16633,16638,16648,16652,16657,16666,16670,16675],{"__ignoreMap":111},[179,16634,16635],{"class":181,"line":182},[179,16636,16637],{"class":185},"# Prévisualiser le contenu des fichiers avec cat\n",[179,16639,16640,16642,16645],{"class":181,"line":189},[179,16641,16157],{"class":192},[179,16643,16644],{"class":224}," --preview",[179,16646,16647],{"class":196}," 'cat {}'\n",[179,16649,16650],{"class":181,"line":448},[179,16651,1404],{"emptyLinePlaceholder":477},[179,16653,16654],{"class":181,"line":775},[179,16655,16656],{"class":185},"# Prévisualiser avec coloration syntaxique (bat)\n",[179,16658,16659,16661,16663],{"class":181,"line":852},[179,16660,16157],{"class":192},[179,16662,16644],{"class":224},[179,16664,16665],{"class":196}," 'bat --color=always {}'\n",[179,16667,16668],{"class":181,"line":1351},[179,16669,1404],{"emptyLinePlaceholder":477},[179,16671,16672],{"class":181,"line":1363},[179,16673,16674],{"class":185},"# Limiter la hauteur de la prévisualisation\n",[179,16676,16677,16679,16681,16684],{"class":181,"line":1381},[179,16678,16157],{"class":192},[179,16680,16644],{"class":224},[179,16682,16683],{"class":196}," 'bat --color=always {}'",[179,16685,16686],{"class":224}," --preview-window=right:60%\n",[53,16688,16690],{"id":16689},"options-daffichage","Options d'affichage",[102,16692,16694],{"className":173,"code":16693,"language":175,"meta":111,"style":111},"# Afficher fzf en bas du terminal (inline)\nfzf --height 40%\n\n# Inverser l'ordre (résultats en haut)\nfzf --reverse\n\n# Avec bordure\nfzf --border\n\n# Combiner les options\nfzf --height 40% --reverse --border\n",[109,16695,16696,16701,16711,16715,16720,16727,16731,16736,16743,16747,16752],{"__ignoreMap":111},[179,16697,16698],{"class":181,"line":182},[179,16699,16700],{"class":185},"# Afficher fzf en bas du terminal (inline)\n",[179,16702,16703,16705,16708],{"class":181,"line":189},[179,16704,16157],{"class":192},[179,16706,16707],{"class":224}," --height",[179,16709,16710],{"class":196}," 40%\n",[179,16712,16713],{"class":181,"line":448},[179,16714,1404],{"emptyLinePlaceholder":477},[179,16716,16717],{"class":181,"line":775},[179,16718,16719],{"class":185},"# Inverser l'ordre (résultats en haut)\n",[179,16721,16722,16724],{"class":181,"line":852},[179,16723,16157],{"class":192},[179,16725,16726],{"class":224}," --reverse\n",[179,16728,16729],{"class":181,"line":1351},[179,16730,1404],{"emptyLinePlaceholder":477},[179,16732,16733],{"class":181,"line":1363},[179,16734,16735],{"class":185},"# Avec bordure\n",[179,16737,16738,16740],{"class":181,"line":1381},[179,16739,16157],{"class":192},[179,16741,16742],{"class":224}," --border\n",[179,16744,16745],{"class":181,"line":1401},[179,16746,1404],{"emptyLinePlaceholder":477},[179,16748,16749],{"class":181,"line":1407},[179,16750,16751],{"class":185},"# Combiner les options\n",[179,16753,16754,16756,16758,16761,16764],{"class":181,"line":1418},[179,16755,16157],{"class":192},[179,16757,16707],{"class":224},[179,16759,16760],{"class":196}," 40%",[179,16762,16763],{"class":224}," --reverse",[179,16765,16742],{"class":224},[53,16767,16769],{"id":16768},"recherche-exacte","Recherche exacte",[102,16771,16773],{"className":173,"code":16772,"language":175,"meta":111,"style":111},"# Par défaut, la recherche est floue\n# Préfixer avec ' pour une correspondance exacte\n# Exemple : taper 'config trouvera uniquement les lignes contenant \"config\"\n\n# Syntaxe de recherche avancée\n# ^mot    → commence par \"mot\"\n# mot$    → finit par \"mot\"\n# 'mot    → correspondance exacte\n# !mot    → exclure \"mot\"\n",[109,16774,16775,16780,16785,16790,16794,16799,16804,16809,16814],{"__ignoreMap":111},[179,16776,16777],{"class":181,"line":182},[179,16778,16779],{"class":185},"# Par défaut, la recherche est floue\n",[179,16781,16782],{"class":181,"line":189},[179,16783,16784],{"class":185},"# Préfixer avec ' pour une correspondance exacte\n",[179,16786,16787],{"class":181,"line":448},[179,16788,16789],{"class":185},"# Exemple : taper 'config trouvera uniquement les lignes contenant \"config\"\n",[179,16791,16792],{"class":181,"line":775},[179,16793,1404],{"emptyLinePlaceholder":477},[179,16795,16796],{"class":181,"line":852},[179,16797,16798],{"class":185},"# Syntaxe de recherche avancée\n",[179,16800,16801],{"class":181,"line":1351},[179,16802,16803],{"class":185},"# ^mot    → commence par \"mot\"\n",[179,16805,16806],{"class":181,"line":1363},[179,16807,16808],{"class":185},"# mot$    → finit par \"mot\"\n",[179,16810,16811],{"class":181,"line":1381},[179,16812,16813],{"class":185},"# 'mot    → correspondance exacte\n",[179,16815,16816],{"class":181,"line":1401},[179,16817,16818],{"class":185},"# !mot    → exclure \"mot\"\n",[12,16820,16822],{"id":16821},"intégration-avec-git","Intégration avec Git",[17,16824,16825],{},"fzf est particulièrement puissant combiné avec Git :",[53,16827,16829],{"id":16828},"changer-de-branche","Changer de branche",[102,16831,16833],{"className":173,"code":16832,"language":175,"meta":111,"style":111},"# Sélectionner une branche interactivement\ngit checkout $(git branch | fzf)\n\n# Inclure les branches distantes\ngit checkout $(git branch -a | fzf)\n",[109,16834,16835,16840,16860,16864,16869],{"__ignoreMap":111},[179,16836,16837],{"class":181,"line":182},[179,16838,16839],{"class":185},"# Sélectionner une branche interactivement\n",[179,16841,16842,16844,16847,16849,16851,16853,16855,16858],{"class":181,"line":189},[179,16843,9840],{"class":192},[179,16845,16846],{"class":196}," checkout",[179,16848,15942],{"class":681},[179,16850,9840],{"class":192},[179,16852,9889],{"class":196},[179,16854,550],{"class":549},[179,16856,16857],{"class":192}," fzf",[179,16859,1480],{"class":681},[179,16861,16862],{"class":181,"line":448},[179,16863,1404],{"emptyLinePlaceholder":477},[179,16865,16866],{"class":181,"line":775},[179,16867,16868],{"class":185},"# Inclure les branches distantes\n",[179,16870,16871,16873,16875,16877,16879,16881,16884,16886,16888],{"class":181,"line":852},[179,16872,9840],{"class":192},[179,16874,16846],{"class":196},[179,16876,15942],{"class":681},[179,16878,9840],{"class":192},[179,16880,9889],{"class":196},[179,16882,16883],{"class":224}," -a",[179,16885,550],{"class":549},[179,16887,16857],{"class":192},[179,16889,1480],{"class":681},[53,16891,16893],{"id":16892},"voir-les-logs","Voir les logs",[102,16895,16897],{"className":173,"code":16896,"language":175,"meta":111,"style":111},"# Parcourir les commits avec prévisualisation\ngit log --oneline | fzf --preview 'git show {1}'\n",[109,16898,16899,16904],{"__ignoreMap":111},[179,16900,16901],{"class":181,"line":182},[179,16902,16903],{"class":185},"# Parcourir les commits avec prévisualisation\n",[179,16905,16906,16908,16911,16914,16916,16918,16920],{"class":181,"line":189},[179,16907,9840],{"class":192},[179,16909,16910],{"class":196}," log",[179,16912,16913],{"class":224}," --oneline",[179,16915,550],{"class":549},[179,16917,16857],{"class":192},[179,16919,16644],{"class":224},[179,16921,16922],{"class":196}," 'git show {1}'\n",[53,16924,16926],{"id":16925},"ajouter-des-fichiers-au-staging","Ajouter des fichiers au staging",[102,16928,16930],{"className":173,"code":16929,"language":175,"meta":111,"style":111},"# Sélectionner les fichiers à ajouter (multi-sélection avec Tab)\ngit add $(git status -s | fzf -m | awk '{print $2}')\n",[109,16931,16932,16937],{"__ignoreMap":111},[179,16933,16934],{"class":181,"line":182},[179,16935,16936],{"class":185},"# Sélectionner les fichiers à ajouter (multi-sélection avec Tab)\n",[179,16938,16939,16941,16943,16945,16947,16949,16951,16953,16955,16957,16959,16962,16965],{"class":181,"line":189},[179,16940,9840],{"class":192},[179,16942,203],{"class":196},[179,16944,15942],{"class":681},[179,16946,9840],{"class":192},[179,16948,7568],{"class":196},[179,16950,8412],{"class":224},[179,16952,550],{"class":549},[179,16954,16857],{"class":192},[179,16956,8420],{"class":224},[179,16958,550],{"class":549},[179,16960,16961],{"class":192}," awk",[179,16963,16964],{"class":196}," '{print $2}'",[179,16966,1480],{"class":681},[53,16968,16970],{"id":16969},"alias-git-fzf","Alias Git + fzf",[17,16972,16973,16974,665,16977,642],{},"Ajoutez ces alias dans votre ",[109,16975,16976],{},".bashrc",[109,16978,16979],{},".zshrc",[102,16981,16983],{"className":173,"code":16982,"language":175,"meta":111,"style":111},"# Changer de branche\nalias gbf='git checkout $(git branch | fzf)'\n\n# Supprimer une branche\nalias gbd='git branch -d $(git branch | fzf)'\n\n# Voir un commit\nalias glf='git log --oneline | fzf --preview \"git show {1}\"'\n",[109,16984,16985,16990,17003,17007,17012,17024,17028,17033],{"__ignoreMap":111},[179,16986,16987],{"class":181,"line":182},[179,16988,16989],{"class":185},"# Changer de branche\n",[179,16991,16992,16995,16998,17000],{"class":181,"line":189},[179,16993,16994],{"class":549},"alias",[179,16996,16997],{"class":681}," gbf",[179,16999,685],{"class":549},[179,17001,17002],{"class":196},"'git checkout $(git branch | fzf)'\n",[179,17004,17005],{"class":181,"line":448},[179,17006,1404],{"emptyLinePlaceholder":477},[179,17008,17009],{"class":181,"line":775},[179,17010,17011],{"class":185},"# Supprimer une branche\n",[179,17013,17014,17016,17019,17021],{"class":181,"line":852},[179,17015,16994],{"class":549},[179,17017,17018],{"class":681}," gbd",[179,17020,685],{"class":549},[179,17022,17023],{"class":196},"'git branch -d $(git branch | fzf)'\n",[179,17025,17026],{"class":181,"line":1351},[179,17027,1404],{"emptyLinePlaceholder":477},[179,17029,17030],{"class":181,"line":1363},[179,17031,17032],{"class":185},"# Voir un commit\n",[179,17034,17035,17037,17040,17042],{"class":181,"line":1381},[179,17036,16994],{"class":549},[179,17038,17039],{"class":681}," glf",[179,17041,685],{"class":549},[179,17043,17044],{"class":196},"'git log --oneline | fzf --preview \"git show {1}\"'\n",[12,17046,17048],{"id":17047},"intégration-avec-dautres-outils","Intégration avec d'autres outils",[53,17050,17052],{"id":17051},"avec-find","Avec find",[102,17054,17056],{"className":173,"code":17055,"language":175,"meta":111,"style":111},"# Chercher uniquement les fichiers .js\nfind . -name \"*.js\" | fzf\n\n# Exclure node_modules\nfind . -not -path \"*/node_modules/*\" -name \"*.ts\" | fzf\n",[109,17057,17058,17063,17080,17084,17089],{"__ignoreMap":111},[179,17059,17060],{"class":181,"line":182},[179,17061,17062],{"class":185},"# Chercher uniquement les fichiers .js\n",[179,17064,17065,17067,17070,17073,17076,17078],{"class":181,"line":189},[179,17066,3989],{"class":192},[179,17068,17069],{"class":196}," .",[179,17071,17072],{"class":224}," -name",[179,17074,17075],{"class":196}," \"*.js\"",[179,17077,550],{"class":549},[179,17079,16186],{"class":192},[179,17081,17082],{"class":181,"line":448},[179,17083,1404],{"emptyLinePlaceholder":477},[179,17085,17086],{"class":181,"line":775},[179,17087,17088],{"class":185},"# Exclure node_modules\n",[179,17090,17091,17093,17095,17098,17101,17104,17106,17109,17111],{"class":181,"line":852},[179,17092,3989],{"class":192},[179,17094,17069],{"class":196},[179,17096,17097],{"class":224}," -not",[179,17099,17100],{"class":224}," -path",[179,17102,17103],{"class":196}," \"*/node_modules/*\"",[179,17105,17072],{"class":224},[179,17107,17108],{"class":196}," \"*.ts\"",[179,17110,550],{"class":549},[179,17112,16186],{"class":192},[53,17114,17116],{"id":17115},"avec-ripgrep-rg","Avec ripgrep (rg)",[102,17118,17120],{"className":173,"code":17119,"language":175,"meta":111,"style":111},"# Rechercher dans le contenu des fichiers puis filtrer avec fzf\nrg --line-number \"\" | fzf --delimiter=: --preview 'bat --color=always {1} --highlight-line {2}'\n",[109,17121,17122,17127],{"__ignoreMap":111},[179,17123,17124],{"class":181,"line":182},[179,17125,17126],{"class":185},"# Rechercher dans le contenu des fichiers puis filtrer avec fzf\n",[179,17128,17129,17132,17135,17138,17140,17142,17145,17147],{"class":181,"line":189},[179,17130,17131],{"class":192},"rg",[179,17133,17134],{"class":224}," --line-number",[179,17136,17137],{"class":196}," \"\"",[179,17139,550],{"class":549},[179,17141,16857],{"class":192},[179,17143,17144],{"class":224}," --delimiter=:",[179,17146,16644],{"class":224},[179,17148,17149],{"class":196}," 'bat --color=always {1} --highlight-line {2}'\n",[53,17151,17153],{"id":17152},"avec-docker","Avec docker",[102,17155,17157],{"className":173,"code":17156,"language":175,"meta":111,"style":111},"# Sélectionner un conteneur à arrêter\ndocker stop $(docker ps --format \"{{.Names}}\" | fzf)\n\n# Voir les logs d'un conteneur\ndocker logs $(docker ps -a --format \"{{.Names}}\" | fzf)\n\n# Supprimer une image\ndocker rmi $(docker images --format \"{{.Repository}}:{{.Tag}}\" | fzf)\n",[109,17158,17159,17164,17188,17192,17197,17221,17225,17229],{"__ignoreMap":111},[179,17160,17161],{"class":181,"line":182},[179,17162,17163],{"class":185},"# Sélectionner un conteneur à arrêter\n",[179,17165,17166,17168,17170,17172,17174,17176,17179,17182,17184,17186],{"class":181,"line":189},[179,17167,8367],{"class":192},[179,17169,15236],{"class":196},[179,17171,15942],{"class":681},[179,17173,8367],{"class":192},[179,17175,15218],{"class":196},[179,17177,17178],{"class":224}," --format",[179,17180,17181],{"class":196}," \"{{.Names}}\"",[179,17183,550],{"class":549},[179,17185,16857],{"class":192},[179,17187,1480],{"class":681},[179,17189,17190],{"class":181,"line":448},[179,17191,1404],{"emptyLinePlaceholder":477},[179,17193,17194],{"class":181,"line":775},[179,17195,17196],{"class":185},"# Voir les logs d'un conteneur\n",[179,17198,17199,17201,17203,17205,17207,17209,17211,17213,17215,17217,17219],{"class":181,"line":852},[179,17200,8367],{"class":192},[179,17202,9137],{"class":196},[179,17204,15942],{"class":681},[179,17206,8367],{"class":192},[179,17208,15218],{"class":196},[179,17210,16883],{"class":224},[179,17212,17178],{"class":224},[179,17214,17181],{"class":196},[179,17216,550],{"class":549},[179,17218,16857],{"class":192},[179,17220,1480],{"class":681},[179,17222,17223],{"class":181,"line":1351},[179,17224,1404],{"emptyLinePlaceholder":477},[179,17226,17227],{"class":181,"line":1363},[179,17228,15362],{"class":185},[179,17230,17231,17233,17235,17237,17239,17242,17244,17247,17249,17251],{"class":181,"line":1381},[179,17232,8367],{"class":192},[179,17234,15369],{"class":196},[179,17236,15942],{"class":681},[179,17238,8367],{"class":192},[179,17240,17241],{"class":196}," images",[179,17243,17178],{"class":224},[179,17245,17246],{"class":196}," \"{{.Repository}}:{{.Tag}}\"",[179,17248,550],{"class":549},[179,17250,16857],{"class":192},[179,17252,1480],{"class":681},[53,17254,17256],{"id":17255},"avec-kill-tuer-un-processus","Avec kill (tuer un processus)",[102,17258,17260],{"className":173,"code":17259,"language":175,"meta":111,"style":111},"# Sélectionner un processus à tuer\nkill $(ps aux | fzf | awk '{print $2}')\n",[109,17261,17262,17267],{"__ignoreMap":111},[179,17263,17264],{"class":181,"line":182},[179,17265,17266],{"class":185},"# Sélectionner un processus à tuer\n",[179,17268,17269,17272,17274,17276,17278,17280,17282,17284,17286,17288],{"class":181,"line":189},[179,17270,17271],{"class":224},"kill",[179,17273,15942],{"class":681},[179,17275,16422],{"class":192},[179,17277,16425],{"class":196},[179,17279,550],{"class":549},[179,17281,16857],{"class":192},[179,17283,550],{"class":549},[179,17285,16961],{"class":192},[179,17287,16964],{"class":196},[179,17289,1480],{"class":681},[12,17291,17293],{"id":17292},"configuration-permanente","Configuration permanente",[17,17295,17296,17297,665,17299,642],{},"Ajoutez ces variables d'environnement dans votre ",[109,17298,16976],{},[109,17300,16979],{},[102,17302,17304],{"className":173,"code":17303,"language":175,"meta":111,"style":111},"# Options par défaut de fzf\nexport FZF_DEFAULT_OPTS='\n  --height 40%\n  --reverse\n  --border\n  --preview \"bat --color=always {} 2>/dev/null || cat {}\"\n'\n\n# Utiliser fd au lieu de find (plus rapide, respecte .gitignore)\nexport FZF_DEFAULT_COMMAND='fd --type f --hidden --follow --exclude .git'\n\n# Options pour Ctrl+T\nexport FZF_CTRL_T_COMMAND=\"$FZF_DEFAULT_COMMAND\"\nexport FZF_CTRL_T_OPTS='--preview \"bat --color=always {}\"'\n\n# Options pour Alt+C\nexport FZF_ALT_C_COMMAND='fd --type d --hidden --follow --exclude .git'\nexport FZF_ALT_C_OPTS='--preview \"ls -la {}\"'\n",[109,17305,17306,17311,17323,17328,17333,17338,17343,17347,17351,17356,17368,17372,17377,17394,17406,17410,17415,17427],{"__ignoreMap":111},[179,17307,17308],{"class":181,"line":182},[179,17309,17310],{"class":185},"# Options par défaut de fzf\n",[179,17312,17313,17315,17318,17320],{"class":181,"line":189},[179,17314,678],{"class":549},[179,17316,17317],{"class":681}," FZF_DEFAULT_OPTS",[179,17319,685],{"class":549},[179,17321,17322],{"class":196},"'\n",[179,17324,17325],{"class":181,"line":448},[179,17326,17327],{"class":196},"  --height 40%\n",[179,17329,17330],{"class":181,"line":775},[179,17331,17332],{"class":196},"  --reverse\n",[179,17334,17335],{"class":181,"line":852},[179,17336,17337],{"class":196},"  --border\n",[179,17339,17340],{"class":181,"line":1351},[179,17341,17342],{"class":196},"  --preview \"bat --color=always {} 2>/dev/null || cat {}\"\n",[179,17344,17345],{"class":181,"line":1363},[179,17346,17322],{"class":196},[179,17348,17349],{"class":181,"line":1381},[179,17350,1404],{"emptyLinePlaceholder":477},[179,17352,17353],{"class":181,"line":1401},[179,17354,17355],{"class":185},"# Utiliser fd au lieu de find (plus rapide, respecte .gitignore)\n",[179,17357,17358,17360,17363,17365],{"class":181,"line":1407},[179,17359,678],{"class":549},[179,17361,17362],{"class":681}," FZF_DEFAULT_COMMAND",[179,17364,685],{"class":549},[179,17366,17367],{"class":196},"'fd --type f --hidden --follow --exclude .git'\n",[179,17369,17370],{"class":181,"line":1418},[179,17371,1404],{"emptyLinePlaceholder":477},[179,17373,17374],{"class":181,"line":1435},[179,17375,17376],{"class":185},"# Options pour Ctrl+T\n",[179,17378,17379,17381,17384,17386,17388,17391],{"class":181,"line":1440},[179,17380,678],{"class":549},[179,17382,17383],{"class":681}," FZF_CTRL_T_COMMAND",[179,17385,685],{"class":549},[179,17387,5813],{"class":196},[179,17389,17390],{"class":681},"$FZF_DEFAULT_COMMAND",[179,17392,17393],{"class":196},"\"\n",[179,17395,17396,17398,17401,17403],{"class":181,"line":1450},[179,17397,678],{"class":549},[179,17399,17400],{"class":681}," FZF_CTRL_T_OPTS",[179,17402,685],{"class":549},[179,17404,17405],{"class":196},"'--preview \"bat --color=always {}\"'\n",[179,17407,17408],{"class":181,"line":1483},[179,17409,1404],{"emptyLinePlaceholder":477},[179,17411,17412],{"class":181,"line":1503},[179,17413,17414],{"class":185},"# Options pour Alt+C\n",[179,17416,17417,17419,17422,17424],{"class":181,"line":1533},[179,17418,678],{"class":549},[179,17420,17421],{"class":681}," FZF_ALT_C_COMMAND",[179,17423,685],{"class":549},[179,17425,17426],{"class":196},"'fd --type d --hidden --follow --exclude .git'\n",[179,17428,17429,17431,17434,17436],{"class":181,"line":1557},[179,17430,678],{"class":549},[179,17432,17433],{"class":681}," FZF_ALT_C_OPTS",[179,17435,685],{"class":549},[179,17437,17438],{"class":196},"'--preview \"ls -la {}\"'\n",[12,17440,17442],{"id":17441},"thème-et-couleurs","Thème et couleurs",[102,17444,17446],{"className":173,"code":17445,"language":175,"meta":111,"style":111},"# Thème sombre personnalisé\nexport FZF_DEFAULT_OPTS='\n  --color=bg+:#363a4f,bg:#24273a,spinner:#f4dbd6,hl:#ed8796\n  --color=fg:#cad3f5,header:#ed8796,info:#c6a0f6,pointer:#f4dbd6\n  --color=marker:#f4dbd6,fg+:#cad3f5,prompt:#c6a0f6,hl+:#ed8796\n  --border --reverse --height 40%\n'\n",[109,17447,17448,17453,17463,17468,17473,17478,17483],{"__ignoreMap":111},[179,17449,17450],{"class":181,"line":182},[179,17451,17452],{"class":185},"# Thème sombre personnalisé\n",[179,17454,17455,17457,17459,17461],{"class":181,"line":189},[179,17456,678],{"class":549},[179,17458,17317],{"class":681},[179,17460,685],{"class":549},[179,17462,17322],{"class":196},[179,17464,17465],{"class":181,"line":448},[179,17466,17467],{"class":196},"  --color=bg+:#363a4f,bg:#24273a,spinner:#f4dbd6,hl:#ed8796\n",[179,17469,17470],{"class":181,"line":775},[179,17471,17472],{"class":196},"  --color=fg:#cad3f5,header:#ed8796,info:#c6a0f6,pointer:#f4dbd6\n",[179,17474,17475],{"class":181,"line":852},[179,17476,17477],{"class":196},"  --color=marker:#f4dbd6,fg+:#cad3f5,prompt:#c6a0f6,hl+:#ed8796\n",[179,17479,17480],{"class":181,"line":1351},[179,17481,17482],{"class":196},"  --border --reverse --height 40%\n",[179,17484,17485],{"class":181,"line":1363},[179,17486,17322],{"class":196},[12,17488,17490],{"id":17489},"fonctions-utiles","Fonctions utiles",[17,17492,17493],{},"Ajoutez ces fonctions à votre shell :",[102,17495,17497],{"className":173,"code":17496,"language":175,"meta":111,"style":111},"# Ouvrir un fichier dans l'éditeur\nfe() {\n  local file\n  file=$(fzf --preview 'bat --color=always {}') && ${EDITOR:-vim} \"$file\"\n}\n\n# cd dans un sous-répertoire\nfcd() {\n  local dir\n  dir=$(fd --type d | fzf --preview 'ls -la {}') && cd \"$dir\"\n}\n\n# Chercher dans le contenu puis ouvrir le fichier\nfgrep() {\n  local result\n  result=$(rg --line-number \"$1\" | fzf --delimiter=: --preview 'bat --color=always {1} --highlight-line {2}')\n  local file=$(echo \"$result\" | cut -d: -f1)\n  local line=$(echo \"$result\" | cut -d: -f2)\n  [ -n \"$file\" ] && ${EDITOR:-vim} \"+$line\" \"$file\"\n}\n",[109,17498,17499,17504,17511,17519,17550,17554,17558,17563,17570,17577,17617,17621,17625,17630,17637,17644,17677,17710,17740,17775],{"__ignoreMap":111},[179,17500,17501],{"class":181,"line":182},[179,17502,17503],{"class":185},"# Ouvrir un fichier dans l'éditeur\n",[179,17505,17506,17509],{"class":181,"line":189},[179,17507,17508],{"class":192},"fe",[179,17510,3741],{"class":681},[179,17512,17513,17516],{"class":181,"line":448},[179,17514,17515],{"class":549},"  local",[179,17517,17518],{"class":681}," file\n",[179,17520,17521,17524,17526,17528,17530,17532,17534,17537,17540,17543,17545,17548],{"class":181,"line":775},[179,17522,17523],{"class":681},"  file",[179,17525,685],{"class":549},[179,17527,3541],{"class":681},[179,17529,16157],{"class":192},[179,17531,16644],{"class":224},[179,17533,16683],{"class":196},[179,17535,17536],{"class":681},") && ${EDITOR",[179,17538,17539],{"class":549},":-",[179,17541,17542],{"class":681},"vim} ",[179,17544,5813],{"class":196},[179,17546,17547],{"class":681},"$file",[179,17549,17393],{"class":196},[179,17551,17552],{"class":181,"line":852},[179,17553,3814],{"class":681},[179,17555,17556],{"class":181,"line":1351},[179,17557,1404],{"emptyLinePlaceholder":477},[179,17559,17560],{"class":181,"line":1363},[179,17561,17562],{"class":185},"# cd dans un sous-répertoire\n",[179,17564,17565,17568],{"class":181,"line":1381},[179,17566,17567],{"class":192},"fcd",[179,17569,3741],{"class":681},[179,17571,17572,17574],{"class":181,"line":1401},[179,17573,17515],{"class":549},[179,17575,17576],{"class":681}," dir\n",[179,17578,17579,17582,17584,17586,17589,17592,17595,17597,17599,17601,17604,17607,17609,17612,17615],{"class":181,"line":1407},[179,17580,17581],{"class":681},"  dir",[179,17583,685],{"class":549},[179,17585,3541],{"class":681},[179,17587,17588],{"class":192},"fd",[179,17590,17591],{"class":224}," --type",[179,17593,17594],{"class":196}," d",[179,17596,550],{"class":549},[179,17598,16857],{"class":192},[179,17600,16644],{"class":224},[179,17602,17603],{"class":196}," 'ls -la {}'",[179,17605,17606],{"class":681},") && ",[179,17608,748],{"class":224},[179,17610,17611],{"class":196}," \"",[179,17613,17614],{"class":681},"$dir",[179,17616,17393],{"class":196},[179,17618,17619],{"class":181,"line":1418},[179,17620,3814],{"class":681},[179,17622,17623],{"class":181,"line":1435},[179,17624,1404],{"emptyLinePlaceholder":477},[179,17626,17627],{"class":181,"line":1440},[179,17628,17629],{"class":185},"# Chercher dans le contenu puis ouvrir le fichier\n",[179,17631,17632,17635],{"class":181,"line":1450},[179,17633,17634],{"class":192},"fgrep",[179,17636,3741],{"class":681},[179,17638,17639,17641],{"class":181,"line":1483},[179,17640,17515],{"class":549},[179,17642,17643],{"class":681}," result\n",[179,17645,17646,17649,17651,17653,17655,17657,17659,17662,17664,17666,17668,17670,17672,17675],{"class":181,"line":1503},[179,17647,17648],{"class":681},"  result",[179,17650,685],{"class":549},[179,17652,3541],{"class":681},[179,17654,17131],{"class":192},[179,17656,17134],{"class":224},[179,17658,17611],{"class":196},[179,17660,17661],{"class":224},"$1",[179,17663,5813],{"class":196},[179,17665,550],{"class":549},[179,17667,16857],{"class":192},[179,17669,17144],{"class":224},[179,17671,16644],{"class":224},[179,17673,17674],{"class":196}," 'bat --color=always {1} --highlight-line {2}'",[179,17676,1480],{"class":681},[179,17678,17679,17681,17684,17686,17688,17690,17692,17695,17697,17699,17702,17705,17708],{"class":181,"line":1533},[179,17680,17515],{"class":549},[179,17682,17683],{"class":681}," file",[179,17685,685],{"class":549},[179,17687,3541],{"class":681},[179,17689,4760],{"class":224},[179,17691,17611],{"class":196},[179,17693,17694],{"class":681},"$result",[179,17696,5813],{"class":196},[179,17698,550],{"class":549},[179,17700,17701],{"class":192}," cut",[179,17703,17704],{"class":224}," -d:",[179,17706,17707],{"class":224}," -f1",[179,17709,1480],{"class":681},[179,17711,17712,17714,17717,17719,17721,17723,17725,17727,17729,17731,17733,17735,17738],{"class":181,"line":1557},[179,17713,17515],{"class":549},[179,17715,17716],{"class":681}," line",[179,17718,685],{"class":549},[179,17720,3541],{"class":681},[179,17722,4760],{"class":224},[179,17724,17611],{"class":196},[179,17726,17694],{"class":681},[179,17728,5813],{"class":196},[179,17730,550],{"class":549},[179,17732,17701],{"class":192},[179,17734,17704],{"class":224},[179,17736,17737],{"class":224}," -f2",[179,17739,1480],{"class":681},[179,17741,17742,17745,17748,17750,17752,17754,17757,17759,17761,17764,17767,17769,17771,17773],{"class":181,"line":1583},[179,17743,17744],{"class":681},"  [ ",[179,17746,17747],{"class":549},"-n",[179,17749,17611],{"class":196},[179,17751,17547],{"class":681},[179,17753,5813],{"class":196},[179,17755,17756],{"class":681}," ] && ${EDITOR",[179,17758,17539],{"class":549},[179,17760,17542],{"class":681},[179,17762,17763],{"class":196},"\"+",[179,17765,17766],{"class":681},"$line",[179,17768,5813],{"class":196},[179,17770,17611],{"class":196},[179,17772,17547],{"class":681},[179,17774,17393],{"class":196},[179,17776,17777],{"class":181,"line":1598},[179,17778,3814],{"class":681},[12,17780,17782],{"id":17781},"outils-complémentaires","Outils complémentaires",[17,17784,17785],{},"Pour tirer le meilleur de fzf, installez ces outils :",[1120,17787,17788,17800],{},[1123,17789,17790],{},[1126,17791,17792,17795,17798],{},[1129,17793,17794],{},"Outil",[1129,17796,17797],{},"Rôle",[1129,17799,15039],{},[1136,17801,17802,17818,17835,17853],{},[1126,17803,17804,17808,17813],{},[1141,17805,17806],{},[109,17807,17588],{},[1141,17809,17810,17811],{},"Alternative rapide à ",[109,17812,3989],{},[1141,17814,17815],{},[109,17816,17817],{},"apt install fd-find",[1126,17819,17820,17825,17830],{},[1141,17821,17822],{},[109,17823,17824],{},"bat",[1141,17826,17827,17829],{},[109,17828,12598],{}," avec coloration syntaxique",[1141,17831,17832],{},[109,17833,17834],{},"apt install bat",[1126,17836,17837,17842,17848],{},[1141,17838,17839],{},[109,17840,17841],{},"ripgrep",[1141,17843,17844,17847],{},[109,17845,17846],{},"grep"," ultra-rapide",[1141,17849,17850],{},[109,17851,17852],{},"apt install ripgrep",[1126,17854,17855,17860,17863],{},[1141,17856,17857],{},[109,17858,17859],{},"tree",[1141,17861,17862],{},"Afficher l'arborescence",[1141,17864,17865],{},[109,17866,17867],{},"apt install tree",[12,17869,406],{"id":405},[17,17871,17872],{},"fzf transforme votre terminal en un outil de recherche puissant et interactif. Que ce soit pour naviguer dans vos fichiers, parcourir votre historique ou gérer vos conteneurs Docker, fzf accélère considérablement votre workflow. Combiné avec fd, bat et ripgrep, il devient un outil indispensable pour tout développeur travaillant en ligne de commande.",[438,17874,17875],{},"html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":111,"searchDepth":189,"depth":189,"links":17877},[17878,17879,17885,17890,17893,17894,17899,17905,17911,17912,17913,17914,17915],{"id":16151,"depth":189,"text":16152},{"id":15038,"depth":189,"text":15039,"children":17880},[17881,17882,17883,17884],{"id":2592,"depth":448,"text":2188},{"id":16225,"depth":448,"text":16226},{"id":2593,"depth":448,"text":16263},{"id":15094,"depth":448,"text":15095},{"id":16310,"depth":189,"text":16311,"children":17886},[17887,17888,17889],{"id":16314,"depth":448,"text":16315},{"id":16340,"depth":448,"text":16341},{"id":16403,"depth":448,"text":16404},{"id":16470,"depth":189,"text":16471,"children":17891},[17892],{"id":16525,"depth":448,"text":16526},{"id":16549,"depth":189,"text":16550},{"id":16622,"depth":189,"text":16623,"children":17895},[17896,17897,17898],{"id":16626,"depth":448,"text":16627},{"id":16689,"depth":448,"text":16690},{"id":16768,"depth":448,"text":16769},{"id":16821,"depth":189,"text":16822,"children":17900},[17901,17902,17903,17904],{"id":16828,"depth":448,"text":16829},{"id":16892,"depth":448,"text":16893},{"id":16925,"depth":448,"text":16926},{"id":16969,"depth":448,"text":16970},{"id":17047,"depth":189,"text":17048,"children":17906},[17907,17908,17909,17910],{"id":17051,"depth":448,"text":17052},{"id":17115,"depth":448,"text":17116},{"id":17152,"depth":448,"text":17153},{"id":17255,"depth":448,"text":17256},{"id":17292,"depth":189,"text":17293},{"id":17441,"depth":189,"text":17442},{"id":17489,"depth":189,"text":17490},{"id":17781,"depth":189,"text":17782},{"id":405,"depth":189,"text":406},"Découvrez fzf, l'outil en ligne de commande pour rechercher fichiers, historique et bien plus grâce à la recherche floue interactive dans votre terminal.","/images/posts/2026/03/fzf-le-fuzzy-finder-qui-booste-votre-productivite-en-terminal.webp",{},"/posts/fzf-le-fuzzy-finder-qui-booste-votre-productivite-en-terminal",{"title":16146,"description":17916},"posts/fzf-le-fuzzy-finder-qui-booste-votre-productivite-en-terminal",[16157,17923,17924,17925,10809],"terminal","cli","productivité","3MFtt0iGxTqOMIBpdNrVFLzx6IVMiRFtnJxv1ssXDEc",{"id":17928,"title":17929,"author":12400,"body":17930,"date":15004,"description":19152,"extension":474,"image":19153,"meta":19154,"navigation":477,"path":19155,"readingTime":479,"seo":19156,"stem":19157,"tags":19158,"updatedAt":15004,"__hash__":19161},"posts/posts/github-collaborer-et-gerer-vos-projets-avec-git.md","GitHub : collaborer et gérer vos projets avec Git",{"type":9,"value":17931,"toc":19113},[17932,17936,17946,17949,17953,17955,17971,17973,17986,17988,17996,18000,18034,18038,18061,18065,18086,18090,18152,18156,18160,18256,18260,18313,18317,18320,18415,18419,18450,18454,18461,18465,18489,18493,18519,18523,18526,18530,18606,18610,18636,18640,18643,18647,18801,18805,18933,18937,18940,18962,18966,19028,19034,19040,19044,19105,19107,19110],[12,17933,17935],{"id":17934},"quest-ce-que-github","Qu'est-ce que GitHub ?",[17,17937,17938,17941,17942,17945],{},[21,17939,17940],{},"GitHub"," est une plateforme web basée sur ",[21,17943,17944],{},"Git"," qui permet d'héberger, versionner et collaborer sur des projets de développement. Avec plus de 100 millions de développeurs, c'est la plus grande communauté de code au monde.",[17,17947,17948],{},"GitHub offre bien plus qu'un simple hébergement de dépôts : gestion de projets, revue de code, CI/CD, documentation et bien plus encore.",[12,17950,17952],{"id":17951},"prérequis-installer-git","Prérequis : installer Git",[53,17954,2188],{"id":2592},[102,17956,17958],{"className":173,"code":17957,"language":175,"meta":111,"style":111},"sudo apt install git\n",[109,17959,17960],{"__ignoreMap":111},[179,17961,17962,17964,17966,17968],{"class":181,"line":182},[179,17963,567],{"class":192},[179,17965,621],{"class":196},[179,17967,573],{"class":196},[179,17969,17970],{"class":196}," git\n",[53,17972,16226],{"id":16225},[102,17974,17976],{"className":173,"code":17975,"language":175,"meta":111,"style":111},"brew install git\n",[109,17977,17978],{"__ignoreMap":111},[179,17979,17980,17982,17984],{"class":181,"line":182},[179,17981,11087],{"class":192},[179,17983,573],{"class":196},[179,17985,17970],{"class":196},[53,17987,16263],{"id":2593},[17,17989,17990,17991,436],{},"Téléchargez ",[730,17992,17995],{"href":17993,"rel":17994},"https://git-scm.com/download/win",[734],"Git for Windows",[53,17997,17999],{"id":17998},"configuration-initiale","Configuration initiale",[102,18001,18003],{"className":173,"code":18002,"language":175,"meta":111,"style":111},"git config --global user.name \"Votre Nom\"\ngit config --global user.email \"votre@email.com\"\n",[109,18004,18005,18021],{"__ignoreMap":111},[179,18006,18007,18009,18012,18015,18018],{"class":181,"line":182},[179,18008,9840],{"class":192},[179,18010,18011],{"class":196}," config",[179,18013,18014],{"class":224}," --global",[179,18016,18017],{"class":196}," user.name",[179,18019,18020],{"class":196}," \"Votre Nom\"\n",[179,18022,18023,18025,18027,18029,18032],{"class":181,"line":189},[179,18024,9840],{"class":192},[179,18026,18011],{"class":196},[179,18028,18014],{"class":224},[179,18030,18031],{"class":196}," user.email",[179,18033,12584],{"class":196},[12,18035,18037],{"id":18036},"créer-un-compte-et-un-dépôt","Créer un compte et un dépôt",[79,18039,18040,18048,18053,18056],{},[36,18041,18042,18043],{},"Créez un compte sur ",[730,18044,18047],{"href":18045,"rel":18046},"https://github.com",[734],"github.com",[36,18049,2848,18050],{},[21,18051,18052],{},"New repository",[36,18054,18055],{},"Donnez un nom, choisissez la visibilité (public/privé)",[36,18057,2848,18058],{},[21,18059,18060],{},"Create repository",[53,18062,18064],{"id":18063},"cloner-un-dépôt-existant","Cloner un dépôt existant",[102,18066,18068],{"className":173,"code":18067,"language":175,"meta":111,"style":111},"git clone https://github.com/utilisateur/mon-projet.git\ncd mon-projet\n",[109,18069,18070,18079],{"__ignoreMap":111},[179,18071,18072,18074,18076],{"class":181,"line":182},[179,18073,9840],{"class":192},[179,18075,16202],{"class":196},[179,18077,18078],{"class":196}," https://github.com/utilisateur/mon-projet.git\n",[179,18080,18081,18083],{"class":181,"line":189},[179,18082,748],{"class":224},[179,18084,18085],{"class":196}," mon-projet\n",[53,18087,18089],{"id":18088},"lier-un-projet-local-à-github","Lier un projet local à GitHub",[102,18091,18093],{"className":173,"code":18092,"language":175,"meta":111,"style":111},"cd mon-projet\ngit init\ngit add .\ngit commit -m \"Initial commit\"\ngit remote add origin https://github.com/utilisateur/mon-projet.git\ngit push -u origin main\n",[109,18094,18095,18101,18107,18115,18126,18138],{"__ignoreMap":111},[179,18096,18097,18099],{"class":181,"line":182},[179,18098,748],{"class":224},[179,18100,18085],{"class":196},[179,18102,18103,18105],{"class":181,"line":189},[179,18104,9840],{"class":192},[179,18106,9843],{"class":196},[179,18108,18109,18111,18113],{"class":181,"line":448},[179,18110,9840],{"class":192},[179,18112,203],{"class":196},[179,18114,9861],{"class":196},[179,18116,18117,18119,18121,18123],{"class":181,"line":775},[179,18118,9840],{"class":192},[179,18120,9868],{"class":196},[179,18122,8420],{"class":224},[179,18124,18125],{"class":196}," \"Initial commit\"\n",[179,18127,18128,18130,18132,18134,18136],{"class":181,"line":852},[179,18129,9840],{"class":192},[179,18131,9911],{"class":196},[179,18133,203],{"class":196},[179,18135,9916],{"class":196},[179,18137,18078],{"class":196},[179,18139,18140,18142,18145,18148,18150],{"class":181,"line":1351},[179,18141,9840],{"class":192},[179,18143,18144],{"class":196}," push",[179,18146,18147],{"class":224}," -u",[179,18149,9916],{"class":196},[179,18151,9895],{"class":196},[12,18153,18155],{"id":18154},"les-commandes-git-essentielles","Les commandes Git essentielles",[53,18157,18159],{"id":18158},"workflow-quotidien","Workflow quotidien",[102,18161,18163],{"className":173,"code":18162,"language":175,"meta":111,"style":111},"# Voir l'état des fichiers\ngit status\n\n# Ajouter des fichiers au staging\ngit add fichier.js\ngit add .              # tous les fichiers modifiés\n\n# Créer un commit\ngit commit -m \"feat: ajouter la page d'accueil\"\n\n# Envoyer les commits sur GitHub\ngit push\n\n# Récupérer les dernières modifications\ngit pull\n",[109,18164,18165,18170,18176,18180,18185,18194,18205,18209,18214,18225,18229,18234,18241,18245,18250],{"__ignoreMap":111},[179,18166,18167],{"class":181,"line":182},[179,18168,18169],{"class":185},"# Voir l'état des fichiers\n",[179,18171,18172,18174],{"class":181,"line":189},[179,18173,9840],{"class":192},[179,18175,7927],{"class":196},[179,18177,18178],{"class":181,"line":448},[179,18179,1404],{"emptyLinePlaceholder":477},[179,18181,18182],{"class":181,"line":775},[179,18183,18184],{"class":185},"# Ajouter des fichiers au staging\n",[179,18186,18187,18189,18191],{"class":181,"line":852},[179,18188,9840],{"class":192},[179,18190,203],{"class":196},[179,18192,18193],{"class":196}," fichier.js\n",[179,18195,18196,18198,18200,18202],{"class":181,"line":1351},[179,18197,9840],{"class":192},[179,18199,203],{"class":196},[179,18201,17069],{"class":196},[179,18203,18204],{"class":185},"              # tous les fichiers modifiés\n",[179,18206,18207],{"class":181,"line":1363},[179,18208,1404],{"emptyLinePlaceholder":477},[179,18210,18211],{"class":181,"line":1381},[179,18212,18213],{"class":185},"# Créer un commit\n",[179,18215,18216,18218,18220,18222],{"class":181,"line":1401},[179,18217,9840],{"class":192},[179,18219,9868],{"class":196},[179,18221,8420],{"class":224},[179,18223,18224],{"class":196}," \"feat: ajouter la page d'accueil\"\n",[179,18226,18227],{"class":181,"line":1407},[179,18228,1404],{"emptyLinePlaceholder":477},[179,18230,18231],{"class":181,"line":1418},[179,18232,18233],{"class":185},"# Envoyer les commits sur GitHub\n",[179,18235,18236,18238],{"class":181,"line":1435},[179,18237,9840],{"class":192},[179,18239,18240],{"class":196}," push\n",[179,18242,18243],{"class":181,"line":1440},[179,18244,1404],{"emptyLinePlaceholder":477},[179,18246,18247],{"class":181,"line":1450},[179,18248,18249],{"class":185},"# Récupérer les dernières modifications\n",[179,18251,18252,18254],{"class":181,"line":1483},[179,18253,9840],{"class":192},[179,18255,9175],{"class":196},[53,18257,18259],{"id":18258},"historique-et-inspection","Historique et inspection",[102,18261,18263],{"className":173,"code":18262,"language":175,"meta":111,"style":111},"# Voir l'historique des commits\ngit log --oneline\n\n# Voir les modifications en cours\ngit diff\n\n# Voir qui a modifié chaque ligne d'un fichier\ngit blame fichier.js\n",[109,18264,18265,18270,18279,18283,18288,18295,18299,18304],{"__ignoreMap":111},[179,18266,18267],{"class":181,"line":182},[179,18268,18269],{"class":185},"# Voir l'historique des commits\n",[179,18271,18272,18274,18276],{"class":181,"line":189},[179,18273,9840],{"class":192},[179,18275,16910],{"class":196},[179,18277,18278],{"class":224}," --oneline\n",[179,18280,18281],{"class":181,"line":448},[179,18282,1404],{"emptyLinePlaceholder":477},[179,18284,18285],{"class":181,"line":775},[179,18286,18287],{"class":185},"# Voir les modifications en cours\n",[179,18289,18290,18292],{"class":181,"line":852},[179,18291,9840],{"class":192},[179,18293,18294],{"class":196}," diff\n",[179,18296,18297],{"class":181,"line":1351},[179,18298,1404],{"emptyLinePlaceholder":477},[179,18300,18301],{"class":181,"line":1363},[179,18302,18303],{"class":185},"# Voir qui a modifié chaque ligne d'un fichier\n",[179,18305,18306,18308,18311],{"class":181,"line":1381},[179,18307,9840],{"class":192},[179,18309,18310],{"class":196}," blame",[179,18312,18193],{"class":196},[12,18314,18316],{"id":18315},"les-branches","Les branches",[17,18318,18319],{},"Les branches permettent de travailler sur des fonctionnalités en parallèle sans affecter le code principal.",[102,18321,18323],{"className":173,"code":18322,"language":175,"meta":111,"style":111},"# Créer et basculer sur une nouvelle branche\ngit checkout -b feature/ma-fonctionnalite\n\n# Lister les branches\ngit branch\n\n# Basculer sur une branche existante\ngit checkout main\n\n# Supprimer une branche locale\ngit branch -d feature/ma-fonctionnalite\n\n# Pousser une branche sur GitHub\ngit push -u origin feature/ma-fonctionnalite\n",[109,18324,18325,18330,18342,18346,18351,18358,18362,18367,18375,18379,18384,18394,18398,18403],{"__ignoreMap":111},[179,18326,18327],{"class":181,"line":182},[179,18328,18329],{"class":185},"# Créer et basculer sur une nouvelle branche\n",[179,18331,18332,18334,18336,18339],{"class":181,"line":189},[179,18333,9840],{"class":192},[179,18335,16846],{"class":196},[179,18337,18338],{"class":224}," -b",[179,18340,18341],{"class":196}," feature/ma-fonctionnalite\n",[179,18343,18344],{"class":181,"line":448},[179,18345,1404],{"emptyLinePlaceholder":477},[179,18347,18348],{"class":181,"line":775},[179,18349,18350],{"class":185},"# Lister les branches\n",[179,18352,18353,18355],{"class":181,"line":852},[179,18354,9840],{"class":192},[179,18356,18357],{"class":196}," branch\n",[179,18359,18360],{"class":181,"line":1351},[179,18361,1404],{"emptyLinePlaceholder":477},[179,18363,18364],{"class":181,"line":1363},[179,18365,18366],{"class":185},"# Basculer sur une branche existante\n",[179,18368,18369,18371,18373],{"class":181,"line":1381},[179,18370,9840],{"class":192},[179,18372,16846],{"class":196},[179,18374,9895],{"class":196},[179,18376,18377],{"class":181,"line":1401},[179,18378,1404],{"emptyLinePlaceholder":477},[179,18380,18381],{"class":181,"line":1407},[179,18382,18383],{"class":185},"# Supprimer une branche locale\n",[179,18385,18386,18388,18390,18392],{"class":181,"line":1418},[179,18387,9840],{"class":192},[179,18389,9889],{"class":196},[179,18391,9050],{"class":224},[179,18393,18341],{"class":196},[179,18395,18396],{"class":181,"line":1435},[179,18397,1404],{"emptyLinePlaceholder":477},[179,18399,18400],{"class":181,"line":1440},[179,18401,18402],{"class":185},"# Pousser une branche sur GitHub\n",[179,18404,18405,18407,18409,18411,18413],{"class":181,"line":1450},[179,18406,9840],{"class":192},[179,18408,18144],{"class":196},[179,18410,18147],{"class":224},[179,18412,9916],{"class":196},[179,18414,18341],{"class":196},[53,18416,18418],{"id":18417},"stratégie-de-branches-courante","Stratégie de branches courante",[33,18420,18421,18426,18432,18438,18444],{},[36,18422,18423,18425],{},[109,18424,4645],{}," — code stable, prêt pour la production",[36,18427,18428,18431],{},[109,18429,18430],{},"develop"," — intégration des fonctionnalités en cours",[36,18433,18434,18437],{},[109,18435,18436],{},"feature/*"," — nouvelles fonctionnalités",[36,18439,18440,18443],{},[109,18441,18442],{},"fix/*"," — corrections de bugs",[36,18445,18446,18449],{},[109,18447,18448],{},"release/*"," — préparation d'une nouvelle version",[12,18451,18453],{"id":18452},"les-pull-requests-pr","Les Pull Requests (PR)",[17,18455,18456,18457,18460],{},"Une ",[21,18458,18459],{},"Pull Request"," est une demande de fusion d'une branche vers une autre. C'est le cœur de la collaboration sur GitHub.",[53,18462,18464],{"id":18463},"créer-une-pull-request","Créer une Pull Request",[79,18466,18467,18470,18473,18478,18481,18484],{},[36,18468,18469],{},"Poussez votre branche sur GitHub",[36,18471,18472],{},"Allez sur votre dépôt GitHub",[36,18474,2848,18475],{},[21,18476,18477],{},"Compare & pull request",[36,18479,18480],{},"Ajoutez un titre et une description",[36,18482,18483],{},"Assignez des reviewers",[36,18485,2848,18486],{},[21,18487,18488],{},"Create pull request",[53,18490,18492],{"id":18491},"bonnes-pratiques-pour-les-pr","Bonnes pratiques pour les PR",[33,18494,18495,18501,18507,18513],{},[36,18496,18497,18500],{},[21,18498,18499],{},"Un sujet par PR"," — ne mélangez pas plusieurs fonctionnalités",[36,18502,18503,18506],{},[21,18504,18505],{},"Description claire"," — expliquez le pourquoi, pas seulement le quoi",[36,18508,18509,18512],{},[21,18510,18511],{},"Petites PR"," — plus faciles à relire et à merger",[36,18514,18515,18518],{},[21,18516,18517],{},"Tests inclus"," — prouvez que votre code fonctionne",[12,18520,18522],{"id":18521},"les-issues","Les Issues",[17,18524,18525],{},"Les Issues servent à suivre les bugs, les fonctionnalités à développer et les discussions.",[53,18527,18529],{"id":18528},"créer-une-bonne-issue","Créer une bonne Issue",[102,18531,18533],{"className":5059,"code":18532,"language":5055,"meta":111,"style":111},"## Description\nDécrivez le problème ou la fonctionnalité demandée.\n\n## Étapes pour reproduire (bugs)\n1. Aller sur la page X\n2. Cliquer sur Y\n3. Observer l'erreur\n\n## Comportement attendu\nCe qui devrait se passer.\n\n## Captures d'écran\nSi applicable.\n",[109,18534,18535,18540,18545,18549,18554,18562,18570,18578,18582,18587,18592,18596,18601],{"__ignoreMap":111},[179,18536,18537],{"class":181,"line":182},[179,18538,18539],{"class":5067},"## Description\n",[179,18541,18542],{"class":181,"line":189},[179,18543,18544],{"class":681},"Décrivez le problème ou la fonctionnalité demandée.\n",[179,18546,18547],{"class":181,"line":448},[179,18548,1404],{"emptyLinePlaceholder":477},[179,18550,18551],{"class":181,"line":775},[179,18552,18553],{"class":5067},"## Étapes pour reproduire (bugs)\n",[179,18555,18556,18559],{"class":181,"line":852},[179,18557,18558],{"class":3802},"1.",[179,18560,18561],{"class":681}," Aller sur la page X\n",[179,18563,18564,18567],{"class":181,"line":1351},[179,18565,18566],{"class":3802},"2.",[179,18568,18569],{"class":681}," Cliquer sur Y\n",[179,18571,18572,18575],{"class":181,"line":1363},[179,18573,18574],{"class":3802},"3.",[179,18576,18577],{"class":681}," Observer l'erreur\n",[179,18579,18580],{"class":181,"line":1381},[179,18581,1404],{"emptyLinePlaceholder":477},[179,18583,18584],{"class":181,"line":1401},[179,18585,18586],{"class":5067},"## Comportement attendu\n",[179,18588,18589],{"class":181,"line":1407},[179,18590,18591],{"class":681},"Ce qui devrait se passer.\n",[179,18593,18594],{"class":181,"line":1418},[179,18595,1404],{"emptyLinePlaceholder":477},[179,18597,18598],{"class":181,"line":1435},[179,18599,18600],{"class":5067},"## Captures d'écran\n",[179,18602,18603],{"class":181,"line":1440},[179,18604,18605],{"class":681},"Si applicable.\n",[53,18607,18609],{"id":18608},"labels-utiles","Labels utiles",[33,18611,18612,18618,18624,18630],{},[36,18613,18614,18617],{},[109,18615,18616],{},"bug"," — quelque chose ne fonctionne pas",[36,18619,18620,18623],{},[109,18621,18622],{},"enhancement"," — amélioration souhaitée",[36,18625,18626,18629],{},[109,18627,18628],{},"documentation"," — mise à jour de la doc",[36,18631,18632,18635],{},[109,18633,18634],{},"good first issue"," — idéal pour les nouveaux contributeurs",[12,18637,18639],{"id":18638},"github-actions-cicd","GitHub Actions (CI/CD)",[17,18641,18642],{},"GitHub Actions permet d'automatiser des workflows directement depuis votre dépôt.",[53,18644,18646],{"id":18645},"exemple-lancer-les-tests-à-chaque-push","Exemple : lancer les tests à chaque push",[102,18648,18650],{"className":4955,"code":18649,"language":4951,"meta":111,"style":111},"# .github/workflows/tests.yml\nname: Tests\n\non:\n  push:\n    branches: [main]\n  pull_request:\n    branches: [main]\n\njobs:\n  test:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n      - uses: actions/setup-node@v4\n        with:\n          node-version: 22\n      - run: npm ci\n      - run: npm test\n",[109,18651,18652,18657,18666,18670,18676,18683,18694,18701,18711,18715,18721,18727,18735,18741,18752,18763,18770,18780,18791],{"__ignoreMap":111},[179,18653,18654],{"class":181,"line":182},[179,18655,18656],{"class":185},"# .github/workflows/tests.yml\n",[179,18658,18659,18661,18663],{"class":181,"line":189},[179,18660,3833],{"class":4053},[179,18662,4251],{"class":681},[179,18664,18665],{"class":196},"Tests\n",[179,18667,18668],{"class":181,"line":448},[179,18669,1404],{"emptyLinePlaceholder":477},[179,18671,18672,18674],{"class":181,"line":775},[179,18673,10579],{"class":224},[179,18675,4966],{"class":681},[179,18677,18678,18681],{"class":181,"line":852},[179,18679,18680],{"class":4053},"  push",[179,18682,4966],{"class":681},[179,18684,18685,18688,18690,18692],{"class":181,"line":1351},[179,18686,18687],{"class":4053},"    branches",[179,18689,10582],{"class":681},[179,18691,4645],{"class":196},[179,18693,10593],{"class":681},[179,18695,18696,18699],{"class":181,"line":1363},[179,18697,18698],{"class":4053},"  pull_request",[179,18700,4966],{"class":681},[179,18702,18703,18705,18707,18709],{"class":181,"line":1381},[179,18704,18687],{"class":4053},[179,18706,10582],{"class":681},[179,18708,4645],{"class":196},[179,18710,10593],{"class":681},[179,18712,18713],{"class":181,"line":1401},[179,18714,1404],{"emptyLinePlaceholder":477},[179,18716,18717,18719],{"class":181,"line":1407},[179,18718,10598],{"class":4053},[179,18720,4966],{"class":681},[179,18722,18723,18725],{"class":181,"line":1418},[179,18724,10605],{"class":4053},[179,18726,4966],{"class":681},[179,18728,18729,18731,18733],{"class":181,"line":1435},[179,18730,10612],{"class":4053},[179,18732,4251],{"class":681},[179,18734,10617],{"class":196},[179,18736,18737,18739],{"class":181,"line":1440},[179,18738,10622],{"class":4053},[179,18740,4966],{"class":681},[179,18742,18743,18745,18747,18749],{"class":181,"line":1450},[179,18744,8560],{"class":681},[179,18746,10631],{"class":4053},[179,18748,4251],{"class":681},[179,18750,18751],{"class":196},"actions/checkout@v4\n",[179,18753,18754,18756,18758,18760],{"class":181,"line":1483},[179,18755,8560],{"class":681},[179,18757,10631],{"class":4053},[179,18759,4251],{"class":681},[179,18761,18762],{"class":196},"actions/setup-node@v4\n",[179,18764,18765,18768],{"class":181,"line":1503},[179,18766,18767],{"class":4053},"        with",[179,18769,4966],{"class":681},[179,18771,18772,18775,18777],{"class":181,"line":1533},[179,18773,18774],{"class":4053},"          node-version",[179,18776,4251],{"class":681},[179,18778,18779],{"class":224},"22\n",[179,18781,18782,18784,18786,18788],{"class":181,"line":1557},[179,18783,8560],{"class":681},[179,18785,10643],{"class":4053},[179,18787,4251],{"class":681},[179,18789,18790],{"class":196},"npm ci\n",[179,18792,18793,18795,18797,18799],{"class":181,"line":1583},[179,18794,8560],{"class":681},[179,18796,10643],{"class":4053},[179,18798,4251],{"class":681},[179,18800,10659],{"class":196},[53,18802,18804],{"id":18803},"exemple-déployer-automatiquement","Exemple : déployer automatiquement",[102,18806,18808],{"className":4955,"code":18807,"language":4951,"meta":111,"style":111},"# .github/workflows/deploy.yml\nname: Deploy\n\non:\n  push:\n    branches: [main]\n\njobs:\n  deploy:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n      - run: npm ci\n      - run: npm run build\n      - name: Deploy to server\n        run: rsync -avz ./dist/ user@serveur:/var/www/html/\n",[109,18809,18810,18815,18824,18828,18834,18840,18850,18854,18860,18867,18875,18881,18891,18901,18912,18923],{"__ignoreMap":111},[179,18811,18812],{"class":181,"line":182},[179,18813,18814],{"class":185},"# .github/workflows/deploy.yml\n",[179,18816,18817,18819,18821],{"class":181,"line":189},[179,18818,3833],{"class":4053},[179,18820,4251],{"class":681},[179,18822,18823],{"class":196},"Deploy\n",[179,18825,18826],{"class":181,"line":448},[179,18827,1404],{"emptyLinePlaceholder":477},[179,18829,18830,18832],{"class":181,"line":775},[179,18831,10579],{"class":224},[179,18833,4966],{"class":681},[179,18835,18836,18838],{"class":181,"line":852},[179,18837,18680],{"class":4053},[179,18839,4966],{"class":681},[179,18841,18842,18844,18846,18848],{"class":181,"line":1351},[179,18843,18687],{"class":4053},[179,18845,10582],{"class":681},[179,18847,4645],{"class":196},[179,18849,10593],{"class":681},[179,18851,18852],{"class":181,"line":1363},[179,18853,1404],{"emptyLinePlaceholder":477},[179,18855,18856,18858],{"class":181,"line":1381},[179,18857,10598],{"class":4053},[179,18859,4966],{"class":681},[179,18861,18862,18865],{"class":181,"line":1401},[179,18863,18864],{"class":4053},"  deploy",[179,18866,4966],{"class":681},[179,18868,18869,18871,18873],{"class":181,"line":1407},[179,18870,10612],{"class":4053},[179,18872,4251],{"class":681},[179,18874,10617],{"class":196},[179,18876,18877,18879],{"class":181,"line":1418},[179,18878,10622],{"class":4053},[179,18880,4966],{"class":681},[179,18882,18883,18885,18887,18889],{"class":181,"line":1435},[179,18884,8560],{"class":681},[179,18886,10631],{"class":4053},[179,18888,4251],{"class":681},[179,18890,18751],{"class":196},[179,18892,18893,18895,18897,18899],{"class":181,"line":1440},[179,18894,8560],{"class":681},[179,18896,10643],{"class":4053},[179,18898,4251],{"class":681},[179,18900,18790],{"class":196},[179,18902,18903,18905,18907,18909],{"class":181,"line":1450},[179,18904,8560],{"class":681},[179,18906,10643],{"class":4053},[179,18908,4251],{"class":681},[179,18910,18911],{"class":196},"npm run build\n",[179,18913,18914,18916,18918,18920],{"class":181,"line":1483},[179,18915,8560],{"class":681},[179,18917,3833],{"class":4053},[179,18919,4251],{"class":681},[179,18921,18922],{"class":196},"Deploy to server\n",[179,18924,18925,18928,18930],{"class":181,"line":1503},[179,18926,18927],{"class":4053},"        run",[179,18929,4251],{"class":681},[179,18931,18932],{"class":196},"rsync -avz ./dist/ user@serveur:/var/www/html/\n",[12,18934,18936],{"id":18935},"github-pages","GitHub Pages",[17,18938,18939],{},"GitHub Pages permet d'héberger gratuitement un site statique directement depuis un dépôt.",[79,18941,18942,18948,18956],{},[36,18943,18944,18945],{},"Allez dans ",[21,18946,18947],{},"Settings > Pages",[36,18949,18950,18951,665,18953,10236],{},"Choisissez la branche source (",[109,18952,4645],{},[109,18954,18955],{},"gh-pages",[36,18957,18958,18959],{},"Votre site est accessible sur ",[109,18960,18961],{},"https://utilisateur.github.io/mon-projet/",[12,18963,18965],{"id":18964},"fichiers-importants-dun-dépôt","Fichiers importants d'un dépôt",[1120,18967,18968,18977],{},[1123,18969,18970],{},[1126,18971,18972,18975],{},[1129,18973,18974],{},"Fichier",[1129,18976,17797],{},[1136,18978,18979,18988,18998,19008,19018],{},[1126,18980,18981,18985],{},[1141,18982,18983],{},[109,18984,9654],{},[1141,18986,18987],{},"Présentation du projet",[1126,18989,18990,18995],{},[1141,18991,18992],{},[109,18993,18994],{},"LICENSE",[1141,18996,18997],{},"Licence open source",[1126,18999,19000,19005],{},[1141,19001,19002],{},[109,19003,19004],{},".gitignore",[1141,19006,19007],{},"Fichiers à exclure du versioning",[1126,19009,19010,19015],{},[1141,19011,19012],{},[109,19013,19014],{},"CONTRIBUTING.md",[1141,19016,19017],{},"Guide pour les contributeurs",[1126,19019,19020,19025],{},[1141,19021,19022],{},[109,19023,19024],{},"CHANGELOG.md",[1141,19026,19027],{},"Historique des changements",[53,19029,15515,19031,19033],{"id":19030},"exemple-de-gitignore-pour-nodejs",[109,19032,19004],{}," pour Node.js",[102,19035,19038],{"className":19036,"code":19037,"language":107},[105],"node_modules/\n.env\ndist/\n*.log\n.DS_Store\n",[109,19039,19037],{"__ignoreMap":111},[12,19041,19043],{"id":19042},"raccourcis-clavier-sur-github","Raccourcis clavier sur GitHub",[1120,19045,19046,19054],{},[1123,19047,19048],{},[1126,19049,19050,19052],{},[1129,19051,16487],{},[1129,19053,16490],{},[1136,19055,19056,19066,19075,19085,19095],{},[1126,19057,19058,19063],{},[1141,19059,19060],{},[109,19061,19062],{},"t",[1141,19064,19065],{},"Rechercher un fichier",[1126,19067,19068,19072],{},[1141,19069,19070],{},[109,19071,436],{},[1141,19073,19074],{},"Ouvrir l'éditeur web (github.dev)",[1126,19076,19077,19082],{},[1141,19078,19079],{},[109,19080,19081],{},"s",[1141,19083,19084],{},"Aller à la barre de recherche",[1126,19086,19087,19092],{},[1141,19088,19089],{},[109,19090,19091],{},"g n",[1141,19093,19094],{},"Aller aux notifications",[1126,19096,19097,19102],{},[1141,19098,19099],{},[109,19100,19101],{},"g c",[1141,19103,19104],{},"Aller au code du dépôt",[12,19106,406],{"id":405},[17,19108,19109],{},"GitHub est bien plus qu'un hébergeur de code — c'est un écosystème complet pour développer, collaborer et déployer vos projets. Maîtriser Git et GitHub est une compétence essentielle pour tout développeur, que ce soit pour contribuer à l'open source ou travailler en équipe.",[438,19111,19112],{},"html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .s9eBZ, html code.shiki .s9eBZ{--shiki-default:#22863A;--shiki-dark:#85E89D}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sq-ep, html code.shiki .sq-ep{--shiki-default:#005CC5;--shiki-default-font-weight:bold;--shiki-dark:#79B8FF;--shiki-dark-font-weight:bold}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}",{"title":111,"searchDepth":189,"depth":189,"links":19114},[19115,19116,19122,19126,19130,19133,19137,19141,19145,19146,19150,19151],{"id":17934,"depth":189,"text":17935},{"id":17951,"depth":189,"text":17952,"children":19117},[19118,19119,19120,19121],{"id":2592,"depth":448,"text":2188},{"id":16225,"depth":448,"text":16226},{"id":2593,"depth":448,"text":16263},{"id":17998,"depth":448,"text":17999},{"id":18036,"depth":189,"text":18037,"children":19123},[19124,19125],{"id":18063,"depth":448,"text":18064},{"id":18088,"depth":448,"text":18089},{"id":18154,"depth":189,"text":18155,"children":19127},[19128,19129],{"id":18158,"depth":448,"text":18159},{"id":18258,"depth":448,"text":18259},{"id":18315,"depth":189,"text":18316,"children":19131},[19132],{"id":18417,"depth":448,"text":18418},{"id":18452,"depth":189,"text":18453,"children":19134},[19135,19136],{"id":18463,"depth":448,"text":18464},{"id":18491,"depth":448,"text":18492},{"id":18521,"depth":189,"text":18522,"children":19138},[19139,19140],{"id":18528,"depth":448,"text":18529},{"id":18608,"depth":448,"text":18609},{"id":18638,"depth":189,"text":18639,"children":19142},[19143,19144],{"id":18645,"depth":448,"text":18646},{"id":18803,"depth":448,"text":18804},{"id":18935,"depth":189,"text":18936},{"id":18964,"depth":189,"text":18965,"children":19147},[19148],{"id":19030,"depth":448,"text":19149},"Exemple de .gitignore pour Node.js",{"id":19042,"depth":189,"text":19043},{"id":405,"depth":189,"text":406},"Découvrez GitHub, la plateforme incontournable pour héberger vos dépôts Git, collaborer en équipe et gérer vos projets open source ou privés.","/images/posts/2026/03/github-collaborer-et-gerer-vos-projets-avec-git.webp",{},"/posts/github-collaborer-et-gerer-vos-projets-avec-git",{"title":17929,"description":19152},"posts/github-collaborer-et-gerer-vos-projets-avec-git",[19159,9840,19160,10809],"github","collaboration","ECrfhAyHZWBxmOYhPtRPaKZ4wauqfhaMVKz2Nb2nzkM",{"id":19163,"title":19164,"author":12400,"body":19165,"date":15004,"description":20164,"extension":474,"image":20165,"meta":20166,"navigation":477,"path":20167,"readingTime":479,"seo":20168,"stem":20169,"tags":20170,"updatedAt":15004,"__hash__":20173},"posts/posts/intelligence-artificielle-et-llm-comprendre-les-modeles-de-langage.md","Intelligence artificielle et LLM : comprendre les modèles de langage",{"type":9,"value":19166,"toc":20129},[19167,19171,19177,19180,19206,19210,19214,19217,19223,19226,19237,19240,19247,19253,19256,19260,19271,19278,19282,19289,19293,19313,19317,19324,19330,19333,19337,19409,19413,19419,19430,19436,19447,19451,19455,19466,19470,19591,19595,19606,19610,19621,19625,19629,19763,19767,19882,19886,19928,19932,19936,19942,19948,19952,19957,19977,19981,19987,20021,20025,20031,20037,20040,20066,20070,20102,20106,20112,20118,20121,20123,20126],[12,19168,19170],{"id":19169},"quest-ce-que-lintelligence-artificielle","Qu'est-ce que l'intelligence artificielle ?",[17,19172,2637,19173,19176],{},[21,19174,19175],{},"intelligence artificielle"," (IA) est un domaine de l'informatique qui vise à créer des systèmes capables de réaliser des tâches nécessitant normalement l'intelligence humaine : comprendre le langage, reconnaître des images, prendre des décisions ou générer du contenu.",[17,19178,19179],{},"L'IA se décline en plusieurs sous-domaines :",[33,19181,19182,19188,19194,19200],{},[36,19183,19184,19187],{},[21,19185,19186],{},"Machine Learning (ML)"," — l'ordinateur apprend à partir de données",[36,19189,19190,19193],{},[21,19191,19192],{},"Deep Learning"," — apprentissage basé sur des réseaux de neurones profonds",[36,19195,19196,19199],{},[21,19197,19198],{},"NLP (Natural Language Processing)"," — traitement du langage naturel",[36,19201,19202,19205],{},[21,19203,19204],{},"Computer Vision"," — analyse et compréhension d'images",[12,19207,19209],{"id":19208},"du-machine-learning-aux-llm","Du Machine Learning aux LLM",[53,19211,19213],{"id":19212},"machine-learning","Machine Learning",[17,19215,19216],{},"Le Machine Learning repose sur l'idée d'entraîner un modèle sur des données pour qu'il puisse faire des prédictions :",[102,19218,19221],{"className":19219,"code":19220,"language":107},[105],"Données d'entraînement → Algorithme → Modèle → Prédictions\n",[109,19222,19220],{"__ignoreMap":111},[17,19224,19225],{},"Exemples classiques :",[33,19227,19228,19231,19234],{},[36,19229,19230],{},"Détection de spam dans les emails",[36,19232,19233],{},"Recommandation de produits",[36,19235,19236],{},"Prédiction de prix",[53,19238,19192],{"id":19239},"deep-learning",[17,19241,19242,19243,19246],{},"Le Deep Learning utilise des ",[21,19244,19245],{},"réseaux de neurones artificiels"," à plusieurs couches pour apprendre des représentations de plus en plus complexes des données.",[102,19248,19251],{"className":19249,"code":19250,"language":107},[105],"Entrée → [Couche 1] → [Couche 2] → ... → [Couche N] → Sortie\n",[109,19252,19250],{"__ignoreMap":111},[17,19254,19255],{},"C'est le Deep Learning qui a permis les avancées majeures en reconnaissance d'images, traduction automatique et génération de texte.",[53,19257,19259],{"id":19258},"les-transformers-la-révolution","Les Transformers : la révolution",[17,19261,19262,19263,19266,19267,19270],{},"En 2017, Google publie l'article ",[21,19264,19265],{},"\"Attention Is All You Need\""," qui introduit l'architecture ",[21,19268,19269],{},"Transformer",". Cette architecture est la base de tous les LLM modernes.",[17,19272,19273,19274,19277],{},"Le mécanisme clé est l'",[21,19275,19276],{},"attention"," : le modèle apprend à identifier quelles parties de l'entrée sont les plus pertinentes pour chaque partie de la sortie.",[12,19279,19281],{"id":19280},"quest-ce-quun-llm","Qu'est-ce qu'un LLM ?",[17,19283,19284,19285,19288],{},"Un ",[21,19286,19287],{},"Large Language Model"," (grand modèle de langage) est un réseau de neurones entraîné sur d'énormes quantités de texte pour comprendre et générer du langage naturel.",[53,19290,19292],{"id":19291},"comment-fonctionne-un-llm","Comment fonctionne un LLM ?",[79,19294,19295,19301,19307],{},[36,19296,19297,19300],{},[21,19298,19299],{},"Pré-entraînement"," — le modèle lit des milliards de textes et apprend les patterns du langage",[36,19302,19303,19306],{},[21,19304,19305],{},"Fine-tuning"," — le modèle est affiné sur des données spécifiques pour une tâche donnée",[36,19308,19309,19312],{},[21,19310,19311],{},"RLHF"," (Reinforcement Learning from Human Feedback) — des humains évaluent les réponses pour améliorer la qualité",[53,19314,19316],{"id":19315},"le-principe-de-la-prédiction","Le principe de la prédiction",[17,19318,19319,19320,19323],{},"Un LLM prédit le ",[21,19321,19322],{},"prochain mot"," (ou token) le plus probable dans une séquence :",[102,19325,19328],{"className":19326,"code":19327,"language":107},[105],"Entrée : \"Le soleil se couche sur la\"\nPrédiction : \"mer\" (probabilité: 0.23), \"ville\" (0.18), \"montagne\" (0.15)...\n",[109,19329,19327],{"__ignoreMap":111},[17,19331,19332],{},"C'est cette prédiction successive, mot après mot, qui permet de générer des textes cohérents.",[12,19334,19336],{"id":19335},"les-principaux-llm","Les principaux LLM",[1120,19338,19339,19352],{},[1123,19340,19341],{},[1126,19342,19343,19346,19349],{},[1129,19344,19345],{},"Modèle",[1129,19347,19348],{},"Créateur",[1129,19350,19351],{},"Caractéristiques",[1136,19353,19354,19365,19376,19387,19398],{},[1126,19355,19356,19359,19362],{},[1141,19357,19358],{},"GPT-4o",[1141,19360,19361],{},"OpenAI",[1141,19363,19364],{},"Multimodal, très performant",[1126,19366,19367,19370,19373],{},[1141,19368,19369],{},"Claude",[1141,19371,19372],{},"Anthropic",[1141,19374,19375],{},"Fiable, bon en raisonnement et en code",[1126,19377,19378,19381,19384],{},[1141,19379,19380],{},"Llama 3",[1141,19382,19383],{},"Meta",[1141,19385,19386],{},"Open source, exécutable en local",[1126,19388,19389,19392,19395],{},[1141,19390,19391],{},"Mistral",[1141,19393,19394],{},"Mistral AI",[1141,19396,19397],{},"Performant, entreprise française",[1126,19399,19400,19403,19406],{},[1141,19401,19402],{},"Gemini",[1141,19404,19405],{},"Google",[1141,19407,19408],{},"Multimodal, intégré à l'écosystème Google",[53,19410,19412],{"id":19411},"modèles-propriétaires-vs-open-source","Modèles propriétaires vs open source",[17,19414,19415,19418],{},[21,19416,19417],{},"Propriétaires"," (GPT-4o, Claude, Gemini) :",[33,19420,19421,19424,19427],{},[36,19422,19423],{},"Accessibles via API payante",[36,19425,19426],{},"Très performants",[36,19428,19429],{},"Données traitées sur des serveurs externes",[17,19431,19432,19435],{},[21,19433,19434],{},"Open source"," (Llama, Mistral) :",[33,19437,19438,19441,19444],{},[36,19439,19440],{},"Exécutables en local (avec Ollama par exemple)",[36,19442,19443],{},"Données restent privées",[36,19445,19446],{},"Personnalisables et fine-tunables",[12,19448,19450],{"id":19449},"cas-dusage-des-llm","Cas d'usage des LLM",[53,19452,19454],{"id":19453},"génération-de-texte","Génération de texte",[33,19456,19457,19460,19463],{},[36,19458,19459],{},"Rédaction d'articles, emails, résumés",[36,19461,19462],{},"Traduction automatique",[36,19464,19465],{},"Création de contenu marketing",[53,19467,19469],{"id":19468},"assistance-au-code","Assistance au code",[102,19471,19473],{"className":5626,"code":19472,"language":5622,"meta":111,"style":111},"# Un LLM peut générer du code à partir d'une description\n# Prompt : \"Fonction Python qui vérifie si un nombre est premier\"\n\ndef is_prime(n):\n    if n \u003C 2:\n        return False\n    for i in range(2, int(n**0.5) + 1):\n        if n % i == 0:\n            return False\n    return True\n",[109,19474,19475,19480,19485,19489,19500,19514,19521,19560,19578,19584],{"__ignoreMap":111},[179,19476,19477],{"class":181,"line":182},[179,19478,19479],{"class":185},"# Un LLM peut générer du code à partir d'une description\n",[179,19481,19482],{"class":181,"line":189},[179,19483,19484],{"class":185},"# Prompt : \"Fonction Python qui vérifie si un nombre est premier\"\n",[179,19486,19487],{"class":181,"line":448},[179,19488,1404],{"emptyLinePlaceholder":477},[179,19490,19491,19494,19497],{"class":181,"line":775},[179,19492,19493],{"class":549},"def",[179,19495,19496],{"class":192}," is_prime",[179,19498,19499],{"class":681},"(n):\n",[179,19501,19502,19504,19507,19509,19512],{"class":181,"line":852},[179,19503,13635],{"class":549},[179,19505,19506],{"class":681}," n ",[179,19508,4050],{"class":549},[179,19510,19511],{"class":224}," 2",[179,19513,4966],{"class":681},[179,19515,19516,19518],{"class":181,"line":1351},[179,19517,5284],{"class":549},[179,19519,19520],{"class":224}," False\n",[179,19522,19523,19526,19529,19531,19534,19536,19538,19540,19542,19545,19548,19551,19553,19555,19557],{"class":181,"line":1363},[179,19524,19525],{"class":549},"    for",[179,19527,19528],{"class":681}," i ",[179,19530,5797],{"class":549},[179,19532,19533],{"class":224}," range",[179,19535,3761],{"class":681},[179,19537,4457],{"class":224},[179,19539,5355],{"class":681},[179,19541,5728],{"class":224},[179,19543,19544],{"class":681},"(n",[179,19546,19547],{"class":549},"**",[179,19549,19550],{"class":224},"0.5",[179,19552,3836],{"class":681},[179,19554,5753],{"class":549},[179,19556,16208],{"class":224},[179,19558,19559],{"class":681},"):\n",[179,19561,19562,19564,19566,19569,19571,19574,19576],{"class":181,"line":1381},[179,19563,14087],{"class":549},[179,19565,19506],{"class":681},[179,19567,19568],{"class":549},"%",[179,19570,19528],{"class":681},[179,19572,19573],{"class":549},"==",[179,19575,13962],{"class":224},[179,19577,4966],{"class":681},[179,19579,19580,19582],{"class":181,"line":1401},[179,19581,5300],{"class":549},[179,19583,19520],{"class":224},[179,19585,19586,19588],{"class":181,"line":1407},[179,19587,6695],{"class":549},[179,19589,19590],{"class":224}," True\n",[53,19592,19594],{"id":19593},"analyse-et-extraction","Analyse et extraction",[33,19596,19597,19600,19603],{},[36,19598,19599],{},"Résumer de longs documents",[36,19601,19602],{},"Extraire des informations structurées d'un texte",[36,19604,19605],{},"Classifier des données (sentiments, catégories)",[53,19607,19609],{"id":19608},"chatbots-et-assistants","Chatbots et assistants",[33,19611,19612,19615,19618],{},[36,19613,19614],{},"Support client automatisé",[36,19616,19617],{},"Assistants virtuels personnalisés",[36,19619,19620],{},"FAQ intelligentes",[12,19622,19624],{"id":19623},"utiliser-les-llm-en-pratique","Utiliser les LLM en pratique",[53,19626,19628],{"id":19627},"via-une-api-exemple-avec-claude","Via une API (exemple avec Claude)",[102,19630,19632],{"className":5626,"code":19631,"language":5622,"meta":111,"style":111},"import anthropic\n\nclient = anthropic.Anthropic(api_key=\"votre-clé\")\n\nmessage = client.messages.create(\n    model=\"claude-sonnet-4-20250514\",\n    max_tokens=1024,\n    messages=[\n        {\"role\": \"user\", \"content\": \"Explique le machine learning simplement.\"}\n    ]\n)\n\nprint(message.content[0].text)\n",[109,19633,19634,19641,19645,19665,19669,19679,19691,19702,19712,19737,19742,19746,19750],{"__ignoreMap":111},[179,19635,19636,19638],{"class":181,"line":182},[179,19637,5455],{"class":549},[179,19639,19640],{"class":681}," anthropic\n",[179,19642,19643],{"class":181,"line":189},[179,19644,1404],{"emptyLinePlaceholder":477},[179,19646,19647,19650,19652,19655,19658,19660,19663],{"class":181,"line":448},[179,19648,19649],{"class":681},"client ",[179,19651,685],{"class":549},[179,19653,19654],{"class":681}," anthropic.Anthropic(",[179,19656,19657],{"class":3802},"api_key",[179,19659,685],{"class":549},[179,19661,19662],{"class":196},"\"votre-clé\"",[179,19664,1480],{"class":681},[179,19666,19667],{"class":181,"line":775},[179,19668,1404],{"emptyLinePlaceholder":477},[179,19670,19671,19674,19676],{"class":181,"line":852},[179,19672,19673],{"class":681},"message ",[179,19675,685],{"class":549},[179,19677,19678],{"class":681}," client.messages.create(\n",[179,19680,19681,19684,19686,19689],{"class":181,"line":1351},[179,19682,19683],{"class":3802},"    model",[179,19685,685],{"class":549},[179,19687,19688],{"class":196},"\"claude-sonnet-4-20250514\"",[179,19690,4864],{"class":681},[179,19692,19693,19696,19698,19700],{"class":181,"line":1363},[179,19694,19695],{"class":3802},"    max_tokens",[179,19697,685],{"class":549},[179,19699,1723],{"class":224},[179,19701,4864],{"class":681},[179,19703,19704,19707,19709],{"class":181,"line":1381},[179,19705,19706],{"class":3802},"    messages",[179,19708,685],{"class":549},[179,19710,19711],{"class":681},"[\n",[179,19713,19714,19717,19720,19722,19725,19727,19730,19732,19735],{"class":181,"line":1401},[179,19715,19716],{"class":681},"        {",[179,19718,19719],{"class":196},"\"role\"",[179,19721,4251],{"class":681},[179,19723,19724],{"class":196},"\"user\"",[179,19726,5355],{"class":681},[179,19728,19729],{"class":196},"\"content\"",[179,19731,4251],{"class":681},[179,19733,19734],{"class":196},"\"Explique le machine learning simplement.\"",[179,19736,3814],{"class":681},[179,19738,19739],{"class":181,"line":1407},[179,19740,19741],{"class":681},"    ]\n",[179,19743,19744],{"class":181,"line":1418},[179,19745,1480],{"class":681},[179,19747,19748],{"class":181,"line":1435},[179,19749,1404],{"emptyLinePlaceholder":477},[179,19751,19752,19755,19758,19760],{"class":181,"line":1440},[179,19753,19754],{"class":224},"print",[179,19756,19757],{"class":681},"(message.content[",[179,19759,4443],{"class":224},[179,19761,19762],{"class":681},"].text)\n",[53,19764,19766],{"id":19765},"via-une-api-exemple-avec-openai","Via une API (exemple avec OpenAI)",[102,19768,19770],{"className":5626,"code":19769,"language":5622,"meta":111,"style":111},"from openai import OpenAI\n\nclient = OpenAI(api_key=\"votre-clé\")\n\nresponse = client.chat.completions.create(\n    model=\"gpt-4o\",\n    messages=[\n        {\"role\": \"user\", \"content\": \"Explique le machine learning simplement.\"}\n    ]\n)\n\nprint(response.choices[0].message.content)\n",[109,19771,19772,19784,19788,19805,19809,19819,19830,19838,19858,19862,19866,19870],{"__ignoreMap":111},[179,19773,19774,19776,19779,19781],{"class":181,"line":182},[179,19775,5634],{"class":549},[179,19777,19778],{"class":681}," openai ",[179,19780,5455],{"class":549},[179,19782,19783],{"class":681}," OpenAI\n",[179,19785,19786],{"class":181,"line":189},[179,19787,1404],{"emptyLinePlaceholder":477},[179,19789,19790,19792,19794,19797,19799,19801,19803],{"class":181,"line":448},[179,19791,19649],{"class":681},[179,19793,685],{"class":549},[179,19795,19796],{"class":681}," OpenAI(",[179,19798,19657],{"class":3802},[179,19800,685],{"class":549},[179,19802,19662],{"class":196},[179,19804,1480],{"class":681},[179,19806,19807],{"class":181,"line":775},[179,19808,1404],{"emptyLinePlaceholder":477},[179,19810,19811,19814,19816],{"class":181,"line":852},[179,19812,19813],{"class":681},"response ",[179,19815,685],{"class":549},[179,19817,19818],{"class":681}," client.chat.completions.create(\n",[179,19820,19821,19823,19825,19828],{"class":181,"line":1351},[179,19822,19683],{"class":3802},[179,19824,685],{"class":549},[179,19826,19827],{"class":196},"\"gpt-4o\"",[179,19829,4864],{"class":681},[179,19831,19832,19834,19836],{"class":181,"line":1363},[179,19833,19706],{"class":3802},[179,19835,685],{"class":549},[179,19837,19711],{"class":681},[179,19839,19840,19842,19844,19846,19848,19850,19852,19854,19856],{"class":181,"line":1381},[179,19841,19716],{"class":681},[179,19843,19719],{"class":196},[179,19845,4251],{"class":681},[179,19847,19724],{"class":196},[179,19849,5355],{"class":681},[179,19851,19729],{"class":196},[179,19853,4251],{"class":681},[179,19855,19734],{"class":196},[179,19857,3814],{"class":681},[179,19859,19860],{"class":181,"line":1401},[179,19861,19741],{"class":681},[179,19863,19864],{"class":181,"line":1407},[179,19865,1480],{"class":681},[179,19867,19868],{"class":181,"line":1418},[179,19869,1404],{"emptyLinePlaceholder":477},[179,19871,19872,19874,19877,19879],{"class":181,"line":1435},[179,19873,19754],{"class":224},[179,19875,19876],{"class":681},"(response.choices[",[179,19878,4443],{"class":224},[179,19880,19881],{"class":681},"].message.content)\n",[53,19883,19885],{"id":19884},"en-local-avec-ollama","En local avec Ollama",[102,19887,19889],{"className":173,"code":19888,"language":175,"meta":111,"style":111},"# Installer Ollama\ncurl -fsSL https://ollama.com/install.sh | sh\n\n# Lancer un modèle\nollama run llama3\n",[109,19890,19891,19896,19909,19913,19918],{"__ignoreMap":111},[179,19892,19893],{"class":181,"line":182},[179,19894,19895],{"class":185},"# Installer Ollama\n",[179,19897,19898,19900,19902,19905,19907],{"class":181,"line":189},[179,19899,540],{"class":192},[179,19901,543],{"class":224},[179,19903,19904],{"class":196}," https://ollama.com/install.sh",[179,19906,550],{"class":549},[179,19908,15061],{"class":192},[179,19910,19911],{"class":181,"line":448},[179,19912,1404],{"emptyLinePlaceholder":477},[179,19914,19915],{"class":181,"line":775},[179,19916,19917],{"class":185},"# Lancer un modèle\n",[179,19919,19920,19923,19925],{"class":181,"line":852},[179,19921,19922],{"class":192},"ollama",[179,19924,8377],{"class":196},[179,19926,19927],{"class":196}," llama3\n",[12,19929,19931],{"id":19930},"les-concepts-clés","Les concepts clés",[53,19933,19935],{"id":19934},"tokens","Tokens",[17,19937,19938,19939,19941],{},"Les LLM ne lisent pas des mots mais des ",[21,19940,19934],{}," — des fragments de mots. En moyenne, 1 token ≈ 0,75 mot en français.",[102,19943,19946],{"className":19944,"code":19945,"language":107},[105],"\"Bonjour le monde\" → [\"Bon\", \"jour\", \" le\", \" monde\"] → 4 tokens\n",[109,19947,19945],{"__ignoreMap":111},[53,19949,19951],{"id":19950},"température","Température",[17,19953,2630,19954,19956],{},[21,19955,19950],{}," contrôle la créativité du modèle :",[33,19958,19959,19965,19971],{},[36,19960,19961,19964],{},[109,19962,19963],{},"0.0"," — réponses déterministes et factuelles",[36,19966,19967,19970],{},[109,19968,19969],{},"0.7"," — bon équilibre créativité/cohérence",[36,19972,19973,19976],{},[109,19974,19975],{},"1.0+"," — réponses plus créatives mais moins prévisibles",[53,19978,19980],{"id":19979},"contexte-context-window","Contexte (context window)",[17,19982,2630,19983,19986],{},[21,19984,19985],{},"fenêtre de contexte"," est le nombre maximum de tokens que le modèle peut traiter en une seule fois :",[1120,19988,19989,19998],{},[1123,19990,19991],{},[1126,19992,19993,19995],{},[1129,19994,19345],{},[1129,19996,19997],{},"Fenêtre de contexte",[1136,19999,20000,20007,20014],{},[1126,20001,20002,20004],{},[1141,20003,19358],{},[1141,20005,20006],{},"128K tokens",[1126,20008,20009,20011],{},[1141,20010,19369],{},[1141,20012,20013],{},"200K tokens",[1126,20015,20016,20018],{},[1141,20017,19380],{},[1141,20019,20020],{},"8K - 128K tokens",[53,20022,20024],{"id":20023},"prompt-engineering","Prompt engineering",[17,20026,1067,20027,20030],{},[21,20028,20029],{},"prompt engineering"," est l'art de formuler des instructions efficaces pour un LLM :",[102,20032,20035],{"className":20033,"code":20034,"language":107},[105],"❌ Mauvais prompt :\n\"Parle-moi de Python\"\n\n✅ Bon prompt :\n\"Explique les 5 structures de données les plus utilisées en Python,\navec un exemple de code pour chacune. Niveau débutant.\"\n",[109,20036,20034],{"__ignoreMap":111},[17,20038,20039],{},"Techniques courantes :",[33,20041,20042,20048,20054,20060],{},[36,20043,20044,20047],{},[21,20045,20046],{},"Zero-shot"," — poser la question directement",[36,20049,20050,20053],{},[21,20051,20052],{},"Few-shot"," — donner des exemples avant la question",[36,20055,20056,20059],{},[21,20057,20058],{},"Chain of thought"," — demander au modèle de raisonner étape par étape",[36,20061,20062,20065],{},[21,20063,20064],{},"System prompt"," — définir le rôle et le comportement du modèle",[12,20067,20069],{"id":20068},"les-limites-des-llm","Les limites des LLM",[33,20071,20072,20078,20084,20090,20096],{},[36,20073,20074,20077],{},[21,20075,20076],{},"Hallucinations"," — le modèle peut inventer des informations fausses avec assurance",[36,20079,20080,20083],{},[21,20081,20082],{},"Données obsolètes"," — les connaissances s'arrêtent à la date d'entraînement",[36,20085,20086,20089],{},[21,20087,20088],{},"Biais"," — le modèle reflète les biais présents dans ses données d'entraînement",[36,20091,20092,20095],{},[21,20093,20094],{},"Coût"," — les modèles les plus performants sont coûteux à utiliser à grande échelle",[36,20097,20098,20101],{},[21,20099,20100],{},"Confidentialité"," — attention aux données sensibles envoyées à des APIs externes",[12,20103,20105],{"id":20104},"rag-augmenter-les-llm-avec-vos-données","RAG : augmenter les LLM avec vos données",[17,20107,1067,20108,20111],{},[21,20109,20110],{},"RAG"," (Retrieval-Augmented Generation) permet de combiner un LLM avec une base de connaissances externe :",[102,20113,20116],{"className":20114,"code":20115,"language":107},[105],"1. L'utilisateur pose une question\n2. Le système recherche les documents pertinents dans votre base\n3. Les documents trouvés sont envoyés au LLM comme contexte\n4. Le LLM génère une réponse basée sur vos données\n",[109,20117,20115],{"__ignoreMap":111},[17,20119,20120],{},"C'est la solution idéale pour créer un assistant qui connaît votre documentation, vos produits ou vos processus internes.",[12,20122,406],{"id":405},[17,20124,20125],{},"Les LLM représentent une avancée majeure en intelligence artificielle. Ils transforment la façon dont nous interagissons avec la technologie — de la génération de code à l'analyse de documents. Comprendre leur fonctionnement, leurs capacités et leurs limites est devenu essentiel pour tout développeur souhaitant les intégrer efficacement dans ses projets.",[438,20127,20128],{},"html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}",{"title":111,"searchDepth":189,"depth":189,"links":20130},[20131,20132,20137,20141,20144,20150,20155,20161,20162,20163],{"id":19169,"depth":189,"text":19170},{"id":19208,"depth":189,"text":19209,"children":20133},[20134,20135,20136],{"id":19212,"depth":448,"text":19213},{"id":19239,"depth":448,"text":19192},{"id":19258,"depth":448,"text":19259},{"id":19280,"depth":189,"text":19281,"children":20138},[20139,20140],{"id":19291,"depth":448,"text":19292},{"id":19315,"depth":448,"text":19316},{"id":19335,"depth":189,"text":19336,"children":20142},[20143],{"id":19411,"depth":448,"text":19412},{"id":19449,"depth":189,"text":19450,"children":20145},[20146,20147,20148,20149],{"id":19453,"depth":448,"text":19454},{"id":19468,"depth":448,"text":19469},{"id":19593,"depth":448,"text":19594},{"id":19608,"depth":448,"text":19609},{"id":19623,"depth":189,"text":19624,"children":20151},[20152,20153,20154],{"id":19627,"depth":448,"text":19628},{"id":19765,"depth":448,"text":19766},{"id":19884,"depth":448,"text":19885},{"id":19930,"depth":189,"text":19931,"children":20156},[20157,20158,20159,20160],{"id":19934,"depth":448,"text":19935},{"id":19950,"depth":448,"text":19951},{"id":19979,"depth":448,"text":19980},{"id":20023,"depth":448,"text":20024},{"id":20068,"depth":189,"text":20069},{"id":20104,"depth":189,"text":20105},{"id":405,"depth":189,"text":406},"Découvrez les fondamentaux de l'intelligence artificielle et des grands modèles de langage (LLM) : fonctionnement, cas d'usage, outils et bonnes pratiques.","/images/posts/2026/03/intelligence-artificielle-et-llm-comprendre-les-modeles-de-langage.webp",{},"/posts/intelligence-artificielle-et-llm-comprendre-les-modeles-de-langage",{"title":19164,"description":20164},"posts/intelligence-artificielle-et-llm-comprendre-les-modeles-de-langage",[20171,20172,19212,19239,10809],"ia","llm","_KeplvNV8zzd5y7o0YeHU1Z3AQH665XE0l_E3hmgKoI",{"id":20175,"title":20176,"author":12400,"body":20177,"date":15004,"description":20785,"extension":474,"image":20786,"meta":20787,"navigation":477,"path":20788,"readingTime":479,"seo":20789,"stem":20790,"tags":20791,"updatedAt":15004,"__hash__":20793},"posts/posts/ollama-executer-des-modeles-ia-en-local-facilement.md","Ollama : exécuter des modèles IA en local facilement",{"type":9,"value":20178,"toc":20767},[20179,20183,20189,20192,20194,20198,20215,20217,20225,20227,20238,20242,20245,20299,20302,20304,20373,20377,20383,20420,20424,20462,20466,20558,20562,20568,20616,20619,20647,20651,20732,20736,20756,20759,20761,20764],[12,20180,20182],{"id":20181},"quest-ce-quollama","Qu'est-ce qu'Ollama ?",[17,20184,20185,20188],{},[21,20186,20187],{},"Ollama"," est un outil open source qui permet d'exécuter des modèles de langage (LLM) directement sur votre machine locale. Plus besoin de dépendre d'APIs cloud payantes ou d'une connexion internet — vos données restent chez vous.",[17,20190,20191],{},"Ollama simplifie considérablement le processus d'installation et d'utilisation des LLM en fournissant une interface en ligne de commande intuitive et une API REST locale.",[12,20193,15039],{"id":15038},[53,20195,20197],{"id":20196},"linux-et-macos","Linux et macOS",[102,20199,20201],{"className":173,"code":20200,"language":175,"meta":111,"style":111},"curl -fsSL https://ollama.com/install.sh | sh\n",[109,20202,20203],{"__ignoreMap":111},[179,20204,20205,20207,20209,20211,20213],{"class":181,"line":182},[179,20206,540],{"class":192},[179,20208,543],{"class":224},[179,20210,19904],{"class":196},[179,20212,550],{"class":549},[179,20214,15061],{"class":192},[53,20216,16263],{"id":2593},[17,20218,20219,20220,436],{},"Téléchargez l'installateur depuis le ",[730,20221,20224],{"href":20222,"rel":20223},"https://ollama.com/download",[734],"site officiel d'Ollama",[53,20226,15095],{"id":15094},[102,20228,20230],{"className":173,"code":20229,"language":175,"meta":111,"style":111},"ollama --version\n",[109,20231,20232],{"__ignoreMap":111},[179,20233,20234,20236],{"class":181,"line":182},[179,20235,19922],{"class":192},[179,20237,8370],{"class":224},[12,20239,20241],{"id":20240},"télécharger-et-exécuter-un-modèle","Télécharger et exécuter un modèle",[17,20243,20244],{},"Ollama propose un large catalogue de modèles. Pour télécharger et lancer un modèle :",[102,20246,20248],{"className":173,"code":20247,"language":175,"meta":111,"style":111},"# Télécharger et lancer Llama 3\nollama run llama3\n\n# Télécharger et lancer Mistral\nollama run mistral\n\n# Télécharger et lancer un modèle plus léger\nollama run phi3\n",[109,20249,20250,20255,20263,20267,20272,20281,20285,20290],{"__ignoreMap":111},[179,20251,20252],{"class":181,"line":182},[179,20253,20254],{"class":185},"# Télécharger et lancer Llama 3\n",[179,20256,20257,20259,20261],{"class":181,"line":189},[179,20258,19922],{"class":192},[179,20260,8377],{"class":196},[179,20262,19927],{"class":196},[179,20264,20265],{"class":181,"line":448},[179,20266,1404],{"emptyLinePlaceholder":477},[179,20268,20269],{"class":181,"line":775},[179,20270,20271],{"class":185},"# Télécharger et lancer Mistral\n",[179,20273,20274,20276,20278],{"class":181,"line":852},[179,20275,19922],{"class":192},[179,20277,8377],{"class":196},[179,20279,20280],{"class":196}," mistral\n",[179,20282,20283],{"class":181,"line":1351},[179,20284,1404],{"emptyLinePlaceholder":477},[179,20286,20287],{"class":181,"line":1363},[179,20288,20289],{"class":185},"# Télécharger et lancer un modèle plus léger\n",[179,20291,20292,20294,20296],{"class":181,"line":1381},[179,20293,19922],{"class":192},[179,20295,8377],{"class":196},[179,20297,20298],{"class":196}," phi3\n",[17,20300,20301],{},"La première exécution télécharge le modèle. Les lancements suivants sont quasi instantanés.",[12,20303,15152],{"id":9081},[102,20305,20307],{"className":173,"code":20306,"language":175,"meta":111,"style":111},"# Lister les modèles installés\nollama list\n\n# Télécharger un modèle sans le lancer\nollama pull llama3\n\n# Supprimer un modèle\nollama rm llama3\n\n# Afficher les informations d'un modèle\nollama show llama3\n",[109,20308,20309,20314,20321,20325,20330,20338,20342,20347,20355,20359,20364],{"__ignoreMap":111},[179,20310,20311],{"class":181,"line":182},[179,20312,20313],{"class":185},"# Lister les modèles installés\n",[179,20315,20316,20318],{"class":181,"line":189},[179,20317,19922],{"class":192},[179,20319,20320],{"class":196}," list\n",[179,20322,20323],{"class":181,"line":448},[179,20324,1404],{"emptyLinePlaceholder":477},[179,20326,20327],{"class":181,"line":775},[179,20328,20329],{"class":185},"# Télécharger un modèle sans le lancer\n",[179,20331,20332,20334,20336],{"class":181,"line":852},[179,20333,19922],{"class":192},[179,20335,15335],{"class":196},[179,20337,19927],{"class":196},[179,20339,20340],{"class":181,"line":1351},[179,20341,1404],{"emptyLinePlaceholder":477},[179,20343,20344],{"class":181,"line":1363},[179,20345,20346],{"class":185},"# Supprimer un modèle\n",[179,20348,20349,20351,20353],{"class":181,"line":1381},[179,20350,19922],{"class":192},[179,20352,15272],{"class":196},[179,20354,19927],{"class":196},[179,20356,20357],{"class":181,"line":1401},[179,20358,1404],{"emptyLinePlaceholder":477},[179,20360,20361],{"class":181,"line":1407},[179,20362,20363],{"class":185},"# Afficher les informations d'un modèle\n",[179,20365,20366,20368,20371],{"class":181,"line":1418},[179,20367,19922],{"class":192},[179,20369,20370],{"class":196}," show",[179,20372,19927],{"class":196},[12,20374,20376],{"id":20375},"utiliser-lapi-rest","Utiliser l'API REST",[17,20378,20379,20380,642],{},"Ollama expose une API REST locale sur le port ",[109,20381,20382],{},"11434",[102,20384,20386],{"className":173,"code":20385,"language":175,"meta":111,"style":111},"# Générer une réponse\ncurl http://localhost:11434/api/generate -d '{\n  \"model\": \"llama3\",\n  \"prompt\": \"Explique-moi le machine learning en 3 phrases.\"\n}'\n",[109,20387,20388,20393,20405,20410,20415],{"__ignoreMap":111},[179,20389,20390],{"class":181,"line":182},[179,20391,20392],{"class":185},"# Générer une réponse\n",[179,20394,20395,20397,20400,20402],{"class":181,"line":189},[179,20396,540],{"class":192},[179,20398,20399],{"class":196}," http://localhost:11434/api/generate",[179,20401,9050],{"class":224},[179,20403,20404],{"class":196}," '{\n",[179,20406,20407],{"class":181,"line":448},[179,20408,20409],{"class":196},"  \"model\": \"llama3\",\n",[179,20411,20412],{"class":181,"line":775},[179,20413,20414],{"class":196},"  \"prompt\": \"Explique-moi le machine learning en 3 phrases.\"\n",[179,20416,20417],{"class":181,"line":852},[179,20418,20419],{"class":196},"}'\n",[53,20421,20423],{"id":20422},"exemple-avec-un-chat","Exemple avec un chat",[102,20425,20427],{"className":173,"code":20426,"language":175,"meta":111,"style":111},"curl http://localhost:11434/api/chat -d '{\n  \"model\": \"llama3\",\n  \"messages\": [\n    { \"role\": \"user\", \"content\": \"Bonjour, comment ça va ?\" }\n  ]\n}'\n",[109,20428,20429,20440,20444,20449,20454,20458],{"__ignoreMap":111},[179,20430,20431,20433,20436,20438],{"class":181,"line":182},[179,20432,540],{"class":192},[179,20434,20435],{"class":196}," http://localhost:11434/api/chat",[179,20437,9050],{"class":224},[179,20439,20404],{"class":196},[179,20441,20442],{"class":181,"line":189},[179,20443,20409],{"class":196},[179,20445,20446],{"class":181,"line":448},[179,20447,20448],{"class":196},"  \"messages\": [\n",[179,20450,20451],{"class":181,"line":775},[179,20452,20453],{"class":196},"    { \"role\": \"user\", \"content\": \"Bonjour, comment ça va ?\" }\n",[179,20455,20456],{"class":181,"line":852},[179,20457,7310],{"class":196},[179,20459,20460],{"class":181,"line":1351},[179,20461,20419],{"class":196},[53,20463,20465],{"id":20464},"intégration-avec-python","Intégration avec Python",[102,20467,20469],{"className":5626,"code":20468,"language":5622,"meta":111,"style":111},"import requests\n\nresponse = requests.post(\"http://localhost:11434/api/generate\", json={\n    \"model\": \"llama3\",\n    \"prompt\": \"Qu'est-ce que le deep learning ?\",\n    \"stream\": False\n})\n\nprint(response.json()[\"response\"])\n",[109,20470,20471,20478,20482,20502,20514,20526,20536,20541,20545],{"__ignoreMap":111},[179,20472,20473,20475],{"class":181,"line":182},[179,20474,5455],{"class":549},[179,20476,20477],{"class":681}," requests\n",[179,20479,20480],{"class":181,"line":189},[179,20481,1404],{"emptyLinePlaceholder":477},[179,20483,20484,20486,20488,20491,20494,20496,20498,20500],{"class":181,"line":448},[179,20485,19813],{"class":681},[179,20487,685],{"class":549},[179,20489,20490],{"class":681}," requests.post(",[179,20492,20493],{"class":196},"\"http://localhost:11434/api/generate\"",[179,20495,5355],{"class":681},[179,20497,3783],{"class":3802},[179,20499,685],{"class":549},[179,20501,4851],{"class":681},[179,20503,20504,20507,20509,20512],{"class":181,"line":775},[179,20505,20506],{"class":196},"    \"model\"",[179,20508,4251],{"class":681},[179,20510,20511],{"class":196},"\"llama3\"",[179,20513,4864],{"class":681},[179,20515,20516,20519,20521,20524],{"class":181,"line":852},[179,20517,20518],{"class":196},"    \"prompt\"",[179,20520,4251],{"class":681},[179,20522,20523],{"class":196},"\"Qu'est-ce que le deep learning ?\"",[179,20525,4864],{"class":681},[179,20527,20528,20531,20533],{"class":181,"line":1351},[179,20529,20530],{"class":196},"    \"stream\"",[179,20532,4251],{"class":681},[179,20534,20535],{"class":224},"False\n",[179,20537,20538],{"class":181,"line":1363},[179,20539,20540],{"class":681},"})\n",[179,20542,20543],{"class":181,"line":1381},[179,20544,1404],{"emptyLinePlaceholder":477},[179,20546,20547,20549,20552,20555],{"class":181,"line":1401},[179,20548,19754],{"class":224},[179,20550,20551],{"class":681},"(response.json()[",[179,20553,20554],{"class":196},"\"response\"",[179,20556,20557],{"class":681},"])\n",[12,20559,20561],{"id":20560},"créer-un-modèle-personnalisé","Créer un modèle personnalisé",[17,20563,20564,20565,642],{},"Vous pouvez créer un modèle avec un prompt système personnalisé via un ",[21,20566,20567],{},"Modelfile",[102,20569,20571],{"className":15404,"code":20570,"language":15406,"meta":111,"style":111},"FROM llama3\n\nSYSTEM \"\"\"\nTu es un assistant spécialisé en développement web.\nTu réponds toujours en français.\nTu donnes des exemples de code quand c'est pertinent.\n\"\"\"\n\nPARAMETER temperature 0.7\n",[109,20572,20573,20578,20582,20587,20592,20597,20602,20607,20611],{"__ignoreMap":111},[179,20574,20575],{"class":181,"line":182},[179,20576,20577],{},"FROM llama3\n",[179,20579,20580],{"class":181,"line":189},[179,20581,1404],{"emptyLinePlaceholder":477},[179,20583,20584],{"class":181,"line":448},[179,20585,20586],{},"SYSTEM \"\"\"\n",[179,20588,20589],{"class":181,"line":775},[179,20590,20591],{},"Tu es un assistant spécialisé en développement web.\n",[179,20593,20594],{"class":181,"line":852},[179,20595,20596],{},"Tu réponds toujours en français.\n",[179,20598,20599],{"class":181,"line":1351},[179,20600,20601],{},"Tu donnes des exemples de code quand c'est pertinent.\n",[179,20603,20604],{"class":181,"line":1363},[179,20605,20606],{},"\"\"\"\n",[179,20608,20609],{"class":181,"line":1381},[179,20610,1404],{"emptyLinePlaceholder":477},[179,20612,20613],{"class":181,"line":1401},[179,20614,20615],{},"PARAMETER temperature 0.7\n",[17,20617,20618],{},"Puis construisez et utilisez votre modèle :",[102,20620,20622],{"className":173,"code":20621,"language":175,"meta":111,"style":111},"ollama create mon-assistant -f Modelfile\nollama run mon-assistant\n",[109,20623,20624,20638],{"__ignoreMap":111},[179,20625,20626,20628,20630,20633,20635],{"class":181,"line":182},[179,20627,19922],{"class":192},[179,20629,15892],{"class":196},[179,20631,20632],{"class":196}," mon-assistant",[179,20634,12185],{"class":224},[179,20636,20637],{"class":196}," Modelfile\n",[179,20639,20640,20642,20644],{"class":181,"line":189},[179,20641,19922],{"class":192},[179,20643,8377],{"class":196},[179,20645,20646],{"class":196}," mon-assistant\n",[12,20648,20650],{"id":20649},"modèles-recommandés","Modèles recommandés",[1120,20652,20653,20665],{},[1123,20654,20655],{},[1126,20656,20657,20659,20662],{},[1129,20658,19345],{},[1129,20660,20661],{},"Taille",[1129,20663,20664],{},"Usage recommandé",[1136,20666,20667,20680,20693,20706,20719],{},[1126,20668,20669,20674,20677],{},[1141,20670,20671],{},[109,20672,20673],{},"llama3",[1141,20675,20676],{},"4.7 Go",[1141,20678,20679],{},"Usage général, bonne qualité",[1126,20681,20682,20687,20690],{},[1141,20683,20684],{},[109,20685,20686],{},"mistral",[1141,20688,20689],{},"4.1 Go",[1141,20691,20692],{},"Rapide, bon en français",[1126,20694,20695,20700,20703],{},[1141,20696,20697],{},[109,20698,20699],{},"phi3",[1141,20701,20702],{},"2.3 Go",[1141,20704,20705],{},"Léger, idéal pour les petites machines",[1126,20707,20708,20713,20716],{},[1141,20709,20710],{},[109,20711,20712],{},"codellama",[1141,20714,20715],{},"3.8 Go",[1141,20717,20718],{},"Génération et analyse de code",[1126,20720,20721,20726,20729],{},[1141,20722,20723],{},[109,20724,20725],{},"llama3:70b",[1141,20727,20728],{},"40 Go",[1141,20730,20731],{},"Haute qualité, nécessite un GPU puissant",[12,20733,20735],{"id":20734},"configuration-matérielle","Configuration matérielle",[33,20737,20738,20744,20750],{},[36,20739,20740,20743],{},[21,20741,20742],{},"Minimum :"," 8 Go de RAM, CPU moderne",[36,20745,20746,20749],{},[21,20747,20748],{},"Recommandé :"," 16 Go de RAM, GPU avec 8 Go+ de VRAM",[36,20751,20752,20755],{},[21,20753,20754],{},"Optimal :"," 32 Go+ de RAM, GPU NVIDIA avec 16 Go+ de VRAM",[17,20757,20758],{},"Ollama détecte automatiquement votre GPU (NVIDIA, AMD, Apple Silicon) et l'utilise si disponible.",[12,20760,406],{"id":405},[17,20762,20763],{},"Ollama rend l'IA locale accessible à tous. En quelques commandes, vous pouvez exécuter des modèles performants sur votre propre machine, garder vos données privées et expérimenter librement sans frais d'API. C'est un outil incontournable pour tout développeur qui souhaite intégrer l'IA dans ses projets.",[438,20765,20766],{},"html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}",{"title":111,"searchDepth":189,"depth":189,"links":20768},[20769,20770,20775,20776,20777,20781,20782,20783,20784],{"id":20181,"depth":189,"text":20182},{"id":15038,"depth":189,"text":15039,"children":20771},[20772,20773,20774],{"id":20196,"depth":448,"text":20197},{"id":2593,"depth":448,"text":16263},{"id":15094,"depth":448,"text":15095},{"id":20240,"depth":189,"text":20241},{"id":9081,"depth":189,"text":15152},{"id":20375,"depth":189,"text":20376,"children":20778},[20779,20780],{"id":20422,"depth":448,"text":20423},{"id":20464,"depth":448,"text":20465},{"id":20560,"depth":189,"text":20561},{"id":20649,"depth":189,"text":20650},{"id":20734,"depth":189,"text":20735},{"id":405,"depth":189,"text":406},"Découvrez Ollama, l'outil open source qui permet d'exécuter des modèles de langage (LLM) en local sur votre machine, sans connexion internet ni API payante.","/images/posts/2026/03/ollama-executer-des-modeles-ia-en-local-facilement.webp",{},"/posts/ollama-executer-des-modeles-ia-en-local-facilement",{"title":20176,"description":20785},"posts/ollama-executer-des-modeles-ia-en-local-facilement",[20171,19922,20172,20792,10809],"open-source","QgGZ2PqKkDO1YePTDJWuwchIYVSq12St8cVJyuYmeT4",{"id":20795,"title":20796,"author":7,"body":20797,"date":22347,"description":22348,"extension":474,"image":22349,"meta":22350,"navigation":477,"path":22351,"readingTime":479,"seo":22352,"stem":22353,"tags":22354,"updatedAt":22347,"__hash__":22357},"posts/posts/git-worktree-travailler-sur-plusieurs-branches-simultanement.md","Git Worktree : travailler sur plusieurs branches simultanément",{"type":9,"value":20798,"toc":22309},[20799,20801,20812,20822,20826,20829,20872,20875,20901,20905,20911,20942,20948,20955,20957,20961,21073,21076,21080,21093,21096,21102,21106,21149,21153,21160,21173,21177,21180,21191,21197,21206,21220,21244,21248,21252,21255,21378,21388,21392,21395,21494,21498,21501,21557,21561,21564,21634,21638,21641,21681,21685,21688,21692,21699,21722,21725,21731,21753,21757,21770,21780,21786,21791,21795,21849,21854,21881,21883,21887,21890,21927,21931,21934,21974,21978,21981,22036,22040,22043,22130,22134,22138,22141,22152,22155,22159,22162,22166,22257,22259,22271,22274,22299,22306],[12,20800,15],{"id":14},[17,20802,20803,20804,20807,20808,20811],{},"Vous êtes en plein développement d'une feature quand on vous demande de corriger un bug urgent en production. Que faites-vous ? ",[109,20805,20806],{},"git stash",", switch de branche, fix, commit, re-switch, ",[109,20809,20810],{},"git stash pop","... et parfois, des conflits au passage.",[17,20813,20814,20817,20818,20821],{},[21,20815,20816],{},"Git worktree"," résout élégamment ce problème. Cette fonctionnalité native de Git (depuis la version 2.5) permet de ",[21,20819,20820],{},"travailler sur plusieurs branches simultanément",", chacune dans son propre répertoire, sans jamais quitter votre travail en cours.",[12,20823,20825],{"id":20824},"le-problème-sans-worktree","Le problème sans worktree",[17,20827,20828],{},"Dans un workflow Git classique, un dépôt = un répertoire de travail = une seule branche active. Pour changer de contexte, vous devez :",[79,20830,20831,20840,20852,20858,20864],{},[36,20832,20833,20836,20837,20839],{},[21,20834,20835],{},"Sauvegarder"," votre travail en cours (",[109,20838,20806],{}," ou commit temporaire)",[36,20841,20842,20845,20846,665,20849,10236],{},[21,20843,20844],{},"Changer"," de branche (",[109,20847,20848],{},"git checkout",[109,20850,20851],{},"git switch",[36,20853,20854,20857],{},[21,20855,20856],{},"Travailler"," sur l'autre branche",[36,20859,20860,20863],{},[21,20861,20862],{},"Revenir"," à votre branche initiale",[36,20865,20866,20869,20870,10236],{},[21,20867,20868],{},"Restaurer"," votre travail (",[109,20871,20810],{},[17,20873,20874],{},"Cela pose plusieurs problèmes :",[33,20876,20877,20883,20889,20895],{},[36,20878,20879,20882],{},[21,20880,20881],{},"Perte de contexte"," : votre IDE recharge tout, les serveurs de dev redémarrent",[36,20884,20885,20888],{},[21,20886,20887],{},"Risque d'erreurs"," : oublier un stash, conflits au pop, commits sur la mauvaise branche",[36,20890,20891,20894],{},[21,20892,20893],{},"Temps perdu"," : rebuild des dépendances, recompilation, rechargement des outils",[36,20896,20897,20900],{},[21,20898,20899],{},"Stash empilés"," : plusieurs stashs qui s'accumulent et deviennent difficiles à gérer",[12,20902,20904],{"id":20903},"quest-ce-quun-worktree","Qu'est-ce qu'un worktree ?",[17,20906,19284,20907,20910],{},[21,20908,20909],{},"worktree"," (arbre de travail) est un répertoire lié à votre dépôt Git qui contient une copie de travail d'une branche spécifique. Chaque worktree :",[33,20912,20913,20920,20926,20936],{},[36,20914,20915,20916,20919],{},"Possède son ",[21,20917,20918],{},"propre répertoire"," sur le disque",[36,20921,20922,20923],{},"Est lié à une ",[21,20924,20925],{},"branche différente",[36,20927,20928,20929,20932,20933,10236],{},"Partage le ",[21,20930,20931],{},"même historique Git"," (même ",[109,20934,20935],{},".git",[36,20937,20938,20939],{},"Fonctionne de manière ",[21,20940,20941],{},"totalement indépendante",[102,20943,20946],{"className":20944,"code":20945,"language":107},[105],"mon-projet/              ← worktree principal (branche main)\nmon-projet-feature/      ← worktree secondaire (branche feature/login)\nmon-projet-hotfix/       ← worktree secondaire (branche hotfix/bug-123)\n",[109,20947,20945],{"__ignoreMap":111},[17,20949,20950,20951,20954],{},"Tous ces répertoires pointent vers le ",[21,20952,20953],{},"même dépôt Git",". Un commit fait dans l'un est visible dans les autres.",[12,20956,15152],{"id":9081},[53,20958,20960],{"id":20959},"créer-un-worktree","Créer un worktree",[102,20962,20964],{"className":173,"code":20963,"language":175,"meta":111,"style":111},"# Syntaxe de base\ngit worktree add \u003Cchemin> \u003Cbranche>\n\n# Créer un worktree pour une branche existante\ngit worktree add ../mon-projet-feature feature/login\n\n# Créer un worktree ET une nouvelle branche\ngit worktree add -b feature/signup ../mon-projet-signup\n\n# Créer un worktree basé sur une branche distante\ngit worktree add ../mon-projet-fix origin/hotfix/bug-456\n",[109,20965,20966,20971,21002,21006,21011,21025,21029,21034,21050,21054,21059],{"__ignoreMap":111},[179,20967,20968],{"class":181,"line":182},[179,20969,20970],{"class":185},"# Syntaxe de base\n",[179,20972,20973,20975,20978,20980,20983,20986,20989,20992,20994,20997,21000],{"class":181,"line":189},[179,20974,9840],{"class":192},[179,20976,20977],{"class":196}," worktree",[179,20979,203],{"class":196},[179,20981,20982],{"class":549}," \u003C",[179,20984,20985],{"class":196},"chemi",[179,20987,20988],{"class":681},"n",[179,20990,20991],{"class":549},">",[179,20993,20982],{"class":549},[179,20995,20996],{"class":196},"branch",[179,20998,20999],{"class":681},"e",[179,21001,4057],{"class":549},[179,21003,21004],{"class":181,"line":448},[179,21005,1404],{"emptyLinePlaceholder":477},[179,21007,21008],{"class":181,"line":775},[179,21009,21010],{"class":185},"# Créer un worktree pour une branche existante\n",[179,21012,21013,21015,21017,21019,21022],{"class":181,"line":852},[179,21014,9840],{"class":192},[179,21016,20977],{"class":196},[179,21018,203],{"class":196},[179,21020,21021],{"class":196}," ../mon-projet-feature",[179,21023,21024],{"class":196}," feature/login\n",[179,21026,21027],{"class":181,"line":1351},[179,21028,1404],{"emptyLinePlaceholder":477},[179,21030,21031],{"class":181,"line":1363},[179,21032,21033],{"class":185},"# Créer un worktree ET une nouvelle branche\n",[179,21035,21036,21038,21040,21042,21044,21047],{"class":181,"line":1381},[179,21037,9840],{"class":192},[179,21039,20977],{"class":196},[179,21041,203],{"class":196},[179,21043,18338],{"class":224},[179,21045,21046],{"class":196}," feature/signup",[179,21048,21049],{"class":196}," ../mon-projet-signup\n",[179,21051,21052],{"class":181,"line":1401},[179,21053,1404],{"emptyLinePlaceholder":477},[179,21055,21056],{"class":181,"line":1407},[179,21057,21058],{"class":185},"# Créer un worktree basé sur une branche distante\n",[179,21060,21061,21063,21065,21067,21070],{"class":181,"line":1418},[179,21062,9840],{"class":192},[179,21064,20977],{"class":196},[179,21066,203],{"class":196},[179,21068,21069],{"class":196}," ../mon-projet-fix",[179,21071,21072],{"class":196}," origin/hotfix/bug-456\n",[17,21074,21075],{},"Après exécution, un nouveau répertoire est créé avec le contenu de la branche spécifiée, prêt à l'emploi.",[53,21077,21079],{"id":21078},"lister-les-worktrees","Lister les worktrees",[102,21081,21083],{"className":173,"code":21082,"language":175,"meta":111,"style":111},"git worktree list\n",[109,21084,21085],{"__ignoreMap":111},[179,21086,21087,21089,21091],{"class":181,"line":182},[179,21088,9840],{"class":192},[179,21090,20977],{"class":196},[179,21092,20320],{"class":196},[17,21094,21095],{},"Résultat :",[102,21097,21100],{"className":21098,"code":21099,"language":107},[105],"/home/user/mon-projet              abc1234 [main]\n/home/user/mon-projet-feature      def5678 [feature/login]\n/home/user/mon-projet-hotfix       ghi9012 [hotfix/bug-123]\n",[109,21101,21099],{"__ignoreMap":111},[53,21103,21105],{"id":21104},"supprimer-un-worktree","Supprimer un worktree",[102,21107,21109],{"className":173,"code":21108,"language":175,"meta":111,"style":111},"# Supprimer un worktree (après avoir terminé le travail)\ngit worktree remove ../mon-projet-feature\n\n# Forcer la suppression (si des modifications non commitées existent)\ngit worktree remove --force ../mon-projet-feature\n",[109,21110,21111,21116,21127,21131,21136],{"__ignoreMap":111},[179,21112,21113],{"class":181,"line":182},[179,21114,21115],{"class":185},"# Supprimer un worktree (après avoir terminé le travail)\n",[179,21117,21118,21120,21122,21124],{"class":181,"line":189},[179,21119,9840],{"class":192},[179,21121,20977],{"class":196},[179,21123,3167],{"class":196},[179,21125,21126],{"class":196}," ../mon-projet-feature\n",[179,21128,21129],{"class":181,"line":448},[179,21130,1404],{"emptyLinePlaceholder":477},[179,21132,21133],{"class":181,"line":775},[179,21134,21135],{"class":185},"# Forcer la suppression (si des modifications non commitées existent)\n",[179,21137,21138,21140,21142,21144,21147],{"class":181,"line":852},[179,21139,9840],{"class":192},[179,21141,20977],{"class":196},[179,21143,3167],{"class":196},[179,21145,21146],{"class":224}," --force",[179,21148,21126],{"class":196},[53,21150,21152],{"id":21151},"nettoyer-les-worktrees-invalides","Nettoyer les worktrees invalides",[17,21154,21155,21156,21159],{},"Si vous supprimez manuellement un répertoire de worktree (avec ",[109,21157,21158],{},"rm -rf","), Git garde une référence orpheline. Pour nettoyer :",[102,21161,21163],{"className":173,"code":21162,"language":175,"meta":111,"style":111},"git worktree prune\n",[109,21164,21165],{"__ignoreMap":111},[179,21166,21167,21169,21171],{"class":181,"line":182},[179,21168,9840],{"class":192},[179,21170,20977],{"class":196},[179,21172,9441],{"class":196},[12,21174,21176],{"id":21175},"comment-ça-fonctionne-en-interne","Comment ça fonctionne en interne ?",[17,21178,21179],{},"Quand vous créez un worktree, Git :",[79,21181,21182,21185],{},[36,21183,21184],{},"Crée le répertoire cible",[36,21186,21187,21188,21190],{},"Y place un fichier ",[109,21189,20935],{}," (pas un dossier) qui pointe vers le dépôt principal :",[102,21192,21195],{"className":21193,"code":21194,"language":107},[105],"# Contenu du fichier .git dans un worktree secondaire\ngitdir: /home/user/mon-projet/.git/worktrees/mon-projet-feature\n",[109,21196,21194],{"__ignoreMap":111},[79,21198,21199],{"start":448},[36,21200,21201,21202,21205],{},"Crée une entrée dans ",[109,21203,21204],{},".git/worktrees/"," du dépôt principal avec les métadonnées du worktree",[17,21207,21208,21209,5355,21212,21215,21216,21219],{},"Le dépôt Git (",[109,21210,21211],{},".git/objects",[109,21213,21214],{},".git/refs",", etc.) est ",[21,21217,21218],{},"partagé",". Cela signifie :",[33,21221,21222,21228,21235],{},[36,21223,21224,21227],{},[21,21225,21226],{},"Pas de duplication"," de l'historique (gain d'espace disque)",[36,21229,21230,21231,21234],{},"Les ",[21,21232,21233],{},"commits"," faits dans un worktree sont immédiatement visibles dans les autres",[36,21236,21230,21237,1468,21240,21243],{},[21,21238,21239],{},"branches distantes",[109,21241,21242],{},"git fetch",") sont partagées",[12,21245,21247],{"id":21246},"cas-dusage-concrets","Cas d'usage concrets",[53,21249,21251],{"id":21250},"_1-hotfix-urgent-pendant-un-développement","1. Hotfix urgent pendant un développement",[17,21253,21254],{},"Le cas le plus classique : vous travaillez sur une feature et devez corriger un bug en production.",[102,21256,21258],{"className":173,"code":21257,"language":175,"meta":111,"style":111},"# Vous êtes sur feature/dashboard dans mon-projet/\n# Créez un worktree pour le hotfix\ngit worktree add ../mon-projet-hotfix -b hotfix/fix-auth main\n\n# Allez dans le worktree du hotfix\ncd ../mon-projet-hotfix\n\n# Corrigez le bug, commitez, pushez\ngit add .\ngit commit -m \"fix: corriger l'authentification JWT expirée\"\ngit push origin hotfix/fix-auth\n\n# Retournez à votre feature, rien n'a changé\ncd ../mon-projet\n\n# Une fois le hotfix mergé, nettoyez\ngit worktree remove ../mon-projet-hotfix\n",[109,21259,21260,21265,21270,21288,21292,21297,21304,21308,21313,21321,21332,21343,21347,21352,21359,21363,21368],{"__ignoreMap":111},[179,21261,21262],{"class":181,"line":182},[179,21263,21264],{"class":185},"# Vous êtes sur feature/dashboard dans mon-projet/\n",[179,21266,21267],{"class":181,"line":189},[179,21268,21269],{"class":185},"# Créez un worktree pour le hotfix\n",[179,21271,21272,21274,21276,21278,21281,21283,21286],{"class":181,"line":448},[179,21273,9840],{"class":192},[179,21275,20977],{"class":196},[179,21277,203],{"class":196},[179,21279,21280],{"class":196}," ../mon-projet-hotfix",[179,21282,18338],{"class":224},[179,21284,21285],{"class":196}," hotfix/fix-auth",[179,21287,9895],{"class":196},[179,21289,21290],{"class":181,"line":775},[179,21291,1404],{"emptyLinePlaceholder":477},[179,21293,21294],{"class":181,"line":852},[179,21295,21296],{"class":185},"# Allez dans le worktree du hotfix\n",[179,21298,21299,21301],{"class":181,"line":1351},[179,21300,748],{"class":224},[179,21302,21303],{"class":196}," ../mon-projet-hotfix\n",[179,21305,21306],{"class":181,"line":1363},[179,21307,1404],{"emptyLinePlaceholder":477},[179,21309,21310],{"class":181,"line":1381},[179,21311,21312],{"class":185},"# Corrigez le bug, commitez, pushez\n",[179,21314,21315,21317,21319],{"class":181,"line":1401},[179,21316,9840],{"class":192},[179,21318,203],{"class":196},[179,21320,9861],{"class":196},[179,21322,21323,21325,21327,21329],{"class":181,"line":1407},[179,21324,9840],{"class":192},[179,21326,9868],{"class":196},[179,21328,8420],{"class":224},[179,21330,21331],{"class":196}," \"fix: corriger l'authentification JWT expirée\"\n",[179,21333,21334,21336,21338,21340],{"class":181,"line":1418},[179,21335,9840],{"class":192},[179,21337,18144],{"class":196},[179,21339,9916],{"class":196},[179,21341,21342],{"class":196}," hotfix/fix-auth\n",[179,21344,21345],{"class":181,"line":1435},[179,21346,1404],{"emptyLinePlaceholder":477},[179,21348,21349],{"class":181,"line":1440},[179,21350,21351],{"class":185},"# Retournez à votre feature, rien n'a changé\n",[179,21353,21354,21356],{"class":181,"line":1450},[179,21355,748],{"class":224},[179,21357,21358],{"class":196}," ../mon-projet\n",[179,21360,21361],{"class":181,"line":1483},[179,21362,1404],{"emptyLinePlaceholder":477},[179,21364,21365],{"class":181,"line":1503},[179,21366,21367],{"class":185},"# Une fois le hotfix mergé, nettoyez\n",[179,21369,21370,21372,21374,21376],{"class":181,"line":1533},[179,21371,9840],{"class":192},[179,21373,20977],{"class":196},[179,21375,3167],{"class":196},[179,21377,21303],{"class":196},[17,21379,21380,21381,21384,21385,436],{},"Votre travail sur ",[109,21382,21383],{},"feature/dashboard"," n'a ",[21,21386,21387],{},"jamais été interrompu",[53,21389,21391],{"id":21390},"_2-review-de-pull-request","2. Review de pull request",[17,21393,21394],{},"Vous voulez tester localement la PR d'un collègue sans toucher à votre travail :",[102,21396,21398],{"className":173,"code":21397,"language":175,"meta":111,"style":111},"# Récupérer la branche de la PR\ngit fetch origin feature/new-api\n\n# Créer un worktree dédié à la review\ngit worktree add ../review-new-api origin/feature/new-api\n\n# Tester, lire le code, lancer les tests dans ce répertoire\ncd ../review-new-api\nnpm install\nnpm test\n\n# Nettoyer après la review\ncd ../mon-projet\ngit worktree remove ../review-new-api\n",[109,21399,21400,21405,21416,21420,21425,21439,21443,21448,21455,21462,21469,21473,21478,21484],{"__ignoreMap":111},[179,21401,21402],{"class":181,"line":182},[179,21403,21404],{"class":185},"# Récupérer la branche de la PR\n",[179,21406,21407,21409,21411,21413],{"class":181,"line":189},[179,21408,9840],{"class":192},[179,21410,3758],{"class":196},[179,21412,9916],{"class":196},[179,21414,21415],{"class":196}," feature/new-api\n",[179,21417,21418],{"class":181,"line":448},[179,21419,1404],{"emptyLinePlaceholder":477},[179,21421,21422],{"class":181,"line":775},[179,21423,21424],{"class":185},"# Créer un worktree dédié à la review\n",[179,21426,21427,21429,21431,21433,21436],{"class":181,"line":852},[179,21428,9840],{"class":192},[179,21430,20977],{"class":196},[179,21432,203],{"class":196},[179,21434,21435],{"class":196}," ../review-new-api",[179,21437,21438],{"class":196}," origin/feature/new-api\n",[179,21440,21441],{"class":181,"line":1351},[179,21442,1404],{"emptyLinePlaceholder":477},[179,21444,21445],{"class":181,"line":1363},[179,21446,21447],{"class":185},"# Tester, lire le code, lancer les tests dans ce répertoire\n",[179,21449,21450,21452],{"class":181,"line":1381},[179,21451,748],{"class":224},[179,21453,21454],{"class":196}," ../review-new-api\n",[179,21456,21457,21459],{"class":181,"line":1401},[179,21458,600],{"class":192},[179,21460,21461],{"class":196}," install\n",[179,21463,21464,21466],{"class":181,"line":1407},[179,21465,600],{"class":192},[179,21467,21468],{"class":196}," test\n",[179,21470,21471],{"class":181,"line":1418},[179,21472,1404],{"emptyLinePlaceholder":477},[179,21474,21475],{"class":181,"line":1435},[179,21476,21477],{"class":185},"# Nettoyer après la review\n",[179,21479,21480,21482],{"class":181,"line":1440},[179,21481,748],{"class":224},[179,21483,21358],{"class":196},[179,21485,21486,21488,21490,21492],{"class":181,"line":1450},[179,21487,9840],{"class":192},[179,21489,20977],{"class":196},[179,21491,3167],{"class":196},[179,21493,21454],{"class":196},[53,21495,21497],{"id":21496},"_3-comparer-deux-versions-côte-à-côte","3. Comparer deux versions côte à côte",[17,21499,21500],{},"Besoin de comparer le comportement entre deux branches ?",[102,21502,21504],{"className":173,"code":21503,"language":175,"meta":111,"style":111},"# Worktree pour la version actuelle\ngit worktree add ../projet-v2 release/v2\n\n# Worktree pour la nouvelle version\ngit worktree add ../projet-v3 release/v3\n\n# Ouvrez les deux dans votre éditeur/navigateur et comparez\n",[109,21505,21506,21511,21525,21529,21534,21548,21552],{"__ignoreMap":111},[179,21507,21508],{"class":181,"line":182},[179,21509,21510],{"class":185},"# Worktree pour la version actuelle\n",[179,21512,21513,21515,21517,21519,21522],{"class":181,"line":189},[179,21514,9840],{"class":192},[179,21516,20977],{"class":196},[179,21518,203],{"class":196},[179,21520,21521],{"class":196}," ../projet-v2",[179,21523,21524],{"class":196}," release/v2\n",[179,21526,21527],{"class":181,"line":448},[179,21528,1404],{"emptyLinePlaceholder":477},[179,21530,21531],{"class":181,"line":775},[179,21532,21533],{"class":185},"# Worktree pour la nouvelle version\n",[179,21535,21536,21538,21540,21542,21545],{"class":181,"line":852},[179,21537,9840],{"class":192},[179,21539,20977],{"class":196},[179,21541,203],{"class":196},[179,21543,21544],{"class":196}," ../projet-v3",[179,21546,21547],{"class":196}," release/v3\n",[179,21549,21550],{"class":181,"line":1351},[179,21551,1404],{"emptyLinePlaceholder":477},[179,21553,21554],{"class":181,"line":1363},[179,21555,21556],{"class":185},"# Ouvrez les deux dans votre éditeur/navigateur et comparez\n",[53,21558,21560],{"id":21559},"_4-exécuter-des-tests-longs-en-parallèle","4. Exécuter des tests longs en parallèle",[17,21562,21563],{},"Si vos tests prennent du temps, lancez-les dans un worktree pendant que vous continuez à coder :",[102,21565,21567],{"className":173,"code":21566,"language":175,"meta":111,"style":111},"# Créer un worktree pour les tests\ngit worktree add ../mon-projet-tests feature/ma-feature\n\n# Lancer les tests en arrière-plan\ncd ../mon-projet-tests\nnpm test &\n\n# Continuer à coder dans le worktree principal\ncd ../mon-projet\n# ... vos modifications ...\n",[109,21568,21569,21574,21588,21592,21597,21604,21614,21618,21623,21629],{"__ignoreMap":111},[179,21570,21571],{"class":181,"line":182},[179,21572,21573],{"class":185},"# Créer un worktree pour les tests\n",[179,21575,21576,21578,21580,21582,21585],{"class":181,"line":189},[179,21577,9840],{"class":192},[179,21579,20977],{"class":196},[179,21581,203],{"class":196},[179,21583,21584],{"class":196}," ../mon-projet-tests",[179,21586,21587],{"class":196}," feature/ma-feature\n",[179,21589,21590],{"class":181,"line":448},[179,21591,1404],{"emptyLinePlaceholder":477},[179,21593,21594],{"class":181,"line":775},[179,21595,21596],{"class":185},"# Lancer les tests en arrière-plan\n",[179,21598,21599,21601],{"class":181,"line":852},[179,21600,748],{"class":224},[179,21602,21603],{"class":196}," ../mon-projet-tests\n",[179,21605,21606,21608,21611],{"class":181,"line":1351},[179,21607,600],{"class":192},[179,21609,21610],{"class":196}," test",[179,21612,21613],{"class":681}," &\n",[179,21615,21616],{"class":181,"line":1363},[179,21617,1404],{"emptyLinePlaceholder":477},[179,21619,21620],{"class":181,"line":1381},[179,21621,21622],{"class":185},"# Continuer à coder dans le worktree principal\n",[179,21624,21625,21627],{"class":181,"line":1401},[179,21626,748],{"class":224},[179,21628,21358],{"class":196},[179,21630,21631],{"class":181,"line":1407},[179,21632,21633],{"class":185},"# ... vos modifications ...\n",[53,21635,21637],{"id":21636},"_5-build-de-production-pendant-le-développement","5. Build de production pendant le développement",[17,21639,21640],{},"Générez un build de production sans interrompre votre serveur de dev :",[102,21642,21644],{"className":173,"code":21643,"language":175,"meta":111,"style":111},"git worktree add ../mon-projet-build main\ncd ../mon-projet-build\nnpm ci\nnpm run build\n",[109,21645,21646,21659,21666,21673],{"__ignoreMap":111},[179,21647,21648,21650,21652,21654,21657],{"class":181,"line":182},[179,21649,9840],{"class":192},[179,21651,20977],{"class":196},[179,21653,203],{"class":196},[179,21655,21656],{"class":196}," ../mon-projet-build",[179,21658,9895],{"class":196},[179,21660,21661,21663],{"class":181,"line":189},[179,21662,748],{"class":224},[179,21664,21665],{"class":196}," ../mon-projet-build\n",[179,21667,21668,21670],{"class":181,"line":448},[179,21669,600],{"class":192},[179,21671,21672],{"class":196}," ci\n",[179,21674,21675,21677,21679],{"class":181,"line":775},[179,21676,600],{"class":192},[179,21678,8377],{"class":196},[179,21680,9397],{"class":196},[12,21682,21684],{"id":21683},"règles-et-contraintes","Règles et contraintes",[17,21686,21687],{},"Il y a quelques règles importantes à retenir :",[53,21689,21691],{"id":21690},"une-branche-un-seul-worktree","Une branche = un seul worktree",[17,21693,21694,21695,21698],{},"Git ",[21,21696,21697],{},"interdit"," d'avoir deux worktrees sur la même branche :",[102,21700,21702],{"className":173,"code":21701,"language":175,"meta":111,"style":111},"git worktree add ../autre-main main\n# Erreur : fatal: 'main' is already checked out at '/home/user/mon-projet'\n",[109,21703,21704,21717],{"__ignoreMap":111},[179,21705,21706,21708,21710,21712,21715],{"class":181,"line":182},[179,21707,9840],{"class":192},[179,21709,20977],{"class":196},[179,21711,203],{"class":196},[179,21713,21714],{"class":196}," ../autre-main",[179,21716,9895],{"class":196},[179,21718,21719],{"class":181,"line":189},[179,21720,21721],{"class":185},"# Erreur : fatal: 'main' is already checked out at '/home/user/mon-projet'\n",[17,21723,21724],{},"C'est une protection contre les conflits : deux répertoires modifiant la même branche simultanément créeraient des incohérences.",[17,21726,21727,21730],{},[21,21728,21729],{},"Solution"," : créez une branche temporaire basée sur la branche souhaitée :",[102,21732,21734],{"className":173,"code":21733,"language":175,"meta":111,"style":111},"git worktree add -b temp/main-copy ../autre-main main\n",[109,21735,21736],{"__ignoreMap":111},[179,21737,21738,21740,21742,21744,21746,21749,21751],{"class":181,"line":182},[179,21739,9840],{"class":192},[179,21741,20977],{"class":196},[179,21743,203],{"class":196},[179,21745,18338],{"class":224},[179,21747,21748],{"class":196}," temp/main-copy",[179,21750,21714],{"class":196},[179,21752,9895],{"class":196},[53,21754,21756],{"id":21755},"les-fichiers-non-suivis-ne-sont-pas-partagés","Les fichiers non suivis ne sont pas partagés",[17,21758,21759,21760,5355,21763,21765,21766,21769],{},"Chaque worktree a son propre ensemble de fichiers non suivis (untracked). Les fichiers comme ",[109,21761,21762],{},"node_modules/",[109,21764,10125],{},", ou les builds locaux ne sont ",[21,21767,21768],{},"pas partagés"," entre worktrees.",[17,21771,21772,21773,1468,21776,21779],{},"Cela signifie que vous devrez ",[21,21774,21775],{},"réinstaller les dépendances",[109,21777,21778],{},"npm install",") dans chaque nouveau worktree.",[53,21781,1067,21783,21785],{"id":21782},"le-gitignore-est-partagé",[109,21784,19004],{}," est partagé",[17,21787,11133,21788,21790],{},[109,21789,19004],{}," fait partie du dépôt, il s'applique donc à tous les worktrees.",[12,21792,21794],{"id":21793},"worktree-vs-autres-approches","Worktree vs autres approches",[1120,21796,21797,21808],{},[1123,21798,21799],{},[1126,21800,21801,21804,21806],{},[1129,21802,21803],{},"Approche",[1129,21805,2249],{},[1129,21807,2279],{},[1136,21809,21810,21822,21836],{},[1126,21811,21812,21816,21819],{},[1141,21813,21814],{},[21,21815,20806],{},[1141,21817,21818],{},"Simple, rapide",[1141,21820,21821],{},"Perte de contexte, risque de conflits",[1126,21823,21824,21830,21833],{},[1141,21825,21826,21829],{},[21,21827,21828],{},"git clone"," (copie)",[1141,21831,21832],{},"Isolation complète",[1141,21834,21835],{},"Duplication du dépôt, historiques séparés",[1126,21837,21838,21843,21846],{},[1141,21839,21840],{},[21,21841,21842],{},"git worktree",[1141,21844,21845],{},"Léger, branches partagées, pas de perte de contexte",[1141,21847,21848],{},"Dépendances à réinstaller",[17,21850,21851],{},[21,21852,21853],{},"En résumé :",[33,21855,21856,21864,21872],{},[36,21857,15493,21858,21860,21861],{},[109,21859,20806],{}," pour des changements de contexte ",[21,21862,21863],{},"rapides et courts",[36,21865,15493,21866,21868,21869],{},[109,21867,21842],{}," pour du travail ",[21,21870,21871],{},"parallèle prolongé",[36,21873,15493,21874,21876,21877,21880],{},[109,21875,21828],{}," si vous avez besoin d'une ",[21,21878,21879],{},"isolation complète"," (rare)",[12,21882,3609],{"id":3608},[53,21884,21886],{"id":21885},"_1-convention-de-nommage","1. Convention de nommage",[17,21888,21889],{},"Adoptez une convention claire pour vos répertoires de worktree :",[102,21891,21893],{"className":173,"code":21892,"language":175,"meta":111,"style":111},"# Convention : \u003Cprojet>-wt-\u003Cdescription>\ngit worktree add ../learn-wt-hotfix hotfix/bug-123\ngit worktree add ../learn-wt-review feature/new-api\n",[109,21894,21895,21900,21914],{"__ignoreMap":111},[179,21896,21897],{"class":181,"line":182},[179,21898,21899],{"class":185},"# Convention : \u003Cprojet>-wt-\u003Cdescription>\n",[179,21901,21902,21904,21906,21908,21911],{"class":181,"line":189},[179,21903,9840],{"class":192},[179,21905,20977],{"class":196},[179,21907,203],{"class":196},[179,21909,21910],{"class":196}," ../learn-wt-hotfix",[179,21912,21913],{"class":196}," hotfix/bug-123\n",[179,21915,21916,21918,21920,21922,21925],{"class":181,"line":448},[179,21917,9840],{"class":192},[179,21919,20977],{"class":196},[179,21921,203],{"class":196},[179,21923,21924],{"class":196}," ../learn-wt-review",[179,21926,21415],{"class":196},[53,21928,21930],{"id":21929},"_2-regrouper-les-worktrees","2. Regrouper les worktrees",[17,21932,21933],{},"Créez un répertoire parent pour garder les choses organisées :",[102,21935,21937],{"className":173,"code":21936,"language":175,"meta":111,"style":111},"mkdir -p ../worktrees\ngit worktree add ../worktrees/hotfix hotfix/bug-123\ngit worktree add ../worktrees/review feature/new-api\n",[109,21938,21939,21948,21961],{"__ignoreMap":111},[179,21940,21941,21943,21945],{"class":181,"line":182},[179,21942,3079],{"class":192},[179,21944,3486],{"class":224},[179,21946,21947],{"class":196}," ../worktrees\n",[179,21949,21950,21952,21954,21956,21959],{"class":181,"line":189},[179,21951,9840],{"class":192},[179,21953,20977],{"class":196},[179,21955,203],{"class":196},[179,21957,21958],{"class":196}," ../worktrees/hotfix",[179,21960,21913],{"class":196},[179,21962,21963,21965,21967,21969,21972],{"class":181,"line":448},[179,21964,9840],{"class":192},[179,21966,20977],{"class":196},[179,21968,203],{"class":196},[179,21970,21971],{"class":196}," ../worktrees/review",[179,21973,21415],{"class":196},[53,21975,21977],{"id":21976},"_3-nettoyer-régulièrement","3. Nettoyer régulièrement",[17,21979,21980],{},"Les worktrees oubliés s'accumulent. Prenez l'habitude de :",[102,21982,21984],{"className":173,"code":21983,"language":175,"meta":111,"style":111},"# Lister les worktrees actifs\ngit worktree list\n\n# Supprimer ceux qui ne sont plus nécessaires\ngit worktree remove ../worktrees/hotfix\n\n# Nettoyer les références orphelines\ngit worktree prune\n",[109,21985,21986,21991,21999,22003,22008,22019,22023,22028],{"__ignoreMap":111},[179,21987,21988],{"class":181,"line":182},[179,21989,21990],{"class":185},"# Lister les worktrees actifs\n",[179,21992,21993,21995,21997],{"class":181,"line":189},[179,21994,9840],{"class":192},[179,21996,20977],{"class":196},[179,21998,20320],{"class":196},[179,22000,22001],{"class":181,"line":448},[179,22002,1404],{"emptyLinePlaceholder":477},[179,22004,22005],{"class":181,"line":775},[179,22006,22007],{"class":185},"# Supprimer ceux qui ne sont plus nécessaires\n",[179,22009,22010,22012,22014,22016],{"class":181,"line":852},[179,22011,9840],{"class":192},[179,22013,20977],{"class":196},[179,22015,3167],{"class":196},[179,22017,22018],{"class":196}," ../worktrees/hotfix\n",[179,22020,22021],{"class":181,"line":1351},[179,22022,1404],{"emptyLinePlaceholder":477},[179,22024,22025],{"class":181,"line":1363},[179,22026,22027],{"class":185},"# Nettoyer les références orphelines\n",[179,22029,22030,22032,22034],{"class":181,"line":1381},[179,22031,9840],{"class":192},[179,22033,20977],{"class":196},[179,22035,9441],{"class":196},[53,22037,22039],{"id":22038},"_4-automatiser-linstallation-des-dépendances","4. Automatiser l'installation des dépendances",[17,22041,22042],{},"Créez un petit script pour initialiser rapidement un worktree :",[102,22044,22046],{"className":173,"code":22045,"language":175,"meta":111,"style":111},"#!/bin/bash\n# wt-create.sh : Créer et initialiser un worktree\nBRANCH=$1\nDIR=$2\n\ngit worktree add \"$DIR\" \"$BRANCH\"\ncd \"$DIR\"\nnpm install\necho \"Worktree prêt dans $DIR\"\n",[109,22047,22048,22052,22057,22067,22077,22081,22103,22113,22119],{"__ignoreMap":111},[179,22049,22050],{"class":181,"line":182},[179,22051,3531],{"class":185},[179,22053,22054],{"class":181,"line":189},[179,22055,22056],{"class":185},"# wt-create.sh : Créer et initialiser un worktree\n",[179,22058,22059,22062,22064],{"class":181,"line":448},[179,22060,22061],{"class":681},"BRANCH",[179,22063,685],{"class":549},[179,22065,22066],{"class":3802},"$1\n",[179,22068,22069,22072,22074],{"class":181,"line":775},[179,22070,22071],{"class":681},"DIR",[179,22073,685],{"class":549},[179,22075,22076],{"class":3802},"$2\n",[179,22078,22079],{"class":181,"line":852},[179,22080,1404],{"emptyLinePlaceholder":477},[179,22082,22083,22085,22087,22089,22091,22094,22096,22098,22101],{"class":181,"line":1351},[179,22084,9840],{"class":192},[179,22086,20977],{"class":196},[179,22088,203],{"class":196},[179,22090,17611],{"class":196},[179,22092,22093],{"class":681},"$DIR",[179,22095,5813],{"class":196},[179,22097,17611],{"class":196},[179,22099,22100],{"class":681},"$BRANCH",[179,22102,17393],{"class":196},[179,22104,22105,22107,22109,22111],{"class":181,"line":1363},[179,22106,748],{"class":224},[179,22108,17611],{"class":196},[179,22110,22093],{"class":681},[179,22112,17393],{"class":196},[179,22114,22115,22117],{"class":181,"line":1381},[179,22116,600],{"class":192},[179,22118,21461],{"class":196},[179,22120,22121,22123,22126,22128],{"class":181,"line":1401},[179,22122,4760],{"class":224},[179,22124,22125],{"class":196}," \"Worktree prêt dans ",[179,22127,22093],{"class":681},[179,22129,17393],{"class":196},[12,22131,22133],{"id":22132},"intégration-avec-les-éditeurs","Intégration avec les éditeurs",[53,22135,22137],{"id":22136},"vs-code","VS Code",[17,22139,22140],{},"VS Code détecte automatiquement les worktrees. Ouvrez simplement le répertoire du worktree comme un projet normal :",[102,22142,22144],{"className":173,"code":22143,"language":175,"meta":111,"style":111},"code ../mon-projet-hotfix\n",[109,22145,22146],{"__ignoreMap":111},[179,22147,22148,22150],{"class":181,"line":182},[179,22149,109],{"class":192},[179,22151,21303],{"class":196},[17,22153,22154],{},"Chaque fenêtre VS Code travaille indépendamment sur sa branche.",[53,22156,22158],{"id":22157},"jetbrains-webstorm-intellij","JetBrains (WebStorm, IntelliJ)",[17,22160,22161],{},"Les IDE JetBrains reconnaissent également les worktrees. Ouvrez le répertoire du worktree comme un projet distinct.",[12,22163,22165],{"id":22164},"résumé-des-commandes","Résumé des commandes",[1120,22167,22168,22176],{},[1123,22169,22170],{},[1126,22171,22172,22174],{},[1129,22173,1131],{},[1129,22175,1134],{},[1136,22177,22178,22188,22198,22208,22217,22227,22237,22247],{},[1126,22179,22180,22185],{},[1141,22181,22182],{},[109,22183,22184],{},"git worktree add \u003Cchemin> \u003Cbranche>",[1141,22186,22187],{},"Créer un worktree pour une branche existante",[1126,22189,22190,22195],{},[1141,22191,22192],{},[109,22193,22194],{},"git worktree add -b \u003Cnouvelle-branche> \u003Cchemin> [base]",[1141,22196,22197],{},"Créer un worktree avec une nouvelle branche",[1126,22199,22200,22205],{},[1141,22201,22202],{},[109,22203,22204],{},"git worktree list",[1141,22206,22207],{},"Lister tous les worktrees",[1126,22209,22210,22215],{},[1141,22211,22212],{},[109,22213,22214],{},"git worktree remove \u003Cchemin>",[1141,22216,21105],{},[1126,22218,22219,22224],{},[1141,22220,22221],{},[109,22222,22223],{},"git worktree prune",[1141,22225,22226],{},"Nettoyer les références orphelines",[1126,22228,22229,22234],{},[1141,22230,22231],{},[109,22232,22233],{},"git worktree move \u003Csource> \u003Cdestination>",[1141,22235,22236],{},"Déplacer un worktree",[1126,22238,22239,22244],{},[1141,22240,22241],{},[109,22242,22243],{},"git worktree lock \u003Cchemin>",[1141,22245,22246],{},"Verrouiller un worktree (empêcher le prune)",[1126,22248,22249,22254],{},[1141,22250,22251],{},[109,22252,22253],{},"git worktree unlock \u003Cchemin>",[1141,22255,22256],{},"Déverrouiller un worktree",[12,22258,406],{"id":405},[17,22260,22261,22263,22264,7885,22267,22270],{},[109,22262,21842],{}," est un outil sous-estimé qui peut transformer votre workflow quotidien. Au lieu de jongler entre les branches avec ",[109,22265,22266],{},"stash",[109,22268,22269],{},"switch",", vous gardez chaque contexte de travail dans son propre répertoire, prêt à l'emploi.",[17,22272,22273],{},"Les bénéfices principaux :",[33,22275,22276,22282,22288,22294],{},[36,22277,22278,22281],{},[21,22279,22280],{},"Zéro interruption"," : votre travail en cours reste intact",[36,22283,22284,22287],{},[21,22285,22286],{},"Parallélisme"," : travaillez sur plusieurs tâches simultanément",[36,22289,22290,22293],{},[21,22291,22292],{},"Légèreté"," : pas de duplication du dépôt Git",[36,22295,22296,22298],{},[21,22297,2268],{}," : quelques commandes suffisent",[17,22300,22301,22302,22305],{},"La prochaine fois que vous devrez gérer un hotfix urgent ou review une PR, pensez à ",[109,22303,22304],{},"git worktree add"," — votre futur vous remerciera.",[438,22307,22308],{},"html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}",{"title":111,"searchDepth":189,"depth":189,"links":22310},[22311,22312,22313,22314,22320,22321,22328,22334,22335,22341,22345,22346],{"id":14,"depth":189,"text":15},{"id":20824,"depth":189,"text":20825},{"id":20903,"depth":189,"text":20904},{"id":9081,"depth":189,"text":15152,"children":22315},[22316,22317,22318,22319],{"id":20959,"depth":448,"text":20960},{"id":21078,"depth":448,"text":21079},{"id":21104,"depth":448,"text":21105},{"id":21151,"depth":448,"text":21152},{"id":21175,"depth":189,"text":21176},{"id":21246,"depth":189,"text":21247,"children":22322},[22323,22324,22325,22326,22327],{"id":21250,"depth":448,"text":21251},{"id":21390,"depth":448,"text":21391},{"id":21496,"depth":448,"text":21497},{"id":21559,"depth":448,"text":21560},{"id":21636,"depth":448,"text":21637},{"id":21683,"depth":189,"text":21684,"children":22329},[22330,22331,22332],{"id":21690,"depth":448,"text":21691},{"id":21755,"depth":448,"text":21756},{"id":21782,"depth":448,"text":22333},"Le .gitignore est partagé",{"id":21793,"depth":189,"text":21794},{"id":3608,"depth":189,"text":3609,"children":22336},[22337,22338,22339,22340],{"id":21885,"depth":448,"text":21886},{"id":21929,"depth":448,"text":21930},{"id":21976,"depth":448,"text":21977},{"id":22038,"depth":448,"text":22039},{"id":22132,"depth":189,"text":22133,"children":22342},[22343,22344],{"id":22136,"depth":448,"text":22137},{"id":22157,"depth":448,"text":22158},{"id":22164,"depth":189,"text":22165},{"id":405,"depth":189,"text":406},"2026-03-25","Maîtrisez git worktree pour gérer plusieurs branches en parallèle sans stash ni commit temporaire. Guide complet avec cas pratiques.","/images/posts/2026/03/git-worktree-travailler-sur-plusieurs-branches-simultanement.webp",{},"/posts/git-worktree-travailler-sur-plusieurs-branches-simultanement",{"title":20796,"description":22348},"posts/git-worktree-travailler-sur-plusieurs-branches-simultanement",[9840,22355,22356],"developpement","productivite","h5y6NPPkqKrtKJQnULPkOFlTaENr1zSmV1k2FroJXHc",{"id":22359,"title":22360,"author":7,"body":22361,"date":24808,"description":24809,"extension":474,"image":24810,"meta":24811,"navigation":477,"path":24812,"readingTime":479,"seo":24813,"stem":24814,"tags":24815,"updatedAt":24808,"__hash__":24820},"posts/posts/guide-de-migration-java-8-java-20.md","Guide de Migration Java 8 → Java 20",{"type":9,"value":22362,"toc":24758},[22363,22366,22369,22373,22376,22408,22411,22413,22417,22420,22424,22620,22624,22646,22651,22665,22667,22671,22674,22678,22768,22772,22878,22882,23018,23020,23024,23027,23030,23110,23113,23152,23156,23167,23169,23173,23176,23179,23244,23248,23382,23384,23388,23391,23395,23448,23452,23495,23501,23503,23507,23513,23516,23694,23697,23810,23816,23916,23918,23922,23925,24076,24078,24082,24089,24093,24099,24102,24105,24118,24124,24126,24130,24137,24140,24184,24187,24233,24242,24244,24248,24251,24254,24274,24277,24288,24291,24293,24297,24300,24420,24422,24426,24430,24465,24469,24474,24501,24506,24532,24536,24556,24560,24574,24576,24578,24581,24586,24617,24620,24622,24626,24755],[4662,22364,22360],{"id":22365},"guide-de-migration-java-8-java-20",[17,22367,22368],{},"Depuis la sortie de Java 8 en 2014, le langage Java a considérablement évolué. Java 20, publié en 2023, marque une étape importante avec des fonctionnalités mature et d'autres en mode \"preview\". Ce guide vous accompagne dans la compréhension des principales évolutions, du plus simple au plus avancé.",[12,22370,22372],{"id":22371},"contexte-java-8-un-point-de-départ-majeur","Contexte : Java 8, un point de départ majeur",[17,22374,22375],{},"Java 8 (2014) a révolutionné le langage avec :",[33,22377,22378,22384,22390,22396,22402],{},[36,22379,22380,22383],{},[21,22381,22382],{},"Lambda expressions"," — Fonctions anonymes pour le style fonctionnel",[36,22385,22386,22389],{},[21,22387,22388],{},"Stream API"," — Traitement fonctionnel des collections",[36,22391,22392,22395],{},[21,22393,22394],{},"Optional"," — Gestion explicite des valeurs nulles",[36,22397,22398,22401],{},[21,22399,22400],{},"Default methods"," — Méthodes par défaut dans les interfaces",[36,22403,22404,22407],{},[21,22405,22406],{},"Date API (java.time)"," — Remplacement de Date/Calendar",[17,22409,22410],{},"Java 20 (2023) construit sur cette base avec des fonctionnalités plus subtiles mais puissantes.",[10725,22412],{},[12,22414,22416],{"id":22415},"_1-records-java-14-standard-en-java-16","1. Records (Java 14, standard en Java 16)",[17,22418,22419],{},"Les records simplifient la création de classes immuables conteneurs de données.",[53,22421,22423],{"id":22422},"java-8-sans-records","Java 8 (sans records)",[102,22425,22427],{"className":5447,"code":22426,"language":652,"meta":111,"style":111},"public class Person {\n    private final String name;\n    private final int age;\n\n    public Person(String name, int age) {\n        this.name = name;\n        this.age = age;\n    }\n\n    public String getName() { return name; }\n    public int getAge() { return age; }\n    \n    @Override\n    public boolean equals(Object o) { ... }\n    @Override\n    public int hashCode() { ... }\n    @Override\n    public String toString() { ... }\n}\n",[109,22428,22429,22440,22449,22461,22465,22485,22497,22508,22512,22516,22535,22551,22555,22563,22581,22587,22599,22605,22616],{"__ignoreMap":111},[179,22430,22431,22433,22435,22438],{"class":181,"line":182},[179,22432,5474],{"class":549},[179,22434,4068],{"class":549},[179,22436,22437],{"class":192}," Person",[179,22439,3892],{"class":681},[179,22441,22442,22444,22446],{"class":181,"line":189},[179,22443,5486],{"class":549},[179,22445,5489],{"class":549},[179,22447,22448],{"class":681}," String name;\n",[179,22450,22451,22453,22455,22458],{"class":181,"line":448},[179,22452,5486],{"class":549},[179,22454,5489],{"class":549},[179,22456,22457],{"class":549}," int",[179,22459,22460],{"class":681}," age;\n",[179,22462,22463],{"class":181,"line":775},[179,22464,1404],{"emptyLinePlaceholder":477},[179,22466,22467,22469,22471,22474,22476,22478,22480,22483],{"class":181,"line":852},[179,22468,5199],{"class":549},[179,22470,22437],{"class":192},[179,22472,22473],{"class":681},"(String ",[179,22475,3833],{"class":3802},[179,22477,5355],{"class":681},[179,22479,5728],{"class":549},[179,22481,22482],{"class":3802}," age",[179,22484,4489],{"class":681},[179,22486,22487,22489,22492,22494],{"class":181,"line":1351},[179,22488,5514],{"class":224},[179,22490,22491],{"class":681},".name ",[179,22493,685],{"class":549},[179,22495,22496],{"class":681}," name;\n",[179,22498,22499,22501,22504,22506],{"class":181,"line":1363},[179,22500,5514],{"class":224},[179,22502,22503],{"class":681},".age ",[179,22505,685],{"class":549},[179,22507,22460],{"class":681},[179,22509,22510],{"class":181,"line":1381},[179,22511,5320],{"class":681},[179,22513,22514],{"class":181,"line":1401},[179,22515,1404],{"emptyLinePlaceholder":477},[179,22517,22518,22520,22523,22526,22529,22532],{"class":181,"line":1407},[179,22519,5199],{"class":549},[179,22521,22522],{"class":681}," String ",[179,22524,22525],{"class":192},"getName",[179,22527,22528],{"class":681},"() { ",[179,22530,22531],{"class":549},"return",[179,22533,22534],{"class":681}," name; }\n",[179,22536,22537,22539,22541,22544,22546,22548],{"class":181,"line":1418},[179,22538,5199],{"class":549},[179,22540,22457],{"class":549},[179,22542,22543],{"class":192}," getAge",[179,22545,22528],{"class":681},[179,22547,22531],{"class":549},[179,22549,22550],{"class":681}," age; }\n",[179,22552,22553],{"class":181,"line":1435},[179,22554,11995],{"class":681},[179,22556,22557,22560],{"class":181,"line":1440},[179,22558,22559],{"class":681},"    @",[179,22561,22562],{"class":549},"Override\n",[179,22564,22565,22567,22570,22573,22576,22578],{"class":181,"line":1450},[179,22566,5199],{"class":549},[179,22568,22569],{"class":549}," boolean",[179,22571,22572],{"class":192}," equals",[179,22574,22575],{"class":681},"(Object ",[179,22577,5358],{"class":3802},[179,22579,22580],{"class":681},") { ... }\n",[179,22582,22583,22585],{"class":181,"line":1483},[179,22584,22559],{"class":681},[179,22586,22562],{"class":549},[179,22588,22589,22591,22593,22596],{"class":181,"line":1503},[179,22590,5199],{"class":549},[179,22592,22457],{"class":549},[179,22594,22595],{"class":192}," hashCode",[179,22597,22598],{"class":681},"() { ... }\n",[179,22600,22601,22603],{"class":181,"line":1533},[179,22602,22559],{"class":681},[179,22604,22562],{"class":549},[179,22606,22607,22609,22611,22614],{"class":181,"line":1557},[179,22608,5199],{"class":549},[179,22610,22522],{"class":681},[179,22612,22613],{"class":192},"toString",[179,22615,22598],{"class":681},[179,22617,22618],{"class":181,"line":1583},[179,22619,3814],{"class":681},[53,22621,22623],{"id":22622},"java-20","Java 20",[102,22625,22627],{"className":5447,"code":22626,"language":652,"meta":111,"style":111},"public record Person(String name, int age) {}\n",[109,22628,22629],{"__ignoreMap":111},[179,22630,22631,22633,22636,22638,22641,22643],{"class":181,"line":182},[179,22632,5474],{"class":549},[179,22634,22635],{"class":549}," record",[179,22637,22437],{"class":192},[179,22639,22640],{"class":681},"(String name, ",[179,22642,5728],{"class":549},[179,22644,22645],{"class":681}," age) {}\n",[17,22647,22648],{},[21,22649,22650],{},"Avantages :",[33,22652,22653,22656,22659,22662],{},[36,22654,22655],{},"Code réduit de ~30 lignes à 1 ligne",[36,22657,22658],{},"Immutabilité garantie",[36,22660,22661],{},"Equals/hashCode/toString générés automatiquement",[36,22663,22664],{},"Support des records dans les switch (pattern matching)",[10725,22666],{},[12,22668,22670],{"id":22669},"_2-pattern-matching-for-switch-java-21-preview-en-java-20","2. Pattern Matching for switch (Java 21, preview en Java 20)",[17,22672,22673],{},"Les expressions switch sont maintenant plus puissantes avec le pattern matching.",[53,22675,22677],{"id":22676},"java-8","Java 8",[102,22679,22681],{"className":5447,"code":22680,"language":652,"meta":111,"style":111},"Object obj = ...;\nif (obj instanceof String) {\n    String s = (String) obj;\n    System.out.println(s.toLowerCase());\n} else if (obj instanceof Integer) {\n    System.out.println(obj * 2);\n}\n",[109,22682,22683,22693,22706,22716,22732,22749,22764],{"__ignoreMap":111},[179,22684,22685,22688,22690],{"class":181,"line":182},[179,22686,22687],{"class":681},"Object obj ",[179,22689,685],{"class":549},[179,22691,22692],{"class":681}," ...;\n",[179,22694,22695,22697,22700,22703],{"class":181,"line":189},[179,22696,4772],{"class":549},[179,22698,22699],{"class":681}," (obj ",[179,22701,22702],{"class":549},"instanceof",[179,22704,22705],{"class":681}," String) {\n",[179,22707,22708,22711,22713],{"class":181,"line":448},[179,22709,22710],{"class":681},"    String s ",[179,22712,685],{"class":549},[179,22714,22715],{"class":681}," (String) obj;\n",[179,22717,22718,22721,22724,22727,22730],{"class":181,"line":775},[179,22719,22720],{"class":681},"    System.out.",[179,22722,22723],{"class":192},"println",[179,22725,22726],{"class":681},"(s.",[179,22728,22729],{"class":192},"toLowerCase",[179,22731,5611],{"class":681},[179,22733,22734,22736,22739,22742,22744,22746],{"class":181,"line":852},[179,22735,10356],{"class":681},[179,22737,22738],{"class":549},"else",[179,22740,22741],{"class":549}," if",[179,22743,22699],{"class":681},[179,22745,22702],{"class":549},[179,22747,22748],{"class":681}," Integer) {\n",[179,22750,22751,22753,22755,22758,22760,22762],{"class":181,"line":1351},[179,22752,22720],{"class":681},[179,22754,22723],{"class":192},[179,22756,22757],{"class":681},"(obj ",[179,22759,762],{"class":549},[179,22761,19511],{"class":224},[179,22763,3767],{"class":681},[179,22765,22766],{"class":181,"line":1363},[179,22767,3814],{"class":681},[53,22769,22771],{"id":22770},"java-20-preview-21-standard","Java 20 (preview) / 21 (standard)",[102,22773,22775],{"className":5447,"code":22774,"language":652,"meta":111,"style":111},"Object obj = ...;\nswitch (obj) {\n    case String s -> System.out.println(s.toLowerCase());\n    case Integer i -> System.out.println(i * 2);\n    case null -> System.out.println(\"Null value\");\n    default -> System.out.println(\"Unknown\");\n}\n",[109,22776,22777,22785,22792,22813,22835,22856,22874],{"__ignoreMap":111},[179,22778,22779,22781,22783],{"class":181,"line":182},[179,22780,22687],{"class":681},[179,22782,685],{"class":549},[179,22784,22692],{"class":681},[179,22786,22787,22789],{"class":181,"line":189},[179,22788,22269],{"class":549},[179,22790,22791],{"class":681}," (obj) {\n",[179,22793,22794,22797,22800,22802,22805,22807,22809,22811],{"class":181,"line":448},[179,22795,22796],{"class":549},"    case",[179,22798,22799],{"class":681}," String s ",[179,22801,5265],{"class":549},[179,22803,22804],{"class":681}," System.out.",[179,22806,22723],{"class":192},[179,22808,22726],{"class":681},[179,22810,22729],{"class":192},[179,22812,5611],{"class":681},[179,22814,22815,22817,22820,22822,22824,22826,22829,22831,22833],{"class":181,"line":775},[179,22816,22796],{"class":549},[179,22818,22819],{"class":681}," Integer i ",[179,22821,5265],{"class":549},[179,22823,22804],{"class":681},[179,22825,22723],{"class":192},[179,22827,22828],{"class":681},"(i ",[179,22830,762],{"class":549},[179,22832,19511],{"class":224},[179,22834,3767],{"class":681},[179,22836,22837,22839,22842,22845,22847,22849,22851,22854],{"class":181,"line":852},[179,22838,22796],{"class":549},[179,22840,22841],{"class":224}," null",[179,22843,22844],{"class":549}," ->",[179,22846,22804],{"class":681},[179,22848,22723],{"class":192},[179,22850,3761],{"class":681},[179,22852,22853],{"class":196},"\"Null value\"",[179,22855,3767],{"class":681},[179,22857,22858,22861,22863,22865,22867,22869,22872],{"class":181,"line":1351},[179,22859,22860],{"class":549},"    default",[179,22862,22844],{"class":549},[179,22864,22804],{"class":681},[179,22866,22723],{"class":192},[179,22868,3761],{"class":681},[179,22870,22871],{"class":196},"\"Unknown\"",[179,22873,3767],{"class":681},[179,22875,22876],{"class":181,"line":1363},[179,22877,3814],{"class":681},[53,22879,22881],{"id":22880},"records-avec-pattern-matching","Records avec pattern matching",[102,22883,22885],{"className":5447,"code":22884,"language":652,"meta":111,"style":111},"record Point(int x, int y) {}\n\nvoid process(Object o) {\n    switch (o) {\n        case Point(int x, int y) -> System.out.println(\"Point: \" + x + \",\" + y);\n        case null -> System.out.println(\"Nothing\");\n        default -> System.out.println(\"Other\");\n    }\n}\n",[109,22886,22887,22907,22911,22922,22930,22973,22992,23010,23014],{"__ignoreMap":111},[179,22888,22889,22892,22895,22897,22899,22902,22904],{"class":181,"line":182},[179,22890,22891],{"class":549},"record",[179,22893,22894],{"class":192}," Point",[179,22896,3761],{"class":681},[179,22898,5728],{"class":549},[179,22900,22901],{"class":681}," x, ",[179,22903,5728],{"class":549},[179,22905,22906],{"class":681}," y) {}\n",[179,22908,22909],{"class":181,"line":189},[179,22910,1404],{"emptyLinePlaceholder":477},[179,22912,22913,22916,22919],{"class":181,"line":448},[179,22914,22915],{"class":549},"void",[179,22917,22918],{"class":192}," process",[179,22920,22921],{"class":681},"(Object o) {\n",[179,22923,22924,22927],{"class":181,"line":775},[179,22925,22926],{"class":549},"    switch",[179,22928,22929],{"class":681}," (o) {\n",[179,22931,22932,22935,22937,22939,22941,22943,22945,22948,22950,22952,22954,22956,22959,22961,22963,22965,22968,22970],{"class":181,"line":852},[179,22933,22934],{"class":549},"        case",[179,22936,22894],{"class":192},[179,22938,3761],{"class":681},[179,22940,5728],{"class":549},[179,22942,22901],{"class":681},[179,22944,5728],{"class":549},[179,22946,22947],{"class":681}," y) ",[179,22949,5265],{"class":549},[179,22951,22804],{"class":681},[179,22953,22723],{"class":192},[179,22955,3761],{"class":681},[179,22957,22958],{"class":196},"\"Point: \"",[179,22960,6442],{"class":549},[179,22962,10288],{"class":681},[179,22964,5753],{"class":549},[179,22966,22967],{"class":196}," \",\"",[179,22969,6442],{"class":549},[179,22971,22972],{"class":681}," y);\n",[179,22974,22975,22977,22979,22981,22983,22985,22987,22990],{"class":181,"line":1351},[179,22976,22934],{"class":549},[179,22978,22841],{"class":224},[179,22980,22844],{"class":549},[179,22982,22804],{"class":681},[179,22984,22723],{"class":192},[179,22986,3761],{"class":681},[179,22988,22989],{"class":196},"\"Nothing\"",[179,22991,3767],{"class":681},[179,22993,22994,22997,22999,23001,23003,23005,23008],{"class":181,"line":1363},[179,22995,22996],{"class":549},"        default",[179,22998,22844],{"class":549},[179,23000,22804],{"class":681},[179,23002,22723],{"class":192},[179,23004,3761],{"class":681},[179,23006,23007],{"class":196},"\"Other\"",[179,23009,3767],{"class":681},[179,23011,23012],{"class":181,"line":1381},[179,23013,5320],{"class":681},[179,23015,23016],{"class":181,"line":1401},[179,23017,3814],{"class":681},[10725,23019],{},[12,23021,23023],{"id":23022},"_3-text-blocks-java-15-standard-en-java-16","3. Text Blocks (Java 15, standard en Java 16)",[17,23025,23026],{},"Les text blocks simplifient l'écriture de chaînes multilignes.",[53,23028,22677],{"id":23029},"java-8-1",[102,23031,23033],{"className":5447,"code":23032,"language":652,"meta":111,"style":111},"String json = \"{\\n\" +\n    \"  \\\"name\\\": \\\"John\\\",\\n\" +\n    \"  \\\"age\\\": 30\\n\" +\n    \"}\";\n",[109,23034,23035,23053,23083,23103],{"__ignoreMap":111},[179,23036,23037,23040,23042,23045,23048,23050],{"class":181,"line":182},[179,23038,23039],{"class":681},"String json ",[179,23041,685],{"class":549},[179,23043,23044],{"class":196}," \"{",[179,23046,23047],{"class":224},"\\n",[179,23049,5813],{"class":196},[179,23051,23052],{"class":549}," +\n",[179,23054,23055,23058,23061,23063,23065,23067,23069,23072,23074,23077,23079,23081],{"class":181,"line":189},[179,23056,23057],{"class":196},"    \"  ",[179,23059,23060],{"class":224},"\\\"",[179,23062,3833],{"class":196},[179,23064,23060],{"class":224},[179,23066,4251],{"class":196},[179,23068,23060],{"class":224},[179,23070,23071],{"class":196},"John",[179,23073,23060],{"class":224},[179,23075,23076],{"class":196},",",[179,23078,23047],{"class":224},[179,23080,5813],{"class":196},[179,23082,23052],{"class":549},[179,23084,23085,23087,23089,23092,23094,23097,23099,23101],{"class":181,"line":448},[179,23086,23057],{"class":196},[179,23088,23060],{"class":224},[179,23090,23091],{"class":196},"age",[179,23093,23060],{"class":224},[179,23095,23096],{"class":196},": 30",[179,23098,23047],{"class":224},[179,23100,5813],{"class":196},[179,23102,23052],{"class":549},[179,23104,23105,23108],{"class":181,"line":775},[179,23106,23107],{"class":196},"    \"}\"",[179,23109,3850],{"class":681},[53,23111,22623],{"id":23112},"java-20-1",[102,23114,23116],{"className":5447,"code":23115,"language":652,"meta":111,"style":111},"String json = \"\"\"\n{\n  \"name\": \"John\",\n  \"age\": 30\n}\n\"\"\";\n",[109,23117,23118,23127,23131,23136,23141,23145],{"__ignoreMap":111},[179,23119,23120,23122,23124],{"class":181,"line":182},[179,23121,23039],{"class":681},[179,23123,685],{"class":549},[179,23125,23126],{"class":196}," \"\"\"\n",[179,23128,23129],{"class":181,"line":189},[179,23130,4851],{"class":196},[179,23132,23133],{"class":181,"line":448},[179,23134,23135],{"class":196},"  \"name\": \"John\",\n",[179,23137,23138],{"class":181,"line":775},[179,23139,23140],{"class":196},"  \"age\": 30\n",[179,23142,23143],{"class":181,"line":852},[179,23144,3814],{"class":196},[179,23146,23147,23150],{"class":181,"line":1351},[179,23148,23149],{"class":196},"\"\"\"",[179,23151,3850],{"class":681},[17,23153,23154],{},[21,23155,22650],{},[33,23157,23158,23161,23164],{},[36,23159,23160],{},"Pas besoin d'échapper les quotes",[36,23162,23163],{},"Meilleure lisibilité",[36,23165,23166],{},"Indentation naturelle",[10725,23168],{},[12,23170,23172],{"id":23171},"_4-optional-améliorations-java-9","4. Optional Améliorations (Java 9+)",[17,23174,23175],{},"Java 8 a introduit Optional, mais Java 9+ l'a enrichi.",[53,23177,22677],{"id":23178},"java-8-2",[102,23180,23182],{"className":5447,"code":23181,"language":652,"meta":111,"style":111},"Optional\u003CString> optional = Optional.ofNullable(getValue());\nif (optional.isPresent()) {\n    System.out.println(optional.get().toUpperCase());\n}\n",[109,23183,23184,23209,23222,23240],{"__ignoreMap":111},[179,23185,23186,23189,23191,23194,23196,23199,23202,23204,23207],{"class":181,"line":182},[179,23187,23188],{"class":681},"Optional\u003C",[179,23190,5540],{"class":549},[179,23192,23193],{"class":681},"> optional ",[179,23195,685],{"class":549},[179,23197,23198],{"class":681}," Optional.",[179,23200,23201],{"class":192},"ofNullable",[179,23203,3761],{"class":681},[179,23205,23206],{"class":192},"getValue",[179,23208,5611],{"class":681},[179,23210,23211,23213,23216,23219],{"class":181,"line":189},[179,23212,4772],{"class":549},[179,23214,23215],{"class":681}," (optional.",[179,23217,23218],{"class":192},"isPresent",[179,23220,23221],{"class":681},"()) {\n",[179,23223,23224,23226,23228,23231,23233,23235,23238],{"class":181,"line":448},[179,23225,22720],{"class":681},[179,23227,22723],{"class":192},[179,23229,23230],{"class":681},"(optional.",[179,23232,1610],{"class":192},[179,23234,5559],{"class":681},[179,23236,23237],{"class":192},"toUpperCase",[179,23239,5611],{"class":681},[179,23241,23242],{"class":181,"line":775},[179,23243,3814],{"class":681},[53,23245,23247],{"id":23246},"java-20-avec-améliorations-successives","Java 20 (avec améliorations successives)",[102,23249,23251],{"className":5447,"code":23250,"language":652,"meta":111,"style":111},"Optional\u003CString> optional = Optional.ofNullable(getValue());\n\n// Optional.or() - Java 9\nOptional\u003CString> result = optional.or(() -> Optional.of(\"default\"));\n\n// Optional.stream() - Java 9\noptional.stream().forEach(System.out::println);\n\n// Optional.isEmpty() - Java 11\nif (optional.isEmpty()) {\n    System.out.println(\"No value\");\n}\n",[109,23252,23253,23273,23277,23282,23316,23320,23325,23345,23349,23354,23365,23378],{"__ignoreMap":111},[179,23254,23255,23257,23259,23261,23263,23265,23267,23269,23271],{"class":181,"line":182},[179,23256,23188],{"class":681},[179,23258,5540],{"class":549},[179,23260,23193],{"class":681},[179,23262,685],{"class":549},[179,23264,23198],{"class":681},[179,23266,23201],{"class":192},[179,23268,3761],{"class":681},[179,23270,23206],{"class":192},[179,23272,5611],{"class":681},[179,23274,23275],{"class":181,"line":189},[179,23276,1404],{"emptyLinePlaceholder":477},[179,23278,23279],{"class":181,"line":448},[179,23280,23281],{"class":185},"// Optional.or() - Java 9\n",[179,23283,23284,23286,23288,23291,23293,23296,23299,23302,23304,23306,23309,23311,23314],{"class":181,"line":775},[179,23285,23188],{"class":681},[179,23287,5540],{"class":549},[179,23289,23290],{"class":681},"> result ",[179,23292,685],{"class":549},[179,23294,23295],{"class":681}," optional.",[179,23297,23298],{"class":192},"or",[179,23300,23301],{"class":681},"(() ",[179,23303,5265],{"class":549},[179,23305,23198],{"class":681},[179,23307,23308],{"class":192},"of",[179,23310,3761],{"class":681},[179,23312,23313],{"class":196},"\"default\"",[179,23315,3871],{"class":681},[179,23317,23318],{"class":181,"line":852},[179,23319,1404],{"emptyLinePlaceholder":477},[179,23321,23322],{"class":181,"line":1351},[179,23323,23324],{"class":185},"// Optional.stream() - Java 9\n",[179,23326,23327,23330,23332,23334,23337,23340,23342],{"class":181,"line":1363},[179,23328,23329],{"class":681},"optional.",[179,23331,5562],{"class":192},[179,23333,5559],{"class":681},[179,23335,23336],{"class":192},"forEach",[179,23338,23339],{"class":681},"(System.out",[179,23341,5578],{"class":549},[179,23343,23344],{"class":681},"println);\n",[179,23346,23347],{"class":181,"line":1381},[179,23348,1404],{"emptyLinePlaceholder":477},[179,23350,23351],{"class":181,"line":1401},[179,23352,23353],{"class":185},"// Optional.isEmpty() - Java 11\n",[179,23355,23356,23358,23360,23363],{"class":181,"line":1407},[179,23357,4772],{"class":549},[179,23359,23215],{"class":681},[179,23361,23362],{"class":192},"isEmpty",[179,23364,23221],{"class":681},[179,23366,23367,23369,23371,23373,23376],{"class":181,"line":1418},[179,23368,22720],{"class":681},[179,23370,22723],{"class":192},[179,23372,3761],{"class":681},[179,23374,23375],{"class":196},"\"No value\"",[179,23377,3767],{"class":681},[179,23379,23380],{"class":181,"line":1435},[179,23381,3814],{"class":681},[10725,23383],{},[12,23385,23387],{"id":23386},"_5-virtual-threads-project-loom-java-21-preview-en-java-20","5. Virtual Threads (Project Loom, Java 21, preview en Java 20)",[17,23389,23390],{},"Les virtual threads révolutionnent la concurrence avec des threads légers.",[53,23392,23394],{"id":23393},"java-8-platform-threads","Java 8 (platform threads)",[102,23396,23398],{"className":5447,"code":23397,"language":652,"meta":111,"style":111},"// Chaque thread = 1 OS thread (coûteux)\nExecutorService executor = Executors.newFixedThreadPool(100);\nexecutor.submit(() -> {\n    // Traitement\n});\n",[109,23399,23400,23405,23425,23439,23444],{"__ignoreMap":111},[179,23401,23402],{"class":181,"line":182},[179,23403,23404],{"class":185},"// Chaque thread = 1 OS thread (coûteux)\n",[179,23406,23407,23410,23412,23415,23418,23420,23423],{"class":181,"line":189},[179,23408,23409],{"class":681},"ExecutorService executor ",[179,23411,685],{"class":549},[179,23413,23414],{"class":681}," Executors.",[179,23416,23417],{"class":192},"newFixedThreadPool",[179,23419,3761],{"class":681},[179,23421,23422],{"class":224},"100",[179,23424,3767],{"class":681},[179,23426,23427,23430,23433,23435,23437],{"class":181,"line":448},[179,23428,23429],{"class":681},"executor.",[179,23431,23432],{"class":192},"submit",[179,23434,23301],{"class":681},[179,23436,5265],{"class":549},[179,23438,3892],{"class":681},[179,23440,23441],{"class":181,"line":775},[179,23442,23443],{"class":185},"    // Traitement\n",[179,23445,23446],{"class":181,"line":852},[179,23447,6732],{"class":681},[53,23449,23451],{"id":23450},"java-2021-virtual-threads","Java 20/21 (virtual threads)",[102,23453,23455],{"className":5447,"code":23454,"language":652,"meta":111,"style":111},"// Virtual threads - légers, millions peuvent coexister\nExecutorService executor = Executors.newVirtualThreadPerTaskExecutor();\nexecutor.submit(() -> {\n    // Traitement\n});\n",[109,23456,23457,23462,23475,23487,23491],{"__ignoreMap":111},[179,23458,23459],{"class":181,"line":182},[179,23460,23461],{"class":185},"// Virtual threads - légers, millions peuvent coexister\n",[179,23463,23464,23466,23468,23470,23473],{"class":181,"line":189},[179,23465,23409],{"class":681},[179,23467,685],{"class":549},[179,23469,23414],{"class":681},[179,23471,23472],{"class":192},"newVirtualThreadPerTaskExecutor",[179,23474,3786],{"class":681},[179,23476,23477,23479,23481,23483,23485],{"class":181,"line":448},[179,23478,23429],{"class":681},[179,23480,23432],{"class":192},[179,23482,23301],{"class":681},[179,23484,5265],{"class":549},[179,23486,3892],{"class":681},[179,23488,23489],{"class":181,"line":775},[179,23490,23443],{"class":185},[179,23492,23493],{"class":181,"line":852},[179,23494,6732],{"class":681},[17,23496,23497,23500],{},[21,23498,23499],{},"Cas d'usage :"," Serveurs haute concurrence, microservices.",[10725,23502],{},[12,23504,23506],{"id":23505},"_6-switch-expressions-java-14-standard-en-java-12","6. Switch Expressions (Java 14, standard en Java 12)",[17,23508,23509,23510,436],{},"Les switch deviennent des expressions avec ",[109,23511,23512],{},"yield",[53,23514,22677],{"id":23515},"java-8-3",[102,23517,23519],{"className":5447,"code":23518,"language":652,"meta":111,"style":111},"int days;\nswitch (month) {\n    case 1: case 3: case 5: case 7: case 8: case 10: case 12:\n        days = 31;\n        break;\n    case 4: case 6: case 9: case 11:\n        days = 30;\n        break;\n    case 2:\n        days = 28;\n        break;\n    default:\n        days = 0;\n}\n",[109,23520,23521,23528,23535,23584,23596,23603,23633,23644,23650,23658,23669,23675,23680,23690],{"__ignoreMap":111},[179,23522,23523,23525],{"class":181,"line":182},[179,23524,5728],{"class":549},[179,23526,23527],{"class":681}," days;\n",[179,23529,23530,23532],{"class":181,"line":189},[179,23531,22269],{"class":549},[179,23533,23534],{"class":681}," (month) {\n",[179,23536,23537,23539,23541,23543,23546,23549,23551,23553,23555,23557,23559,23562,23564,23566,23569,23571,23573,23575,23577,23579,23582],{"class":181,"line":448},[179,23538,22796],{"class":549},[179,23540,16208],{"class":224},[179,23542,3900],{"class":549},[179,23544,23545],{"class":549}," case",[179,23547,23548],{"class":224}," 3",[179,23550,3900],{"class":549},[179,23552,23545],{"class":549},[179,23554,13976],{"class":224},[179,23556,3900],{"class":549},[179,23558,23545],{"class":549},[179,23560,23561],{"class":224}," 7",[179,23563,3900],{"class":549},[179,23565,23545],{"class":549},[179,23567,23568],{"class":224}," 8",[179,23570,3900],{"class":549},[179,23572,23545],{"class":549},[179,23574,5439],{"class":224},[179,23576,3900],{"class":549},[179,23578,23545],{"class":549},[179,23580,23581],{"class":224}," 12",[179,23583,4966],{"class":549},[179,23585,23586,23589,23591,23594],{"class":181,"line":775},[179,23587,23588],{"class":681},"        days ",[179,23590,685],{"class":549},[179,23592,23593],{"class":224}," 31",[179,23595,3850],{"class":681},[179,23597,23598,23601],{"class":181,"line":852},[179,23599,23600],{"class":549},"        break",[179,23602,3850],{"class":681},[179,23604,23605,23607,23610,23612,23614,23617,23619,23621,23624,23626,23628,23631],{"class":181,"line":1351},[179,23606,22796],{"class":549},[179,23608,23609],{"class":224}," 4",[179,23611,3900],{"class":549},[179,23613,23545],{"class":549},[179,23615,23616],{"class":224}," 6",[179,23618,3900],{"class":549},[179,23620,23545],{"class":549},[179,23622,23623],{"class":224}," 9",[179,23625,3900],{"class":549},[179,23627,23545],{"class":549},[179,23629,23630],{"class":224}," 11",[179,23632,4966],{"class":549},[179,23634,23635,23637,23639,23642],{"class":181,"line":1363},[179,23636,23588],{"class":681},[179,23638,685],{"class":549},[179,23640,23641],{"class":224}," 30",[179,23643,3850],{"class":681},[179,23645,23646,23648],{"class":181,"line":1381},[179,23647,23600],{"class":549},[179,23649,3850],{"class":681},[179,23651,23652,23654,23656],{"class":181,"line":1401},[179,23653,22796],{"class":549},[179,23655,19511],{"class":224},[179,23657,4966],{"class":549},[179,23659,23660,23662,23664,23667],{"class":181,"line":1407},[179,23661,23588],{"class":681},[179,23663,685],{"class":549},[179,23665,23666],{"class":224}," 28",[179,23668,3850],{"class":681},[179,23670,23671,23673],{"class":181,"line":1418},[179,23672,23600],{"class":549},[179,23674,3850],{"class":681},[179,23676,23677],{"class":181,"line":1435},[179,23678,23679],{"class":549},"    default:\n",[179,23681,23682,23684,23686,23688],{"class":181,"line":1440},[179,23683,23588],{"class":681},[179,23685,685],{"class":549},[179,23687,13962],{"class":224},[179,23689,3850],{"class":681},[179,23691,23692],{"class":181,"line":1450},[179,23693,3814],{"class":681},[53,23695,22623],{"id":23696},"java-20-2",[102,23698,23700],{"className":5447,"code":23699,"language":652,"meta":111,"style":111},"int days = switch (month) {\n    case 1, 3, 5, 7, 8, 10, 12 -> 31;\n    case 4, 6, 9, 11 -> 30;\n    case 2 -> 28;\n    default -> 0;\n};\n",[109,23701,23702,23716,23757,23784,23796,23806],{"__ignoreMap":111},[179,23703,23704,23706,23709,23711,23714],{"class":181,"line":182},[179,23705,5728],{"class":549},[179,23707,23708],{"class":681}," days ",[179,23710,685],{"class":549},[179,23712,23713],{"class":549}," switch",[179,23715,23534],{"class":681},[179,23717,23718,23720,23722,23724,23727,23729,23732,23734,23737,23739,23741,23743,23746,23748,23751,23753,23755],{"class":181,"line":189},[179,23719,22796],{"class":549},[179,23721,16208],{"class":224},[179,23723,5355],{"class":681},[179,23725,23726],{"class":224},"3",[179,23728,5355],{"class":681},[179,23730,23731],{"class":224},"5",[179,23733,5355],{"class":681},[179,23735,23736],{"class":224},"7",[179,23738,5355],{"class":681},[179,23740,4346],{"class":224},[179,23742,5355],{"class":681},[179,23744,23745],{"class":224},"10",[179,23747,5355],{"class":681},[179,23749,23750],{"class":224},"12",[179,23752,22844],{"class":549},[179,23754,23593],{"class":224},[179,23756,3850],{"class":681},[179,23758,23759,23761,23763,23765,23768,23770,23773,23775,23778,23780,23782],{"class":181,"line":448},[179,23760,22796],{"class":549},[179,23762,23609],{"class":224},[179,23764,5355],{"class":681},[179,23766,23767],{"class":224},"6",[179,23769,5355],{"class":681},[179,23771,23772],{"class":224},"9",[179,23774,5355],{"class":681},[179,23776,23777],{"class":224},"11",[179,23779,22844],{"class":549},[179,23781,23641],{"class":224},[179,23783,3850],{"class":681},[179,23785,23786,23788,23790,23792,23794],{"class":181,"line":775},[179,23787,22796],{"class":549},[179,23789,19511],{"class":224},[179,23791,22844],{"class":549},[179,23793,23666],{"class":224},[179,23795,3850],{"class":681},[179,23797,23798,23800,23802,23804],{"class":181,"line":852},[179,23799,22860],{"class":549},[179,23801,22844],{"class":549},[179,23803,13962],{"class":224},[179,23805,3850],{"class":681},[179,23807,23808],{"class":181,"line":1351},[179,23809,12994],{"class":681},[17,23811,23812,23813,23815],{},"Avec ",[109,23814,23512],{}," pour des blocs plus complexes :",[102,23817,23819],{"className":5447,"code":23818,"language":652,"meta":111,"style":111},"int result = switch (value) {\n    case 1 -> {\n        yield 10;\n    }\n    case 2 -> {\n        int x = value * 2;\n        yield x + 5;\n    }\n    default -> 0;\n};\n",[109,23820,23821,23835,23845,23854,23858,23868,23886,23898,23902,23912],{"__ignoreMap":111},[179,23822,23823,23825,23828,23830,23832],{"class":181,"line":182},[179,23824,5728],{"class":549},[179,23826,23827],{"class":681}," result ",[179,23829,685],{"class":549},[179,23831,23713],{"class":549},[179,23833,23834],{"class":681}," (value) {\n",[179,23836,23837,23839,23841,23843],{"class":181,"line":189},[179,23838,22796],{"class":549},[179,23840,16208],{"class":224},[179,23842,22844],{"class":549},[179,23844,3892],{"class":681},[179,23846,23847,23850,23852],{"class":181,"line":448},[179,23848,23849],{"class":549},"        yield",[179,23851,5439],{"class":224},[179,23853,3850],{"class":681},[179,23855,23856],{"class":181,"line":775},[179,23857,5320],{"class":681},[179,23859,23860,23862,23864,23866],{"class":181,"line":852},[179,23861,22796],{"class":549},[179,23863,19511],{"class":224},[179,23865,22844],{"class":549},[179,23867,3892],{"class":681},[179,23869,23870,23873,23875,23877,23880,23882,23884],{"class":181,"line":1351},[179,23871,23872],{"class":549},"        int",[179,23874,10288],{"class":681},[179,23876,685],{"class":549},[179,23878,23879],{"class":681}," value ",[179,23881,762],{"class":549},[179,23883,19511],{"class":224},[179,23885,3850],{"class":681},[179,23887,23888,23890,23892,23894,23896],{"class":181,"line":1363},[179,23889,23849],{"class":549},[179,23891,10288],{"class":681},[179,23893,5753],{"class":549},[179,23895,13976],{"class":224},[179,23897,3850],{"class":681},[179,23899,23900],{"class":181,"line":1381},[179,23901,5320],{"class":681},[179,23903,23904,23906,23908,23910],{"class":181,"line":1401},[179,23905,22860],{"class":549},[179,23907,22844],{"class":549},[179,23909,13962],{"class":224},[179,23911,3850],{"class":681},[179,23913,23914],{"class":181,"line":1407},[179,23915,12994],{"class":681},[10725,23917],{},[12,23919,23921],{"id":23920},"_7-records-patterns-java-21","7. Records Patterns (Java 21)",[17,23923,23924],{},"Les records s'intègrent parfaitement avec les patterns.",[102,23926,23928],{"className":5447,"code":23927,"language":652,"meta":111,"style":111},"record Point(int x, int y) {}\nrecord Rectangle(Point upperLeft, Point lowerRight) {}\n\nvoid process(Rectangle rect) {\n    // Déconstruction directe\n    if (rect instanceof Rectangle(Point(int x1, int y1), Point(int x2, int y2))) {\n        System.out.println(\"Rectangle from (\" + x1 + \",\" + y1 + \") to (\" + x2 + \",\" + y2 + \")\");\n    }\n}\n",[109,23929,23930,23946,23956,23960,23969,23974,24016,24068,24072],{"__ignoreMap":111},[179,23931,23932,23934,23936,23938,23940,23942,23944],{"class":181,"line":182},[179,23933,22891],{"class":549},[179,23935,22894],{"class":192},[179,23937,3761],{"class":681},[179,23939,5728],{"class":549},[179,23941,22901],{"class":681},[179,23943,5728],{"class":549},[179,23945,22906],{"class":681},[179,23947,23948,23950,23953],{"class":181,"line":189},[179,23949,22891],{"class":549},[179,23951,23952],{"class":192}," Rectangle",[179,23954,23955],{"class":681},"(Point upperLeft, Point lowerRight) {}\n",[179,23957,23958],{"class":181,"line":448},[179,23959,1404],{"emptyLinePlaceholder":477},[179,23961,23962,23964,23966],{"class":181,"line":775},[179,23963,22915],{"class":549},[179,23965,22918],{"class":192},[179,23967,23968],{"class":681},"(Rectangle rect) {\n",[179,23970,23971],{"class":181,"line":852},[179,23972,23973],{"class":185},"    // Déconstruction directe\n",[179,23975,23976,23978,23981,23983,23985,23987,23990,23992,23994,23997,23999,24002,24004,24006,24008,24011,24013],{"class":181,"line":1351},[179,23977,13635],{"class":549},[179,23979,23980],{"class":681}," (rect ",[179,23982,22702],{"class":549},[179,23984,23952],{"class":192},[179,23986,3761],{"class":681},[179,23988,23989],{"class":192},"Point",[179,23991,3761],{"class":681},[179,23993,5728],{"class":549},[179,23995,23996],{"class":681}," x1, ",[179,23998,5728],{"class":549},[179,24000,24001],{"class":681}," y1), ",[179,24003,23989],{"class":192},[179,24005,3761],{"class":681},[179,24007,5728],{"class":549},[179,24009,24010],{"class":681}," x2, ",[179,24012,5728],{"class":549},[179,24014,24015],{"class":681}," y2))) {\n",[179,24017,24018,24021,24023,24025,24028,24030,24033,24035,24037,24039,24042,24044,24047,24049,24052,24054,24056,24058,24061,24063,24066],{"class":181,"line":1363},[179,24019,24020],{"class":681},"        System.out.",[179,24022,22723],{"class":192},[179,24024,3761],{"class":681},[179,24026,24027],{"class":196},"\"Rectangle from (\"",[179,24029,6442],{"class":549},[179,24031,24032],{"class":681}," x1 ",[179,24034,5753],{"class":549},[179,24036,22967],{"class":196},[179,24038,6442],{"class":549},[179,24040,24041],{"class":681}," y1 ",[179,24043,5753],{"class":549},[179,24045,24046],{"class":196}," \") to (\"",[179,24048,6442],{"class":549},[179,24050,24051],{"class":681}," x2 ",[179,24053,5753],{"class":549},[179,24055,22967],{"class":196},[179,24057,6442],{"class":549},[179,24059,24060],{"class":681}," y2 ",[179,24062,5753],{"class":549},[179,24064,24065],{"class":196}," \")\"",[179,24067,3767],{"class":681},[179,24069,24070],{"class":181,"line":1381},[179,24071,5320],{"class":681},[179,24073,24074],{"class":181,"line":1401},[179,24075,3814],{"class":681},[10725,24077],{},[12,24079,24081],{"id":24080},"_8-strongly-encapsulate-jdk-internals-java-16","8. Strongly Encapsulate JDK Internals (Java 16+)",[17,24083,24084,24085,24088],{},"Par défaut, l'accès aux API internes (",[109,24086,24087],{},"sun.misc.Unsafe",", etc.) est restreint.",[53,24090,24092],{"id":24091},"message-derreur-typique","Message d'erreur typique",[102,24094,24097],{"className":24095,"code":24096,"language":107},[105],"ERROR: Access denied for sun.misc.Unsafe\n",[109,24098,24096],{"__ignoreMap":111},[53,24100,21729],{"id":24101},"solution",[17,24103,24104],{},"Soit on utilise l'API officielle, soit on ajoute des options :",[102,24106,24108],{"className":173,"code":24107,"language":175,"meta":111,"style":111},"--add-opens java.base/java.util=ALL-UNNAMED\n",[109,24109,24110],{"__ignoreMap":111},[179,24111,24112,24115],{"class":181,"line":182},[179,24113,24114],{"class":192},"--add-opens",[179,24116,24117],{"class":196}," java.base/java.util=ALL-UNNAMED\n",[17,24119,24120,24123],{},[21,24121,24122],{},"Meilleure pratique :"," Éviter les internal APIs, utiliser les alternatives officielles.",[10725,24125],{},[12,24127,24129],{"id":24128},"_9-type-inference-for-local-variables-java-10","9. Type Inference for Local Variables (Java 10)",[17,24131,24132,24133,24136],{},"Le mot-clé ",[109,24134,24135],{},"var"," pour les variables locales.",[53,24138,22677],{"id":24139},"java-8-4",[102,24141,24143],{"className":5447,"code":24142,"language":652,"meta":111,"style":111},"List\u003CString> list = new ArrayList\u003C>();\nMap\u003CString, Integer> map = new HashMap\u003C>();\n",[109,24144,24145,24162],{"__ignoreMap":111},[179,24146,24147,24150,24152,24155,24157,24159],{"class":181,"line":182},[179,24148,24149],{"class":681},"List\u003C",[179,24151,5540],{"class":549},[179,24153,24154],{"class":681},"> list ",[179,24156,685],{"class":549},[179,24158,10445],{"class":549},[179,24160,24161],{"class":681}," ArrayList\u003C>();\n",[179,24163,24164,24167,24169,24171,24174,24177,24179,24181],{"class":181,"line":189},[179,24165,24166],{"class":681},"Map\u003C",[179,24168,5540],{"class":549},[179,24170,5355],{"class":681},[179,24172,24173],{"class":549},"Integer",[179,24175,24176],{"class":681},"> map ",[179,24178,685],{"class":549},[179,24180,10445],{"class":549},[179,24182,24183],{"class":681}," HashMap\u003C>();\n",[53,24185,22623],{"id":24186},"java-20-3",[102,24188,24190],{"className":5447,"code":24189,"language":652,"meta":111,"style":111},"var list = new ArrayList\u003CString>();\nvar map = new HashMap\u003CString, Integer>();\n",[109,24191,24192,24211],{"__ignoreMap":111},[179,24193,24194,24196,24199,24201,24203,24206,24208],{"class":181,"line":182},[179,24195,24135],{"class":549},[179,24197,24198],{"class":681}," list ",[179,24200,685],{"class":549},[179,24202,10445],{"class":549},[179,24204,24205],{"class":681}," ArrayList\u003C",[179,24207,5540],{"class":549},[179,24209,24210],{"class":681},">();\n",[179,24212,24213,24215,24218,24220,24222,24225,24227,24229,24231],{"class":181,"line":189},[179,24214,24135],{"class":549},[179,24216,24217],{"class":681}," map ",[179,24219,685],{"class":549},[179,24221,10445],{"class":549},[179,24223,24224],{"class":681}," HashMap\u003C",[179,24226,5540],{"class":549},[179,24228,5355],{"class":681},[179,24230,24173],{"class":549},[179,24232,24210],{"class":681},[17,24234,24235,24238,24239,24241],{},[21,24236,24237],{},"Note :"," ",[109,24240,24135],{}," n'est pas une keyword, juste un type réservé. Ne s'applique qu'aux variables locales.",[10725,24243],{},[12,24245,24247],{"id":24246},"_10-multi-file-source-code-execution-java-11","10. Multi-File Source-Code Execution (Java 11+)",[17,24249,24250],{},"Lancer un fichier Java unique sans compilation préalable.",[53,24252,22677],{"id":24253},"java-8-5",[102,24255,24257],{"className":173,"code":24256,"language":175,"meta":111,"style":111},"javac Main.java\njava Main\n",[109,24258,24259,24267],{"__ignoreMap":111},[179,24260,24261,24264],{"class":181,"line":182},[179,24262,24263],{"class":192},"javac",[179,24265,24266],{"class":196}," Main.java\n",[179,24268,24269,24271],{"class":181,"line":189},[179,24270,652],{"class":192},[179,24272,24273],{"class":196}," Main\n",[53,24275,22623],{"id":24276},"java-20-4",[102,24278,24280],{"className":173,"code":24279,"language":175,"meta":111,"style":111},"java Main.java\n",[109,24281,24282],{"__ignoreMap":111},[179,24283,24284,24286],{"class":181,"line":182},[179,24285,652],{"class":192},[179,24287,24266],{"class":196},[17,24289,24290],{},"Fonctionne même avec plusieurs fichiers dans le même répertoire.",[10725,24292],{},[12,24294,24296],{"id":24295},"_11-concise-method-bodies-java-21-preview","11. Concise Method Bodies (Java 21, preview)",[17,24298,24299],{},"Syntaxe simplifiée pour les méthodes sans paramètres.",[102,24301,24303],{"className":5447,"code":24302,"language":652,"meta":111,"style":111},"// Preview en Java 21\nclass DateUtils {\n    int year() { 365; }  // Return implicite\n    \n    String season() {\n        switch (month) {\n            case 12, 1, 2 -> \"Winter\";\n            case 3, 4, 5 -> \"Spring\";\n            // ...\n        }\n    }\n}\n",[109,24304,24305,24310,24319,24338,24342,24352,24359,24381,24403,24408,24412,24416],{"__ignoreMap":111},[179,24306,24307],{"class":181,"line":182},[179,24308,24309],{"class":185},"// Preview en Java 21\n",[179,24311,24312,24314,24317],{"class":181,"line":189},[179,24313,5187],{"class":549},[179,24315,24316],{"class":192}," DateUtils",[179,24318,3892],{"class":681},[179,24320,24321,24324,24327,24329,24332,24335],{"class":181,"line":448},[179,24322,24323],{"class":549},"    int",[179,24325,24326],{"class":192}," year",[179,24328,22528],{"class":681},[179,24330,24331],{"class":224},"365",[179,24333,24334],{"class":681},"; }  ",[179,24336,24337],{"class":185},"// Return implicite\n",[179,24339,24340],{"class":181,"line":775},[179,24341,11995],{"class":681},[179,24343,24344,24347,24350],{"class":181,"line":852},[179,24345,24346],{"class":681},"    String ",[179,24348,24349],{"class":192},"season",[179,24351,3741],{"class":681},[179,24353,24354,24357],{"class":181,"line":1351},[179,24355,24356],{"class":549},"        switch",[179,24358,23534],{"class":681},[179,24360,24361,24364,24366,24368,24370,24372,24374,24376,24379],{"class":181,"line":1363},[179,24362,24363],{"class":549},"            case",[179,24365,23581],{"class":224},[179,24367,5355],{"class":681},[179,24369,4331],{"class":224},[179,24371,5355],{"class":681},[179,24373,4457],{"class":224},[179,24375,22844],{"class":549},[179,24377,24378],{"class":196}," \"Winter\"",[179,24380,3850],{"class":681},[179,24382,24383,24385,24387,24389,24392,24394,24396,24398,24401],{"class":181,"line":1381},[179,24384,24363],{"class":549},[179,24386,23548],{"class":224},[179,24388,5355],{"class":681},[179,24390,24391],{"class":224},"4",[179,24393,5355],{"class":681},[179,24395,23731],{"class":224},[179,24397,22844],{"class":549},[179,24399,24400],{"class":196}," \"Spring\"",[179,24402,3850],{"class":681},[179,24404,24405],{"class":181,"line":1401},[179,24406,24407],{"class":185},"            // ...\n",[179,24409,24410],{"class":181,"line":1407},[179,24411,12015],{"class":681},[179,24413,24414],{"class":181,"line":1418},[179,24415,5320],{"class":681},[179,24417,24418],{"class":181,"line":1435},[179,24419,3814],{"class":681},[10725,24421],{},[12,24423,24425],{"id":24424},"migration-checklist-pratique","Migration : Checklist Pratique",[53,24427,24429],{"id":24428},"étape-1-mise-à-jour-du-jdk","Étape 1 : Mise à jour du JDK",[102,24431,24433],{"className":173,"code":24432,"language":175,"meta":111,"style":111},"# Vérifier la version\njava -version\n\n# Installer Java 20/21\n# Ubuntu/Debian : apt install openjdk-21-jdk\n# macOS : brew install openjdk\n",[109,24434,24435,24440,24446,24450,24455,24460],{"__ignoreMap":111},[179,24436,24437],{"class":181,"line":182},[179,24438,24439],{"class":185},"# Vérifier la version\n",[179,24441,24442,24444],{"class":181,"line":189},[179,24443,652],{"class":192},[179,24445,655],{"class":224},[179,24447,24448],{"class":181,"line":448},[179,24449,1404],{"emptyLinePlaceholder":477},[179,24451,24452],{"class":181,"line":775},[179,24453,24454],{"class":185},"# Installer Java 20/21\n",[179,24456,24457],{"class":181,"line":852},[179,24458,24459],{"class":185},"# Ubuntu/Debian : apt install openjdk-21-jdk\n",[179,24461,24462],{"class":181,"line":1351},[179,24463,24464],{"class":185},"# macOS : brew install openjdk\n",[53,24466,24468],{"id":24467},"étape-2-mise-à-jour-du-build","Étape 2 : Mise à jour du build",[17,24470,24471],{},[21,24472,24473],{},"Maven (pom.xml)",[102,24475,24479],{"className":24476,"code":24477,"language":24478,"meta":111,"style":111},"language-xml shiki shiki-themes github-light github-dark","\u003Cproperties>\n    \u003Cmaven.compiler.source>21\u003C/maven.compiler.source>\n    \u003Cmaven.compiler.target>21\u003C/maven.compiler.target>\n\u003C/properties>\n","xml",[109,24480,24481,24486,24491,24496],{"__ignoreMap":111},[179,24482,24483],{"class":181,"line":182},[179,24484,24485],{},"\u003Cproperties>\n",[179,24487,24488],{"class":181,"line":189},[179,24489,24490],{},"    \u003Cmaven.compiler.source>21\u003C/maven.compiler.source>\n",[179,24492,24493],{"class":181,"line":448},[179,24494,24495],{},"    \u003Cmaven.compiler.target>21\u003C/maven.compiler.target>\n",[179,24497,24498],{"class":181,"line":775},[179,24499,24500],{},"\u003C/properties>\n",[17,24502,24503],{},[21,24504,24505],{},"Gradle (build.gradle)",[102,24507,24511],{"className":24508,"code":24509,"language":24510,"meta":111,"style":111},"language-groovy shiki shiki-themes github-light github-dark","java {\n    sourceCompatibility = JavaVersion.VERSION_21\n    targetCompatibility = JavaVersion.VERSION_21\n}\n","groovy",[109,24512,24513,24518,24523,24528],{"__ignoreMap":111},[179,24514,24515],{"class":181,"line":182},[179,24516,24517],{},"java {\n",[179,24519,24520],{"class":181,"line":189},[179,24521,24522],{},"    sourceCompatibility = JavaVersion.VERSION_21\n",[179,24524,24525],{"class":181,"line":448},[179,24526,24527],{},"    targetCompatibility = JavaVersion.VERSION_21\n",[179,24529,24530],{"class":181,"line":775},[179,24531,3814],{},[53,24533,24535],{"id":24534},"étape-3-réfactoring-progressif","Étape 3 : Réfactoring progressif",[79,24537,24538,24541,24544,24547,24550],{},[36,24539,24540],{},"Remplacer les POJOs par des records",[36,24542,24543],{},"Utiliser le pattern matching dans les switch",[36,24545,24546],{},"Adopter les text blocks pour les chaînes multilignes",[36,24548,24549],{},"Remplacer Optional.isEmpty() par isEmpty() (Java 11+)",[36,24551,24552,24553,24555],{},"Utiliser ",[109,24554,24135],{}," pour les variables locales",[53,24557,24559],{"id":24558},"étape-4-gestion-des-breaking-changes","Étape 4 : Gestion des breaking changes",[33,24561,24562,24568,24571],{},[36,24563,24564,24565,24567],{},"Joueur avec les ",[109,24566,24114],{}," si nécessaire",[36,24569,24570],{},"Vérifier les dépendances tierces",[36,24572,24573],{},"Tests automatisés pour valider la migration",[10725,24575],{},[12,24577,406],{"id":405},[17,24579,24580],{},"Java 20/21 n'est pas une révolution comme Java 8, mais une évolution continue qui rend le langage plus expressif et plus performant.",[17,24582,24583],{},[21,24584,24585],{},"Points à retenir :",[33,24587,24588,24594,24600,24606,24612],{},[36,24589,24590,24593],{},[21,24591,24592],{},"Records"," — Simplifient les classes de données",[36,24595,24596,24599],{},[21,24597,24598],{},"Pattern matching"," — Switch plus puissant avec déconstruction",[36,24601,24602,24605],{},[21,24603,24604],{},"Virtual threads"," — Concurrence à grande échelle",[36,24607,24608,24611],{},[21,24609,24610],{},"Text blocks"," — Chaînes multilignes naturelles",[36,24613,24614,24616],{},[21,24615,24135],{}," — Inférence de type pour les locales",[17,24618,24619],{},"Pour une migration réussie, procédez progressivement, testez chaque nouvelle fonctionnalité et profitez des outils modernes de Java.",[10725,24621],{},[12,24623,24625],{"id":24624},"annexe-chronologie-des-fonctionnalités","Annexe : Chronologie des fonctionnalités",[1120,24627,24628,24640],{},[1123,24629,24630],{},[1126,24631,24632,24634,24637],{},[1129,24633,12813],{},[1129,24635,24636],{},"Date",[1129,24638,24639],{},"Fonctionnalités majeures",[1136,24641,24642,24652,24662,24672,24681,24692,24702,24713,24723,24734,24745],{},[1126,24643,24644,24646,24649],{},[1141,24645,4346],{},[1141,24647,24648],{},"2014",[1141,24650,24651],{},"Lambda, Stream, Optional, Date API",[1126,24653,24654,24656,24659],{},[1141,24655,23772],{},[1141,24657,24658],{},"2017",[1141,24660,24661],{},"Modules, JShell, Optional.or/stream",[1126,24663,24664,24666,24669],{},[1141,24665,23745],{},[1141,24667,24668],{},"2018",[1141,24670,24671],{},"var, G1 GC par défaut",[1126,24673,24674,24676,24678],{},[1141,24675,23777],{},[1141,24677,24668],{},[1141,24679,24680],{},"LTS, var, isEmpty()",[1126,24682,24683,24686,24689],{},[1141,24684,24685],{},"14",[1141,24687,24688],{},"2020",[1141,24690,24691],{},"Records (preview), Switch expressions",[1126,24693,24694,24697,24699],{},[1141,24695,24696],{},"15",[1141,24698,24688],{},[1141,24700,24701],{},"Text blocks, Sealed classes",[1126,24703,24704,24707,24710],{},[1141,24705,24706],{},"16",[1141,24708,24709],{},"2021",[1141,24711,24712],{},"Records (standard), Pattern matching",[1126,24714,24715,24718,24720],{},[1141,24716,24717],{},"17",[1141,24719,24709],{},[1141,24721,24722],{},"LTS, Sealed classes, Pattern matching",[1126,24724,24725,24728,24731],{},[1141,24726,24727],{},"19",[1141,24729,24730],{},"2022",[1141,24732,24733],{},"Text blocks (standard), Virtual threads",[1126,24735,24736,24739,24742],{},[1141,24737,24738],{},"20",[1141,24740,24741],{},"2023",[1141,24743,24744],{},"Virtual threads (preview), Records patterns",[1126,24746,24747,24750,24752],{},[1141,24748,24749],{},"21",[1141,24751,24741],{},[1141,24753,24754],{},"Virtual threads (standard), Pattern matching (standard)",[438,24756,24757],{},"html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}",{"title":111,"searchDepth":189,"depth":189,"links":24759},[24760,24761,24765,24770,24774,24778,24782,24786,24787,24791,24795,24799,24800,24806,24807],{"id":22371,"depth":189,"text":22372},{"id":22415,"depth":189,"text":22416,"children":24762},[24763,24764],{"id":22422,"depth":448,"text":22423},{"id":22622,"depth":448,"text":22623},{"id":22669,"depth":189,"text":22670,"children":24766},[24767,24768,24769],{"id":22676,"depth":448,"text":22677},{"id":22770,"depth":448,"text":22771},{"id":22880,"depth":448,"text":22881},{"id":23022,"depth":189,"text":23023,"children":24771},[24772,24773],{"id":23029,"depth":448,"text":22677},{"id":23112,"depth":448,"text":22623},{"id":23171,"depth":189,"text":23172,"children":24775},[24776,24777],{"id":23178,"depth":448,"text":22677},{"id":23246,"depth":448,"text":23247},{"id":23386,"depth":189,"text":23387,"children":24779},[24780,24781],{"id":23393,"depth":448,"text":23394},{"id":23450,"depth":448,"text":23451},{"id":23505,"depth":189,"text":23506,"children":24783},[24784,24785],{"id":23515,"depth":448,"text":22677},{"id":23696,"depth":448,"text":22623},{"id":23920,"depth":189,"text":23921},{"id":24080,"depth":189,"text":24081,"children":24788},[24789,24790],{"id":24091,"depth":448,"text":24092},{"id":24101,"depth":448,"text":21729},{"id":24128,"depth":189,"text":24129,"children":24792},[24793,24794],{"id":24139,"depth":448,"text":22677},{"id":24186,"depth":448,"text":22623},{"id":24246,"depth":189,"text":24247,"children":24796},[24797,24798],{"id":24253,"depth":448,"text":22677},{"id":24276,"depth":448,"text":22623},{"id":24295,"depth":189,"text":24296},{"id":24424,"depth":189,"text":24425,"children":24801},[24802,24803,24804,24805],{"id":24428,"depth":448,"text":24429},{"id":24467,"depth":448,"text":24468},{"id":24534,"depth":448,"text":24535},{"id":24558,"depth":448,"text":24559},{"id":405,"depth":189,"text":406},{"id":24624,"depth":189,"text":24625},"2026-03-20","Découvrez les évolutions entre Java 8 et Java 20 : records, pattern matching, virtual threads, switch expressions et plus.","/images/posts/2026/03/guide-de-migration-java-8-java-20.webp",{},"/posts/guide-de-migration-java-8-java-20",{"title":22360,"description":24809},"posts/guide-de-migration-java-8-java-20",[652,24816,24817,24818,24819],"jvm","migration","backend","programmation","3fdJKLHPSfQSG4B_lNzkEQwkojreKkej8WmRDQGuCRU",{"id":24822,"title":24823,"author":7,"body":24824,"date":25897,"description":25898,"extension":474,"image":25899,"meta":25900,"navigation":477,"path":25901,"readingTime":479,"seo":25902,"stem":25903,"tags":25904,"updatedAt":25897,"__hash__":25908},"posts/posts/guide-suivi-evaluation.md","Guide du Suivi et Évaluation",{"type":9,"value":24825,"toc":25846},[24826,24828,24834,24837,24841,24845,24855,24858,24872,24876,24886,24888,24902,24906,24978,24982,24988,24992,24997,25000,25006,25010,25013,25018,25022,25025,25029,25040,25044,25047,25051,25062,25066,25072,25079,25083,25089,25093,25125,25129,25133,25136,25140,25151,25155,25158,25162,25173,25177,25180,25184,25195,25199,25202,25206,25217,25221,25224,25299,25303,25307,25311,25322,25328,25332,25343,25347,25358,25362,25366,25369,25373,25376,25380,25383,25387,25390,25394,25399,25405,25409,25413,25416,25433,25437,25440,25443,25457,25461,25559,25563,25595,25599,25603,25629,25633,25659,25663,25689,25693,25700,25704,25707,25711,25714,25718,25721,25725,25728,25732,25735,25739,25742,25744,25748,25751,25755,25758,25762,25765,25769,25772,25776,25779,25783,25794,25796,25799,25825,25828,25832],[12,24827,15],{"id":14},[17,24829,1067,24830,24833],{},[21,24831,24832],{},"Suivi et Évaluation (S&E)"," est un processus essentiel dans la gestion de projets et programmes. Il permet de mesurer les progrès, d'identifier les problèmes et d'évaluer l'impact des interventions.",[17,24835,24836],{},"Que vous travailliez dans le développement, l'humanitaire, l'éducation ou le secteur privé, maîtriser le S&E vous permettra de prendre des décisions basées sur des données concrètes.",[12,24838,24840],{"id":24839},"différence-entre-suivi-et-évaluation","Différence entre Suivi et Évaluation",[53,24842,24844],{"id":24843},"le-suivi-monitoring","Le Suivi (Monitoring)",[17,24846,24847,24848,24851,24852],{},"Le suivi est un processus ",[21,24849,24850],{},"continu"," qui consiste à collecter et analyser des données pendant toute la durée du projet. Il répond à la question : ",[21,24853,24854],{},"\"Sommes-nous sur la bonne voie ?\"",[17,24856,24857],{},"Caractéristiques :",[33,24859,24860,24863,24866,24869],{},[36,24861,24862],{},"Collecte régulière de données",[36,24864,24865],{},"Comparaison avec les objectifs planifiés",[36,24867,24868],{},"Détection rapide des écarts",[36,24870,24871],{},"Ajustements en temps réel",[53,24873,24875],{"id":24874},"lévaluation-evaluation","L'Évaluation (Evaluation)",[17,24877,24878,24879,24882,24883],{},"L'évaluation est un exercice ",[21,24880,24881],{},"ponctuel"," et plus approfondi. Elle répond à la question : ",[21,24884,24885],{},"\"Avons-nous atteint nos objectifs ? Pourquoi ou pourquoi pas ?\"",[17,24887,24857],{},[33,24889,24890,24893,24896,24899],{},[36,24891,24892],{},"Analyse approfondie à des moments clés",[36,24894,24895],{},"Mesure de l'impact et des résultats",[36,24897,24898],{},"Identification des leçons apprises",[36,24900,24901],{},"Recommandations pour l'avenir",[53,24903,24905],{"id":24904},"tableau-comparatif","Tableau comparatif",[1120,24907,24908,24921],{},[1123,24909,24910],{},[1126,24911,24912,24915,24918],{},[1129,24913,24914],{},"Critère",[1129,24916,24917],{},"Suivi",[1129,24919,24920],{},"Évaluation",[1136,24922,24923,24934,24945,24956,24967],{},[1126,24924,24925,24928,24931],{},[1141,24926,24927],{},"Fréquence",[1141,24929,24930],{},"Continue",[1141,24932,24933],{},"Ponctuelle",[1126,24935,24936,24939,24942],{},[1141,24937,24938],{},"Objectif",[1141,24940,24941],{},"Suivre les progrès",[1141,24943,24944],{},"Mesurer l'impact",[1126,24946,24947,24950,24953],{},[1141,24948,24949],{},"Question clé",[1141,24951,24952],{},"\"On avance bien ?\"",[1141,24954,24955],{},"\"On a réussi ?\"",[1126,24957,24958,24961,24964],{},[1141,24959,24960],{},"Responsable",[1141,24962,24963],{},"Équipe projet",[1141,24965,24966],{},"Souvent externe",[1126,24968,24969,24972,24975],{},[1141,24970,24971],{},"Données",[1141,24973,24974],{},"Quantitatives surtout",[1141,24976,24977],{},"Quali + Quanti",[12,24979,24981],{"id":24980},"le-cadre-logique","Le Cadre Logique",[17,24983,1067,24984,24987],{},[21,24985,24986],{},"cadre logique"," (ou LogFrame) est l'outil fondamental du S&E. Il structure la logique d'intervention d'un projet en 4 niveaux.",[53,24989,24991],{"id":24990},"les-4-niveaux-du-cadre-logique","Les 4 niveaux du cadre logique",[24993,24994,24996],"h4",{"id":24995},"_1-objectif-global-impact","1. Objectif global (Impact)",[17,24998,24999],{},"L'objectif de développement à long terme auquel le projet contribue.",[17,25001,25002,25005],{},[21,25003,25004],{},"Exemple :"," Améliorer la sécurité alimentaire dans la région Sud-Est de Madagascar.",[24993,25007,25009],{"id":25008},"_2-objectif-spécifique-outcome","2. Objectif spécifique (Outcome)",[17,25011,25012],{},"Le changement concret attendu à la fin du projet.",[17,25014,25015,25017],{},[21,25016,25004],{}," Augmenter de 30% la production rizicole des 500 ménages ciblés d'ici 2028.",[24993,25019,25021],{"id":25020},"_3-résultats-outputs","3. Résultats (Outputs)",[17,25023,25024],{},"Les produits ou services livrés par le projet.",[17,25026,25027],{},[21,25028,25004],{},[33,25030,25031,25034,25037],{},[36,25032,25033],{},"500 agriculteurs formés aux techniques SRI",[36,25035,25036],{},"10 périmètres irrigués réhabilités",[36,25038,25039],{},"3 coopératives agricoles créées",[24993,25041,25043],{"id":25042},"_4-activités-activities","4. Activités (Activities)",[17,25045,25046],{},"Les actions concrètes pour produire les résultats.",[17,25048,25049],{},[21,25050,25004],{},[33,25052,25053,25056,25059],{},[36,25054,25055],{},"Organiser 20 sessions de formation",[36,25057,25058],{},"Réhabiliter les canaux d'irrigation",[36,25060,25061],{},"Accompagner la création des coopératives",[53,25063,25065],{"id":25064},"la-chaîne-de-résultats","La chaîne de résultats",[102,25067,25070],{"className":25068,"code":25069,"language":107},[105],"Activités → Résultats → Objectif spécifique → Objectif global\n(Actions)   (Outputs)    (Outcome)              (Impact)\n",[109,25071,25069],{"__ignoreMap":111},[17,25073,25074,25075,25078],{},"Chaque niveau doit logiquement mener au suivant. C'est la ",[21,25076,25077],{},"théorie du changement"," du projet.",[12,25080,25082],{"id":25081},"les-indicateurs","Les Indicateurs",[17,25084,25085,25086,436],{},"Les indicateurs sont les mesures concrètes qui permettent de suivre les progrès. Un bon indicateur est ",[21,25087,25088],{},"SMART",[53,25090,25092],{"id":25091},"critères-smart","Critères SMART",[33,25094,25095,25101,25107,25113,25119],{},[36,25096,25097,25100],{},[21,25098,25099],{},"S","pécifique : clair et précis",[36,25102,25103,25106],{},[21,25104,25105],{},"M","esurable : quantifiable",[36,25108,25109,25112],{},[21,25110,25111],{},"A","tteignable : réaliste",[36,25114,25115,25118],{},[21,25116,25117],{},"R","éaliste : pertinent par rapport à l'objectif",[36,25120,25121,25124],{},[21,25122,25123],{},"T","emporel : délimité dans le temps",[53,25126,25128],{"id":25127},"types-dindicateurs","Types d'indicateurs",[24993,25130,25132],{"id":25131},"indicateurs-dactivité-processus","Indicateurs d'activité (processus)",[17,25134,25135],{},"Mesurent la réalisation des activités.",[17,25137,25138],{},[21,25139,14612],{},[33,25141,25142,25145,25148],{},[36,25143,25144],{},"Nombre de formations réalisées",[36,25146,25147],{},"Nombre de participants aux formations",[36,25149,25150],{},"Nombre de kits distribués",[24993,25152,25154],{"id":25153},"indicateurs-de-résultat-output","Indicateurs de résultat (output)",[17,25156,25157],{},"Mesurent les produits livrés.",[17,25159,25160],{},[21,25161,14612],{},[33,25163,25164,25167,25170],{},[36,25165,25166],{},"Nombre d'agriculteurs maîtrisant la technique SRI",[36,25168,25169],{},"Surface de périmètres irrigués fonctionnels",[36,25171,25172],{},"Nombre de coopératives opérationnelles",[24993,25174,25176],{"id":25175},"indicateurs-deffet-outcome","Indicateurs d'effet (outcome)",[17,25178,25179],{},"Mesurent le changement chez les bénéficiaires.",[17,25181,25182],{},[21,25183,14612],{},[33,25185,25186,25189,25192],{},[36,25187,25188],{},"Augmentation du rendement rizicole (tonnes/hectare)",[36,25190,25191],{},"Augmentation du revenu des ménages",[36,25193,25194],{},"Réduction de la période de soudure",[24993,25196,25198],{"id":25197},"indicateurs-dimpact","Indicateurs d'impact",[17,25200,25201],{},"Mesurent le changement à long terme.",[17,25203,25204],{},[21,25205,14612],{},[33,25207,25208,25211,25214],{},[36,25209,25210],{},"Taux de malnutrition dans la zone",[36,25212,25213],{},"Indice de sécurité alimentaire",[36,25215,25216],{},"Taux de pauvreté",[53,25218,25220],{"id":25219},"la-fiche-indicateur","La fiche indicateur",[17,25222,25223],{},"Pour chaque indicateur, documentez :",[1120,25225,25226,25235],{},[1123,25227,25228],{},[1126,25229,25230,25233],{},[1129,25231,25232],{},"Élément",[1129,25234,1134],{},[1136,25236,25237,25245,25253,25261,25269,25277,25284,25291],{},[1126,25238,25239,25242],{},[1141,25240,25241],{},"Nom",[1141,25243,25244],{},"Intitulé clair de l'indicateur",[1126,25246,25247,25250],{},[1141,25248,25249],{},"Définition",[1141,25251,25252],{},"Description précise de ce qui est mesuré",[1126,25254,25255,25258],{},[1141,25256,25257],{},"Valeur de base",[1141,25259,25260],{},"Situation avant le projet (baseline)",[1126,25262,25263,25266],{},[1141,25264,25265],{},"Cible",[1141,25267,25268],{},"Valeur à atteindre",[1126,25270,25271,25274],{},[1141,25272,25273],{},"Source",[1141,25275,25276],{},"D'où viennent les données",[1126,25278,25279,25281],{},[1141,25280,24927],{},[1141,25282,25283],{},"À quelle fréquence mesurer",[1126,25285,25286,25288],{},[1141,25287,24960],{},[1141,25289,25290],{},"Qui collecte les données",[1126,25292,25293,25296],{},[1141,25294,25295],{},"Méthode",[1141,25297,25298],{},"Comment les données sont collectées",[12,25300,25302],{"id":25301},"collecte-de-données","Collecte de données",[53,25304,25306],{"id":25305},"méthodes-quantitatives","Méthodes quantitatives",[24993,25308,25310],{"id":25309},"enquêtes-et-questionnaires","Enquêtes et questionnaires",[33,25312,25313,25316,25319],{},[36,25314,25315],{},"Enquête de base (baseline)",[36,25317,25318],{},"Enquêtes périodiques de suivi",[36,25320,25321],{},"Enquête finale (endline)",[17,25323,25324,25327],{},[21,25325,25326],{},"Conseil :"," Utilisez les mêmes questions entre baseline et endline pour pouvoir comparer.",[24993,25329,25331],{"id":25330},"données-administratives","Données administratives",[33,25333,25334,25337,25340],{},[36,25335,25336],{},"Registres de présence",[36,25338,25339],{},"Rapports d'activités",[36,25341,25342],{},"Données des systèmes de gestion",[24993,25344,25346],{"id":25345},"observation-directe","Observation directe",[33,25348,25349,25352,25355],{},[36,25350,25351],{},"Visites de terrain",[36,25353,25354],{},"Comptages physiques",[36,25356,25357],{},"Mesures techniques (rendement, surface, etc.)",[53,25359,25361],{"id":25360},"méthodes-qualitatives","Méthodes qualitatives",[24993,25363,25365],{"id":25364},"entretiens-individuels","Entretiens individuels",[17,25367,25368],{},"Conversations approfondies avec des informateurs clés (bénéficiaires, leaders, partenaires).",[24993,25370,25372],{"id":25371},"focus-groups-groupes-de-discussion","Focus groups (groupes de discussion)",[17,25374,25375],{},"Discussions de groupe (6-12 personnes) pour explorer des perceptions, attitudes et expériences.",[24993,25377,25379],{"id":25378},"études-de-cas","Études de cas",[17,25381,25382],{},"Analyse détaillée d'un cas spécifique pour comprendre le \"comment\" et le \"pourquoi\".",[24993,25384,25386],{"id":25385},"observation-participante","Observation participante",[17,25388,25389],{},"Immersion dans le contexte pour comprendre les dynamiques locales.",[53,25391,25393],{"id":25392},"triangulation","Triangulation",[17,25395,2630,25396,25398],{},[21,25397,25392],{}," consiste à croiser plusieurs sources et méthodes pour renforcer la fiabilité des données.",[102,25400,25403],{"className":25401,"code":25402,"language":107},[105],"     Source 1 (Enquête)\n           \\\n            → Conclusion validée\n           /\n     Source 2 (Entretien)\n           \\\n            → Confirmation\n           /\n     Source 3 (Observation)\n",[109,25404,25402],{"__ignoreMap":111},[12,25406,25408],{"id":25407},"outils-pratiques-du-se","Outils pratiques du S&E",[53,25410,25412],{"id":25411},"_1-le-plan-de-se","1. Le plan de S&E",[17,25414,25415],{},"Document qui décrit :",[33,25417,25418,25421,25424,25427,25430],{},[36,25419,25420],{},"Les indicateurs à suivre",[36,25422,25423],{},"Les méthodes de collecte",[36,25425,25426],{},"Le calendrier de collecte",[36,25428,25429],{},"Les responsabilités",[36,25431,25432],{},"Le budget S&E",[53,25434,25436],{"id":25435},"_2-le-tableau-de-bord-dashboard","2. Le tableau de bord (dashboard)",[17,25438,25439],{},"Outil visuel qui présente les indicateurs clés en un coup d'œil. Il permet aux décideurs de suivre les progrès rapidement.",[17,25441,25442],{},"Éléments typiques :",[33,25444,25445,25448,25451,25454],{},[36,25446,25447],{},"Indicateurs avec valeurs actuelles vs cibles",[36,25449,25450],{},"Graphiques de tendance",[36,25452,25453],{},"Code couleur (vert/jaune/rouge) pour l'état d'avancement",[36,25455,25456],{},"Carte géographique si pertinent",[53,25458,25460],{"id":25459},"_3-la-matrice-de-suivi-des-indicateurs","3. La matrice de suivi des indicateurs",[1120,25462,25463,25490],{},[1123,25464,25465],{},[1126,25466,25467,25470,25473,25475,25478,25481,25484,25487],{},[1129,25468,25469],{},"Indicateur",[1129,25471,25472],{},"Baseline",[1129,25474,25265],{},[1129,25476,25477],{},"T1",[1129,25479,25480],{},"T2",[1129,25482,25483],{},"T3",[1129,25485,25486],{},"T4",[1129,25488,25489],{},"Statut",[1136,25491,25492,25515,25540],{},[1126,25493,25494,25497,25499,25502,25505,25508,25510,25512],{},[1141,25495,25496],{},"Agriculteurs formés",[1141,25498,4443],{},[1141,25500,25501],{},"500",[1141,25503,25504],{},"120",[1141,25506,25507],{},"280",[1141,25509,7044],{},[1141,25511,25501],{},[1141,25513,25514],{},"En bonne voie",[1126,25516,25517,25520,25523,25526,25529,25532,25535,25537],{},[1141,25518,25519],{},"Rendement (t/ha)",[1141,25521,25522],{},"2.1",[1141,25524,25525],{},"3.0",[1141,25527,25528],{},"2.3",[1141,25530,25531],{},"2.5",[1141,25533,25534],{},"2.7",[1141,25536,5100],{},[1141,25538,25539],{},"Attention",[1126,25541,25542,25545,25547,25549,25551,25553,25555,25557],{},[1141,25543,25544],{},"Coopératives créées",[1141,25546,4443],{},[1141,25548,23726],{},[1141,25550,4331],{},[1141,25552,4331],{},[1141,25554,4457],{},[1141,25556,5100],{},[1141,25558,25539],{},[53,25560,25562],{"id":25561},"_4-outils-numériques","4. Outils numériques",[33,25564,25565,25571,25577,25583,25589],{},[36,25566,25567,25570],{},[21,25568,25569],{},"KoboToolbox"," : collecte de données mobile (gratuit, open source)",[36,25572,25573,25576],{},[21,25574,25575],{},"ODK (Open Data Kit)"," : formulaires de collecte sur terrain",[36,25578,25579,25582],{},[21,25580,25581],{},"Power BI / Tableau"," : visualisation de données et dashboards",[36,25584,25585,25588],{},[21,25586,25587],{},"Excel / Google Sheets"," : analyse de base, toujours utile",[36,25590,25591,25594],{},[21,25592,25593],{},"DHIS2"," : système d'information pour la santé et le développement",[12,25596,25598],{"id":25597},"types-dévaluation","Types d'évaluation",[53,25600,25602],{"id":25601},"par-moment","Par moment",[33,25604,25605,25611,25617,25623],{},[36,25606,25607,25610],{},[21,25608,25609],{},"Ex-ante"," : avant le projet (étude de faisabilité)",[36,25612,25613,25616],{},[21,25614,25615],{},"Mi-parcours"," : à mi-chemin (ajustements)",[36,25618,25619,25622],{},[21,25620,25621],{},"Finale"," : à la fin du projet (résultats)",[36,25624,25625,25628],{},[21,25626,25627],{},"Ex-post"," : après le projet (impact durable)",[53,25630,25632],{"id":25631},"par-objectif","Par objectif",[33,25634,25635,25641,25647,25653],{},[36,25636,25637,25640],{},[21,25638,25639],{},"Évaluation de processus"," : comment le projet est mis en œuvre",[36,25642,25643,25646],{},[21,25644,25645],{},"Évaluation de résultats"," : qu'est-ce qui a été produit",[36,25648,25649,25652],{},[21,25650,25651],{},"Évaluation d'impact"," : quel changement a été généré",[36,25654,25655,25658],{},[21,25656,25657],{},"Évaluation économique"," : coût-efficacité, coût-bénéfice",[53,25660,25662],{"id":25661},"par-acteur","Par acteur",[33,25664,25665,25671,25677,25683],{},[36,25666,25667,25670],{},[21,25668,25669],{},"Auto-évaluation"," : par l'équipe projet elle-même",[36,25672,25673,25676],{},[21,25674,25675],{},"Évaluation interne"," : par l'organisation mais hors équipe projet",[36,25678,25679,25682],{},[21,25680,25681],{},"Évaluation externe"," : par un évaluateur indépendant",[36,25684,25685,25688],{},[21,25686,25687],{},"Évaluation participative"," : impliquant les bénéficiaires",[12,25690,25692],{"id":25691},"les-critères-dévaluation-du-cadocde","Les critères d'évaluation du CAD/OCDE",[17,25694,25695,25696,25699],{},"L'OCDE a défini ",[21,25697,25698],{},"6 critères"," standards pour évaluer les projets de développement :",[53,25701,25703],{"id":25702},"_1-pertinence","1. Pertinence",[17,25705,25706],{},"Le projet répond-il aux besoins réels des bénéficiaires ?",[53,25708,25710],{"id":25709},"_2-cohérence","2. Cohérence",[17,25712,25713],{},"Le projet est-il en harmonie avec les autres interventions dans le même contexte ?",[53,25715,25717],{"id":25716},"_3-efficacité","3. Efficacité",[17,25719,25720],{},"Les objectifs ont-ils été atteints ?",[53,25722,25724],{"id":25723},"_4-efficience","4. Efficience",[17,25726,25727],{},"Les ressources ont-elles été bien utilisées (rapport résultats/coûts) ?",[53,25729,25731],{"id":25730},"_5-impact","5. Impact",[17,25733,25734],{},"Quels changements durables le projet a-t-il générés ?",[53,25736,25738],{"id":25737},"_6-durabilité-viabilité","6. Durabilité (Viabilité)",[17,25740,25741],{},"Les bénéfices se maintiendront-ils après la fin du projet ?",[12,25743,3609],{"id":3608},[53,25745,25747],{"id":25746},"planifier-le-se-dès-le-début","Planifier le S&E dès le début",[17,25749,25750],{},"Ne pas attendre la fin du projet pour penser à l'évaluation. Le système de S&E doit être conçu en même temps que le projet.",[53,25752,25754],{"id":25753},"collecter-les-données-de-base-baseline","Collecter les données de base (baseline)",[17,25756,25757],{},"Sans baseline, impossible de mesurer le changement. C'est la photo \"avant\" du projet.",[53,25759,25761],{"id":25760},"impliquer-les-parties-prenantes","Impliquer les parties prenantes",[17,25763,25764],{},"Les bénéficiaires, les partenaires et les bailleurs doivent être impliqués dans le processus de S&E.",[53,25766,25768],{"id":25767},"utiliser-les-données-pour-décider","Utiliser les données pour décider",[17,25770,25771],{},"Le S&E n'a de valeur que si les données collectées sont analysées et utilisées pour améliorer le projet.",[53,25773,25775],{"id":25774},"documenter-les-leçons-apprises","Documenter les leçons apprises",[17,25777,25778],{},"Chaque projet génère des connaissances précieuses. Les capitaliser permet d'améliorer les projets futurs.",[53,25780,25782],{"id":25781},"assurer-la-qualité-des-données","Assurer la qualité des données",[33,25784,25785,25788,25791],{},[36,25786,25787],{},"Former les collecteurs de données",[36,25789,25790],{},"Vérifier les données à chaque étape",[36,25792,25793],{},"Mettre en place des contrôles de qualité",[12,25795,406],{"id":405},[17,25797,25798],{},"Le Suivi et Évaluation n'est pas une simple formalité administrative. C'est un outil de pilotage puissant qui permet de :",[33,25800,25801,25807,25813,25819],{},[36,25802,25803,25806],{},[21,25804,25805],{},"Rendre compte"," aux bailleurs et parties prenantes",[36,25808,25809,25812],{},[21,25810,25811],{},"Apprendre"," de l'expérience",[36,25814,25815,25818],{},[21,25816,25817],{},"Améliorer"," les interventions en cours",[36,25820,25821,25824],{},[21,25822,25823],{},"Démontrer"," l'impact du travail réalisé",[17,25826,25827],{},"Maîtriser le S&E, c'est passer d'une gestion basée sur l'intuition à une gestion basée sur les preuves. C'est un investissement qui profite à tous : équipes projet, bénéficiaires et décideurs.",[12,25829,25831],{"id":25830},"ressources","Ressources",[33,25833,25834,25837,25840,25843],{},[36,25835,25836],{},"Guide du S&E de la Croix-Rouge (IFRC)",[36,25838,25839],{},"BetterEvaluation : plateforme de ressources sur l'évaluation",[36,25841,25842],{},"Critères du CAD/OCDE pour l'évaluation",[36,25844,25845],{},"KoboToolbox : outil gratuit de collecte de données",{"title":111,"searchDepth":189,"depth":189,"links":25847},[25848,25849,25854,25858,25863,25868,25874,25879,25887,25895,25896],{"id":14,"depth":189,"text":15},{"id":24839,"depth":189,"text":24840,"children":25850},[25851,25852,25853],{"id":24843,"depth":448,"text":24844},{"id":24874,"depth":448,"text":24875},{"id":24904,"depth":448,"text":24905},{"id":24980,"depth":189,"text":24981,"children":25855},[25856,25857],{"id":24990,"depth":448,"text":24991},{"id":25064,"depth":448,"text":25065},{"id":25081,"depth":189,"text":25082,"children":25859},[25860,25861,25862],{"id":25091,"depth":448,"text":25092},{"id":25127,"depth":448,"text":25128},{"id":25219,"depth":448,"text":25220},{"id":25301,"depth":189,"text":25302,"children":25864},[25865,25866,25867],{"id":25305,"depth":448,"text":25306},{"id":25360,"depth":448,"text":25361},{"id":25392,"depth":448,"text":25393},{"id":25407,"depth":189,"text":25408,"children":25869},[25870,25871,25872,25873],{"id":25411,"depth":448,"text":25412},{"id":25435,"depth":448,"text":25436},{"id":25459,"depth":448,"text":25460},{"id":25561,"depth":448,"text":25562},{"id":25597,"depth":189,"text":25598,"children":25875},[25876,25877,25878],{"id":25601,"depth":448,"text":25602},{"id":25631,"depth":448,"text":25632},{"id":25661,"depth":448,"text":25662},{"id":25691,"depth":189,"text":25692,"children":25880},[25881,25882,25883,25884,25885,25886],{"id":25702,"depth":448,"text":25703},{"id":25709,"depth":448,"text":25710},{"id":25716,"depth":448,"text":25717},{"id":25723,"depth":448,"text":25724},{"id":25730,"depth":448,"text":25731},{"id":25737,"depth":448,"text":25738},{"id":3608,"depth":189,"text":3609,"children":25888},[25889,25890,25891,25892,25893,25894],{"id":25746,"depth":448,"text":25747},{"id":25753,"depth":448,"text":25754},{"id":25760,"depth":448,"text":25761},{"id":25767,"depth":448,"text":25768},{"id":25774,"depth":448,"text":25775},{"id":25781,"depth":448,"text":25782},{"id":405,"depth":189,"text":406},{"id":25830,"depth":189,"text":25831},"2026-03-17","Les fondamentaux du suivi et évaluation : cadre logique, indicateurs SMART, collecte de données et outils pratiques pour mesurer l'impact de vos projets de développement.","/images/posts/2026/03/guide-suivi-evaluation.webp",{},"/posts/guide-suivi-evaluation",{"title":24823,"description":25898},"posts/guide-suivi-evaluation",[25905,25906,25907],"suivi-evaluation","gestion-projet","methodologie","SfPAqKAlgSeI0Dzs0ZCzyQ2mRNZlkEZgIuqREmYIWoc",{"id":25910,"title":25911,"author":7,"body":25912,"date":26652,"description":26653,"extension":474,"image":26654,"meta":26655,"navigation":477,"path":26656,"readingTime":479,"seo":26657,"stem":26658,"tags":26659,"updatedAt":479,"__hash__":26662},"posts/posts/creation-plateforme-nuxt4.md","Création d'une plateforme moderne avec Nuxt 4",{"type":9,"value":25913,"toc":26624},[25914,25916,25927,25930,25934,25938,25963,25967,25986,25990,25996,26000,26006,26090,26094,26097,26116,26123,26127,26131,26134,26151,26153,26181,26185,26209,26213,26217,26227,26312,26316,26326,26367,26371,26374,26465,26469,26473,26476,26504,26508,26511,26554,26558,26561,26575,26582,26584,26587,26590,26592,26621],[12,25915,15],{"id":14},[17,25917,25918,25919,25922,25923,25926],{},"Cette plateforme a été entièrement développée avec ",[21,25920,25921],{},"Nuxt 4"," en mode ",[21,25924,25925],{},"SSG (Static Site Generation)",". L'objectif : créer une plateforme de publication d'articles performante, SEO-friendly, et simple à maintenir.",[17,25928,25929],{},"Dans cet article, je partage les choix techniques, l'architecture du projet, et les leçons apprises lors du développement.",[12,25931,25933],{"id":25932},"stack-technique","Stack technique",[53,25935,25937],{"id":25936},"framework-et-modules","Framework et modules",[33,25939,25940,25945,25951,25957],{},[36,25941,25942,25944],{},[21,25943,25921],{}," - Le méta-framework Vue.js pour la génération statique",[36,25946,25947,25950],{},[21,25948,25949],{},"@nuxt/content"," - Gestion du contenu Markdown avec collections Zod",[36,25952,25953,25956],{},[21,25954,25955],{},"@nuxt/image"," - Optimisation automatique des images (WebP, AVIF)",[36,25958,25959,25962],{},[21,25960,25961],{},"@nuxtjs/tailwindcss"," - Framework CSS utility-first",[53,25964,25966],{"id":25965},"technologies-complémentaires","Technologies complémentaires",[33,25968,25969,25974,25980],{},[36,25970,25971,25973],{},[21,25972,3875],{}," - Typage statique pour un code plus robuste",[36,25975,25976,25979],{},[21,25977,25978],{},"Vue 3 Composition API"," - Architecture moderne des composants",[36,25981,25982,25985],{},[21,25983,25984],{},"Tailwind CSS"," - Styling avec le plugin Typography pour le contenu",[12,25987,25989],{"id":25988},"architecture-du-projet","Architecture du projet",[102,25991,25994],{"className":25992,"code":25993,"language":107},[105],"learn/\n├── app/\n│   ├── components/       # Composants réutilisables\n│   ├── composables/      # Logique partagée (useFormatDate, useTags)\n│   ├── layouts/          # Layout principal\n│   ├── pages/            # Routes et pages\n│   └── types/            # Interfaces TypeScript\n├── content/\n│   └── posts/            # Articles Markdown\n├── public/\n│   └── images/           # Images statiques\n└── server/\n    └── routes/           # RSS et Sitemap\n",[109,25995,25993],{"__ignoreMap":111},[12,25997,25999],{"id":25998},"gestion-du-contenu","Gestion du contenu",[17,26001,26002,26003,26005],{},"Les articles sont rédigés en ",[21,26004,5056],{}," avec un front-matter YAML :",[102,26007,26009],{"className":4955,"code":26008,"language":4951,"meta":111,"style":111},"---\ntitle: \"Titre de l'article\"\ndescription: \"Description SEO (150-160 caractères)\"\ndate: 2026-01-24\nauthor: \"Nom de l'auteur\"\ntags: [tag1, tag2, tag3]\nimage: \"/images/posts/2026/01/cover.jpg\"\n---\n",[109,26010,26011,26016,26025,26035,26044,26054,26076,26086],{"__ignoreMap":111},[179,26012,26013],{"class":181,"line":182},[179,26014,26015],{"class":192},"---\n",[179,26017,26018,26020,26022],{"class":181,"line":189},[179,26019,4589],{"class":4053},[179,26021,4251],{"class":681},[179,26023,26024],{"class":196},"\"Titre de l'article\"\n",[179,26026,26027,26030,26032],{"class":181,"line":448},[179,26028,26029],{"class":4053},"description",[179,26031,4251],{"class":681},[179,26033,26034],{"class":196},"\"Description SEO (150-160 caractères)\"\n",[179,26036,26037,26039,26041],{"class":181,"line":775},[179,26038,3544],{"class":4053},[179,26040,4251],{"class":681},[179,26042,26043],{"class":224},"2026-01-24\n",[179,26045,26046,26049,26051],{"class":181,"line":852},[179,26047,26048],{"class":4053},"author",[179,26050,4251],{"class":681},[179,26052,26053],{"class":196},"\"Nom de l'auteur\"\n",[179,26055,26056,26059,26061,26064,26066,26069,26071,26074],{"class":181,"line":1351},[179,26057,26058],{"class":4053},"tags",[179,26060,10582],{"class":681},[179,26062,26063],{"class":196},"tag1",[179,26065,5355],{"class":681},[179,26067,26068],{"class":196},"tag2",[179,26070,5355],{"class":681},[179,26072,26073],{"class":196},"tag3",[179,26075,10593],{"class":681},[179,26077,26078,26081,26083],{"class":181,"line":1363},[179,26079,26080],{"class":4053},"image",[179,26082,4251],{"class":681},[179,26084,26085],{"class":196},"\"/images/posts/2026/01/cover.jpg\"\n",[179,26087,26088],{"class":181,"line":1381},[179,26089,26015],{"class":192},[53,26091,26093],{"id":26092},"système-de-brouillons","Système de brouillons",[17,26095,26096],{},"Une convention simple pour gérer les brouillons :",[33,26098,26099,26108],{},[36,26100,26101,26104,26105],{},[21,26102,26103],{},"Publié"," : ",[109,26106,26107],{},"mon-article.md",[36,26109,26110,26104,26113],{},[21,26111,26112],{},"Brouillon",[109,26114,26115],{},"mon-article.draft.md",[17,26117,26118,26119,26122],{},"Les fichiers ",[109,26120,26121],{},".draft.md"," sont automatiquement exclus de la production.",[12,26124,26126],{"id":26125},"fonctionnalités-principales","Fonctionnalités principales",[53,26128,26130],{"id":26129},"seo-optimisé","SEO optimisé",[17,26132,26133],{},"Chaque page inclut :",[33,26135,26136,26139,26142,26145,26148],{},[36,26137,26138],{},"Meta title et description dynamiques",[36,26140,26141],{},"OpenGraph et Twitter Cards",[36,26143,26144],{},"Structured Data (JSON-LD) pour Schema.org",[36,26146,26147],{},"Canonical URLs",[36,26149,26150],{},"Sitemap XML et flux RSS",[53,26152,2286],{"id":6383},[33,26154,26155,26163,26169,26175],{},[36,26156,26157,26160,26161],{},[21,26158,26159],{},"Lazy loading"," des images avec ",[109,26162,25955],{},[36,26164,26165,26168],{},[21,26166,26167],{},"Code splitting"," automatique par page",[36,26170,26171,26174],{},[21,26172,26173],{},"Formats modernes"," : WebP et AVIF",[36,26176,26177,26180],{},[21,26178,26179],{},"Images responsive"," avec srcset",[53,26182,26184],{"id":26183},"navigation","Navigation",[33,26186,26187,26190,26200,26203],{},[36,26188,26189],{},"Filtrage par tags sur la page d'accueil",[36,26191,26192,26193,5355,26196,26199],{},"Pagination URL-based (",[109,26194,26195],{},"/page/2",[109,26197,26198],{},"/page/3","...)",[36,26201,26202],{},"Navigation article précédent/suivant",[36,26204,26205,26206,10236],{},"Page dédiée par tag (",[109,26207,26208],{},"/tags/nuxt",[12,26210,26212],{"id":26211},"leçons-apprises","Leçons apprises",[53,26214,26216],{"id":26215},"querycollection-vs-querycontent","queryCollection vs queryContent",[17,26218,26219,26220,26223,26224,642],{},"Avec Nuxt Content v3 et les collections définies dans ",[109,26221,26222],{},"content.config.ts",", il faut utiliser ",[109,26225,26226],{},"queryCollection()",[102,26228,26230],{"className":3878,"code":26229,"language":3874,"meta":111,"style":111},"// Nouvelle API\nconst { data } = await useAsyncData('articles', () =>\n    queryCollection('posts')\n        .order('date', 'DESC')\n        .all()\n)\n",[109,26231,26232,26237,26267,26279,26299,26308],{"__ignoreMap":111},[179,26233,26234],{"class":181,"line":182},[179,26235,26236],{"class":185},"// Nouvelle API\n",[179,26238,26239,26241,26244,26246,26249,26251,26253,26256,26258,26261,26264],{"class":181,"line":189},[179,26240,3823],{"class":549},[179,26242,26243],{"class":681}," { ",[179,26245,6779],{"class":224},[179,26247,26248],{"class":681}," } ",[179,26250,685],{"class":549},[179,26252,3755],{"class":549},[179,26254,26255],{"class":192}," useAsyncData",[179,26257,3761],{"class":681},[179,26259,26260],{"class":196},"'articles'",[179,26262,26263],{"class":681},", () ",[179,26265,26266],{"class":549},"=>\n",[179,26268,26269,26272,26274,26277],{"class":181,"line":448},[179,26270,26271],{"class":192},"    queryCollection",[179,26273,3761],{"class":681},[179,26275,26276],{"class":196},"'posts'",[179,26278,1480],{"class":681},[179,26280,26281,26284,26287,26289,26292,26294,26297],{"class":181,"line":775},[179,26282,26283],{"class":681},"        .",[179,26285,26286],{"class":192},"order",[179,26288,3761],{"class":681},[179,26290,26291],{"class":196},"'date'",[179,26293,5355],{"class":681},[179,26295,26296],{"class":196},"'DESC'",[179,26298,1480],{"class":681},[179,26300,26301,26303,26306],{"class":181,"line":852},[179,26302,26283],{"class":681},[179,26304,26305],{"class":192},"all",[179,26307,5565],{"class":681},[179,26309,26310],{"class":181,"line":1351},[179,26311,1480],{"class":681},[53,26313,26315],{"id":26314},"propriété-stem","Propriété stem",[17,26317,26318,26319,26322,26323,642],{},"La collection retourne ",[109,26320,26321],{},"stem"," au lieu de ",[109,26324,26325],{},"_path",[102,26327,26329],{"className":3878,"code":26328,"language":3874,"meta":111,"style":111},"// stem = \"posts/mon-article\" (sans slash initial)\nconst articlePath = computed(() => `/${article.stem}`)\n",[109,26330,26331,26336],{"__ignoreMap":111},[179,26332,26333],{"class":181,"line":182},[179,26334,26335],{"class":185},"// stem = \"posts/mon-article\" (sans slash initial)\n",[179,26337,26338,26340,26343,26345,26348,26350,26352,26355,26358,26360,26362,26365],{"class":181,"line":189},[179,26339,3823],{"class":549},[179,26341,26342],{"class":224}," articlePath",[179,26344,3752],{"class":549},[179,26346,26347],{"class":192}," computed",[179,26349,23301],{"class":681},[179,26351,3839],{"class":549},[179,26353,26354],{"class":196}," `/${",[179,26356,26357],{"class":681},"article",[179,26359,436],{"class":196},[179,26361,26321],{"class":681},[179,26363,26364],{"class":196},"}`",[179,26366,1480],{"class":681},[53,26368,26370],{"id":26369},"types-partagés","Types partagés",[17,26372,26373],{},"Centraliser les interfaces TypeScript évite la duplication :",[102,26375,26377],{"className":3878,"code":26376,"language":3874,"meta":111,"style":111},"// app/types/article.ts\nexport interface Article {\n    stem: string\n    title: string\n    description: string\n    date: string\n    author?: string\n    tags?: string[]\n    image?: string\n}\n",[109,26378,26379,26384,26395,26405,26414,26423,26432,26441,26453,26461],{"__ignoreMap":111},[179,26380,26381],{"class":181,"line":182},[179,26382,26383],{"class":185},"// app/types/article.ts\n",[179,26385,26386,26388,26391,26393],{"class":181,"line":189},[179,26387,678],{"class":549},[179,26389,26390],{"class":549}," interface",[179,26392,5670],{"class":192},[179,26394,3892],{"class":681},[179,26396,26397,26400,26402],{"class":181,"line":448},[179,26398,26399],{"class":3802},"    stem",[179,26401,3900],{"class":549},[179,26403,26404],{"class":224}," string\n",[179,26406,26407,26410,26412],{"class":181,"line":775},[179,26408,26409],{"class":3802},"    title",[179,26411,3900],{"class":549},[179,26413,26404],{"class":224},[179,26415,26416,26419,26421],{"class":181,"line":852},[179,26417,26418],{"class":3802},"    description",[179,26420,3900],{"class":549},[179,26422,26404],{"class":224},[179,26424,26425,26428,26430],{"class":181,"line":1351},[179,26426,26427],{"class":3802},"    date",[179,26429,3900],{"class":549},[179,26431,26404],{"class":224},[179,26433,26434,26437,26439],{"class":181,"line":1363},[179,26435,26436],{"class":3802},"    author",[179,26438,4208],{"class":549},[179,26440,26404],{"class":224},[179,26442,26443,26446,26448,26450],{"class":181,"line":1381},[179,26444,26445],{"class":3802},"    tags",[179,26447,4208],{"class":549},[179,26449,3915],{"class":224},[179,26451,26452],{"class":681},"[]\n",[179,26454,26455,26457,26459],{"class":181,"line":1401},[179,26456,8614],{"class":3802},[179,26458,4208],{"class":549},[179,26460,26404],{"class":224},[179,26462,26463],{"class":181,"line":1407},[179,26464,3814],{"class":681},[12,26466,26468],{"id":26467},"composables-créés","Composables créés",[53,26470,26472],{"id":26471},"useformatdate","useFormatDate",[17,26474,26475],{},"Formatage des dates en français :",[102,26477,26479],{"className":3878,"code":26478,"language":3874,"meta":111,"style":111},"const { formatDate } = useFormatDate()\n// \"24 janvier 2026\"\n",[109,26480,26481,26499],{"__ignoreMap":111},[179,26482,26483,26485,26487,26490,26492,26494,26497],{"class":181,"line":182},[179,26484,3823],{"class":549},[179,26486,26243],{"class":681},[179,26488,26489],{"class":224},"formatDate",[179,26491,26248],{"class":681},[179,26493,685],{"class":549},[179,26495,26496],{"class":192}," useFormatDate",[179,26498,5565],{"class":681},[179,26500,26501],{"class":181,"line":189},[179,26502,26503],{"class":185},"// \"24 janvier 2026\"\n",[53,26505,26507],{"id":26506},"usetags","useTags",[17,26509,26510],{},"Extraction et comptage des tags :",[102,26512,26514],{"className":3878,"code":26513,"language":3874,"meta":111,"style":111},"const { extractTags } = useTags()\nconst tags = extractTags(articles)\n// [{ name: 'nuxt', count: 5 }, { name: 'vue', count: 3 }]\n",[109,26515,26516,26534,26549],{"__ignoreMap":111},[179,26517,26518,26520,26522,26525,26527,26529,26532],{"class":181,"line":182},[179,26519,3823],{"class":549},[179,26521,26243],{"class":681},[179,26523,26524],{"class":224},"extractTags",[179,26526,26248],{"class":681},[179,26528,685],{"class":549},[179,26530,26531],{"class":192}," useTags",[179,26533,5565],{"class":681},[179,26535,26536,26538,26541,26543,26546],{"class":181,"line":189},[179,26537,3823],{"class":549},[179,26539,26540],{"class":224}," tags",[179,26542,3752],{"class":549},[179,26544,26545],{"class":192}," extractTags",[179,26547,26548],{"class":681},"(articles)\n",[179,26550,26551],{"class":181,"line":448},[179,26552,26553],{"class":185},"// [{ name: 'nuxt', count: 5 }, { name: 'vue', count: 3 }]\n",[12,26555,26557],{"id":26556},"déploiement","Déploiement",[17,26559,26560],{},"La plateforme est générée en statique avec :",[102,26562,26564],{"className":173,"code":26563,"language":175,"meta":111,"style":111},"npm run generate\n",[109,26565,26566],{"__ignoreMap":111},[179,26567,26568,26570,26572],{"class":181,"line":182},[179,26569,600],{"class":192},[179,26571,8377],{"class":196},[179,26573,26574],{"class":196}," generate\n",[17,26576,26577,26578,26581],{},"Le résultat dans ",[109,26579,26580],{},".output/public/"," peut être déployé sur n'importe quel CDN (Vercel, Netlify, Cloudflare Pages).",[12,26583,406],{"id":405},[17,26585,26586],{},"Nuxt 4 avec @nuxt/content offre une excellente expérience développeur pour créer une plateforme statique. La combinaison TypeScript + Tailwind CSS permet un développement rapide et maintenable.",[17,26588,26589],{},"Le code source de cette plateforme est disponible pour ceux qui souhaitent s'en inspirer. N'hésitez pas à me contacter pour toute question !",[12,26591,25831],{"id":25830},[33,26593,26594,26601,26608,26614],{},[36,26595,26596],{},[730,26597,26600],{"href":26598,"rel":26599},"https://nuxt.com",[734],"Documentation Nuxt 4",[36,26602,26603],{},[730,26604,26607],{"href":26605,"rel":26606},"https://content.nuxt.com",[734],"Documentation @nuxt/content",[36,26609,26610],{},[730,26611,25984],{"href":26612,"rel":26613},"https://tailwindcss.com",[734],[36,26615,26616],{},[730,26617,26620],{"href":26618,"rel":26619},"https://vuejs.org",[734],"Vue.js",[438,26622,26623],{},"html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .s9eBZ, html code.shiki .s9eBZ{--shiki-default:#22863A;--shiki-dark:#85E89D}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}",{"title":111,"searchDepth":189,"depth":189,"links":26625},[26626,26627,26631,26632,26635,26640,26645,26649,26650,26651],{"id":14,"depth":189,"text":15},{"id":25932,"depth":189,"text":25933,"children":26628},[26629,26630],{"id":25936,"depth":448,"text":25937},{"id":25965,"depth":448,"text":25966},{"id":25988,"depth":189,"text":25989},{"id":25998,"depth":189,"text":25999,"children":26633},[26634],{"id":26092,"depth":448,"text":26093},{"id":26125,"depth":189,"text":26126,"children":26636},[26637,26638,26639],{"id":26129,"depth":448,"text":26130},{"id":6383,"depth":448,"text":2286},{"id":26183,"depth":448,"text":26184},{"id":26211,"depth":189,"text":26212,"children":26641},[26642,26643,26644],{"id":26215,"depth":448,"text":26216},{"id":26314,"depth":448,"text":26315},{"id":26369,"depth":448,"text":26370},{"id":26467,"depth":189,"text":26468,"children":26646},[26647,26648],{"id":26471,"depth":448,"text":26472},{"id":26506,"depth":448,"text":26507},{"id":26556,"depth":189,"text":26557},{"id":405,"depth":189,"text":406},{"id":25830,"depth":189,"text":25831},"2026-01-24","Découvrez comment j'ai construit cette plateforme d'apprentissage avec Nuxt 4, @nuxt/content et Tailwind CSS. Architecture, choix techniques et bonnes pratiques.","/images/posts/2026/01/creation-plateforme-nuxt4.webp",{},"/posts/creation-plateforme-nuxt4",{"title":25911,"description":26653},"posts/creation-plateforme-nuxt4",[26660,4038,26661,3874],"nuxt","tailwind","-3wHnzFUTb_ZJYSEb2cHU_0eOXWLsmNYI5z_AxTWfTk",1776608855576]