[{"data":1,"prerenderedAt":1078},["ShallowReactive",2],{"articles-tags-CI-CD":3},[4],{"id":5,"title":6,"body":7,"date":1064,"description":1065,"draft":1066,"extension":1067,"meta":1068,"navigation":473,"path":1069,"seo":1070,"slug":1071,"stem":1072,"tags":1073,"thumbnail":1076,"__hash__":1077},"articles\u002Farticles\u002FDéploiement site Nuxt avec Gitlab.md","Déploiement automatique d'un site Nuxt avec Gitlab",{"type":8,"value":9,"toc":1054},"minimark",[10,19,24,46,49,59,63,77,81,91,101,142,149,230,233,249,265,274,285,348,364,378,382,392,399,402,428,440,446,600,604,638,644,651,655,672,682,688,696,702,935,940,972,978,982,994,999,1002,1012,1022,1026,1050],[11,12,13,14,18],"p",{},"Vous en avez assez de déployer manuellement votre site Nuxt ? Dans cet article, je vous montre comment automatiser l'ensemble du processus grâce à GitLab CI\u002FCD, du ",[15,16,17],"em",{},"commit"," jusqu'à la mise en ligne.",[20,21,23],"h2",{"id":22},"rappel-technique-concernant-nuxt","Rappel technique concernant Nuxt",[11,25,26,34,35,40,41,45],{},[27,28,33],"a",{"href":29,":target":30,"rel":31},"https:\u002F\u002Fnuxt.com","_blank",[32],"nofollow","Nuxt est un framework JavaScript","\nque j'utilise beaucoup ces derniers temps. Il est facile à mettre en place et permet de réaliser des sites web dynamiques, ",[27,36,39],{"href":37,"title":38},"\u002Farticles\u002Fcomment-verifier-si-votre-site-web-est-performant-seo-ux-vitesse","Comment vérifier si votre site web est performant ?","rapides et performants",". J'apprécie beaucoup le fait que l'on puisse compiler le projet pour générer des fichiers statiques prêts à être déposés sur un hébergement tout simple. ",[42,43,44],"strong",{},"C'est ce que l'on appelle le mode SSG (Static Site Generation)",".",[11,47,48],{},"Cette façon d'utiliser Nuxt me permet de déployer des sites très rapides à charger même lorsqu'ils contiennent des images volumineuses. Les images sont automatiquement optimisées et déclinées en plusieurs tailles selon la largeur d'écran.",[50,51,52],"blockquote",{},[11,53,54,55,58],{},"Lorsque le visiteur charge le site, il récupère directement le HTML, le JS et le CSS. ",[42,56,57],{},"Il n'y a aucun traitement réalisé côté serveur",". C'est comme si le site était perpétuellement en cache sur le serveur.",[20,60,62],{"id":61},"comment-se-passe-alors-une-mise-à-jour-de-contenu","Comment se passe alors une mise à jour de contenu ?",[11,64,65,66,69,70,73,74,45],{},"Ce type de site est adapté aux projets où il y a très peu de mises à jour. Cela peut être un site vitrine, un portfolio ou un site de chambres d'hôtes. Comme il n'y a pas d'interface admin, il est donc nécessaire de toucher au code, de recompiler le site puis de redéployer le site sur le serveur. ",[42,67,68],{},"Cela n'est pas très pratique",", mais heureusement, il est possible d'automatiser tout cela si vous utilisez ",[15,71,72],{},"Git"," et notamment ",[15,75,76],{},"Gitlab",[20,78,80],{"id":79},"découverte-et-mise-en-place-de-gitlab-ci","Découverte et mise en place de GitLab CI",[11,82,83,84,87,88,90],{},"Que ce soit chez GitHub ou Gitlab, le concept de ",[15,85,86],{},"CI"," (pour intégration continue) permet de déclencher des traitements automatiques lors d'un ",[15,89,17],{}," Git. Les opérations se font dans un container et peuvent être diverses et variées : vérification du code, compilation et envoi vers un serveur FTP distant par exemple. Pile-poil ce dont j'avais besoin !",[11,92,93,94,97,98,100],{},"Le point d'entrée de la CI chez Gitlab est le fichier ",[42,95,96],{},".gitlab-ci.yml",", à la racine du projet. On va décrire, au format YAML, les différentes étapes qui seront réalisées lors d'un ",[15,99,17],{},". Voici un premier point d'entrée :",[102,103,108],"pre",{"className":104,"code":105,"language":106,"meta":107,"style":107},"language-yml shiki shiki-themes github-light","stages:\n    - build\n    - deploy\n","yml","",[109,110,111,124,134],"code",{"__ignoreMap":107},[112,113,116,120],"span",{"class":114,"line":115},"line",1,[112,117,119],{"class":118},"shJU0","stages",[112,121,123],{"class":122},"sgsFI",":\n",[112,125,127,130],{"class":114,"line":126},2,[112,128,129],{"class":122},"    - ",[112,131,133],{"class":132},"sYBdl","build\n",[112,135,137,139],{"class":114,"line":136},3,[112,138,129],{"class":122},[112,140,141],{"class":132},"deploy\n",[11,143,144,145,148],{},"Ici, on a donc deux étapes qui seront réalisées les unes après les autres. Ensuite, on va pouvoir décrire chacune de ces étapes. Par exemple, l'étape du ",[109,146,147],{},"build"," :",[102,150,152],{"className":104,"code":151,"language":106,"meta":107,"style":107},"build:\n    stage: build\n    image: node:22\n    script:\n        - npm ci --cache .npm --prefer-offline\n        - npm run generate\n    artifacts:\n        paths:\n            - .output\u002Fpublic\n",[109,153,154,160,170,180,188,197,205,213,221],{"__ignoreMap":107},[112,155,156,158],{"class":114,"line":115},[112,157,147],{"class":118},[112,159,123],{"class":122},[112,161,162,165,168],{"class":114,"line":126},[112,163,164],{"class":118},"    stage",[112,166,167],{"class":122},": ",[112,169,133],{"class":132},[112,171,172,175,177],{"class":114,"line":136},[112,173,174],{"class":118},"    image",[112,176,167],{"class":122},[112,178,179],{"class":132},"node:22\n",[112,181,183,186],{"class":114,"line":182},4,[112,184,185],{"class":118},"    script",[112,187,123],{"class":122},[112,189,191,194],{"class":114,"line":190},5,[112,192,193],{"class":122},"        - ",[112,195,196],{"class":132},"npm ci --cache .npm --prefer-offline\n",[112,198,200,202],{"class":114,"line":199},6,[112,201,193],{"class":122},[112,203,204],{"class":132},"npm run generate\n",[112,206,208,211],{"class":114,"line":207},7,[112,209,210],{"class":118},"    artifacts",[112,212,123],{"class":122},[112,214,216,219],{"class":114,"line":215},8,[112,217,218],{"class":118},"        paths",[112,220,123],{"class":122},[112,222,224,227],{"class":114,"line":223},9,[112,225,226],{"class":122},"            - ",[112,228,229],{"class":132},".output\u002Fpublic\n",[11,231,232],{},"On utilise ici une image en Node v22 comme environnement d'exécution et on va lancer deux commandes :",[234,235,236,243],"ul",{},[237,238,239,242],"li",{},[109,240,241],{},"npm ci"," pour installer les dépendances de notre projet ;",[237,244,245,248],{},[109,246,247],{},"npm run generate"," pour créer la version SSG de notre application.",[50,250,251],{},[11,252,253,254,256,257,260,261,264],{},"Ici j'utilise ",[109,255,241],{}," plutôt que ",[109,258,259],{},"npm i",". Node utilise alors le fichier ",[15,262,263],{},"package-lock.json"," pour installer toutes les dépendances d'un coup. C'est le plus adapté aux environnements automatisés comme l'intégration continue.",[50,266,267],{},[11,268,269,270,273],{},"Les ",[15,271,272],{},"artifacts"," sont les données qui sont passées d'une étape à l'autre. Ici j'ai mis le dossier qui contient le site compilé.",[11,275,276,277,280,281,284],{},"L'étape ",[109,278,279],{},"deploy"," consiste donc à déployer le résultat de l'étape précédente sur un serveur distant. Pour cela, j'ai utilisé l'outil ",[109,282,283],{},"lftp"," qui permet de transférer les fichiers.",[102,286,288],{"className":104,"code":287,"language":106,"meta":107,"style":107},"deploy:\n    stage: deploy\n    timeout: 10 minutes\n    script:\n    - apt-get update -qq && apt-get install -y -qq lftp\n    - lftp -e \"set sftp:auto-confirm yes; mirror -R .\u002F.output\u002Fpublic\u002F \u002Fhome\u002Fsite\u002Fwww; quit\" -u utilisateur,m0td3p4ss3 sftp:\u002F\u002Fftp.herbergement.fr\n    only: [ master ]\n\n",[109,289,290,296,304,314,320,327,334],{"__ignoreMap":107},[112,291,292,294],{"class":114,"line":115},[112,293,279],{"class":118},[112,295,123],{"class":122},[112,297,298,300,302],{"class":114,"line":126},[112,299,164],{"class":118},[112,301,167],{"class":122},[112,303,141],{"class":132},[112,305,306,309,311],{"class":114,"line":136},[112,307,308],{"class":118},"    timeout",[112,310,167],{"class":122},[112,312,313],{"class":132},"10 minutes\n",[112,315,316,318],{"class":114,"line":182},[112,317,185],{"class":118},[112,319,123],{"class":122},[112,321,322,324],{"class":114,"line":190},[112,323,129],{"class":122},[112,325,326],{"class":132},"apt-get update -qq && apt-get install -y -qq lftp\n",[112,328,329,331],{"class":114,"line":199},[112,330,129],{"class":122},[112,332,333],{"class":132},"lftp -e \"set sftp:auto-confirm yes; mirror -R .\u002F.output\u002Fpublic\u002F \u002Fhome\u002Fsite\u002Fwww; quit\" -u utilisateur,m0td3p4ss3 sftp:\u002F\u002Fftp.herbergement.fr\n",[112,335,336,339,342,345],{"class":114,"line":207},[112,337,338],{"class":118},"    only",[112,340,341],{"class":122},": [ ",[112,343,344],{"class":132},"master",[112,346,347],{"class":122}," ]\n",[50,349,350],{},[11,351,352,353,356,357,360,361,363],{},"Le paramètre ",[109,354,355],{},"only"," permet d'indiquer que seuls les ",[15,358,359],{},"commits"," de la branche ",[15,362,344],{}," seront déployés sur le serveur distant.",[11,365,366,367,370,371,373,374,377],{},"Une alarme a sûrement sonné dans votre tête : ",[42,368,369],{},"les informations de connexion au serveur FTP sont en clair"," dans le fichier ",[42,372,96],{},". Heureusement, il est possible de les rendre invisibles via ",[15,375,376],{},"la gestion des secrets"," de Gitlab.",[20,379,381],{"id":380},"gestion-des-secrets","Gestion des secrets",[11,383,384,385,388,389,45],{},"Sur Gitlab, il faut se rendre dans ",[109,386,387],{},"Paramètres > CI\u002FCD"," puis dans la section ",[42,390,391],{},"Variables de projet",[11,393,394],{},[395,396],"img",{"alt":397,"src":398,"title":397},"Tableau de mes variables","img\u002Farticles\u002Fgitlab\u002Fgitlab-variables.png",[11,400,401],{},"Dans mon cas, j'ai ajouté les variables suivantes :",[234,403,404,410,416,422],{},[237,405,406,409],{},[109,407,408],{},"DEPLOY_HOST"," : l'hôte du serveur FTP auquel se connecter ;",[237,411,412,415],{},[109,413,414],{},"DEPLOY_USER"," : l'identifiant de connexion ;",[237,417,418,421],{},[109,419,420],{},"DEPLOY_PASSWORD"," : le mot de passe de connexion ;",[237,423,424,427],{},[109,425,426],{},"DEPLOY_PATH"," : le chemin où déposer les fichiers.",[50,429,430],{},[11,431,432,433,436,437,45],{},"Pensez à protéger les variables en les ",[42,434,435],{},"masquant"," et en ",[42,438,439],{},"cachant le mot de passe",[11,441,442,443,445],{},"On peut donc mettre à jour notre fichier ",[42,444,96],{},". Le voici au complet à ce stade :",[102,447,449],{"className":104,"code":448,"language":106,"meta":107,"style":107},"stages:\n    - build\n    - deploy\n\nbuild:\n    stage: build\n    image: node:22\n    script:\n        - npm ci --cache .npm --prefer-offline\n        - npm run generate\n    artifacts:\n        paths:\n            - .output\u002Fpublic\n\ndeploy:\n    stage: deploy\n    timeout: 10 minutes\n    script:\n    - apt-get update -qq && apt-get install -y -qq lftp\n    - lftp -e \"set sftp:auto-confirm yes; mirror -R .\u002F.output\u002Fpublic\u002F $DEPLOY_PATH; quit\" -u $DEPLOY_USER,$DEPLOY_PASSWORD sftp:\u002F\u002F$DEPLOY_HOST\n    only: [ master ]\n\n",[109,450,451,457,463,469,475,481,489,497,503,509,516,523,530,537,542,549,558,567,574,581,589],{"__ignoreMap":107},[112,452,453,455],{"class":114,"line":115},[112,454,119],{"class":118},[112,456,123],{"class":122},[112,458,459,461],{"class":114,"line":126},[112,460,129],{"class":122},[112,462,133],{"class":132},[112,464,465,467],{"class":114,"line":136},[112,466,129],{"class":122},[112,468,141],{"class":132},[112,470,471],{"class":114,"line":182},[112,472,474],{"emptyLinePlaceholder":473},true,"\n",[112,476,477,479],{"class":114,"line":190},[112,478,147],{"class":118},[112,480,123],{"class":122},[112,482,483,485,487],{"class":114,"line":199},[112,484,164],{"class":118},[112,486,167],{"class":122},[112,488,133],{"class":132},[112,490,491,493,495],{"class":114,"line":207},[112,492,174],{"class":118},[112,494,167],{"class":122},[112,496,179],{"class":132},[112,498,499,501],{"class":114,"line":215},[112,500,185],{"class":118},[112,502,123],{"class":122},[112,504,505,507],{"class":114,"line":223},[112,506,193],{"class":122},[112,508,196],{"class":132},[112,510,512,514],{"class":114,"line":511},10,[112,513,193],{"class":122},[112,515,204],{"class":132},[112,517,519,521],{"class":114,"line":518},11,[112,520,210],{"class":118},[112,522,123],{"class":122},[112,524,526,528],{"class":114,"line":525},12,[112,527,218],{"class":118},[112,529,123],{"class":122},[112,531,533,535],{"class":114,"line":532},13,[112,534,226],{"class":122},[112,536,229],{"class":132},[112,538,540],{"class":114,"line":539},14,[112,541,474],{"emptyLinePlaceholder":473},[112,543,545,547],{"class":114,"line":544},15,[112,546,279],{"class":118},[112,548,123],{"class":122},[112,550,552,554,556],{"class":114,"line":551},16,[112,553,164],{"class":118},[112,555,167],{"class":122},[112,557,141],{"class":132},[112,559,561,563,565],{"class":114,"line":560},17,[112,562,308],{"class":118},[112,564,167],{"class":122},[112,566,313],{"class":132},[112,568,570,572],{"class":114,"line":569},18,[112,571,185],{"class":118},[112,573,123],{"class":122},[112,575,577,579],{"class":114,"line":576},19,[112,578,129],{"class":122},[112,580,326],{"class":132},[112,582,584,586],{"class":114,"line":583},20,[112,585,129],{"class":122},[112,587,588],{"class":132},"lftp -e \"set sftp:auto-confirm yes; mirror -R .\u002F.output\u002Fpublic\u002F $DEPLOY_PATH; quit\" -u $DEPLOY_USER,$DEPLOY_PASSWORD sftp:\u002F\u002F$DEPLOY_HOST\n",[112,590,592,594,596,598],{"class":114,"line":591},21,[112,593,338],{"class":118},[112,595,341],{"class":122},[112,597,344],{"class":132},[112,599,347],{"class":122},[20,601,603],{"id":602},"tests-et-peaufinage","Tests et peaufinage",[11,605,606,607,609,610,612,613,616,617,620,621,624,625,628,629,631,632,634,635,637],{},"C'est le moment de tester ! Commencez par ",[15,608,17],{}," le fichier ",[42,611,96],{}," puis effectuez un ",[109,614,615],{},"git push",". Dans Gitlab, tout ce qui concerne le déploiement continu est dans le menu ",[42,618,619],{},"Compilation",". On y retrouve les ",[15,622,623],{},"jobs"," (chaque étape définie dans le YAML), mais également les ",[15,626,627],{},"pipelines"," qui regroupent ces ",[15,630,623],{}," pour chaque ",[15,633,17],{},". Un éditeur de pipeline permet de modifier directement en ligne notre fichier ",[42,636,96],{}," !",[11,639,640],{},[395,641],{"alt":642,"src":643,"title":642},"Les pipelines de Gitlab","img\u002Farticles\u002Fgitlab\u002Fgitlab-pipelines.png",[11,645,646,647,650],{},"Lorsqu'il y a une erreur, on peut consulter le détail du ",[15,648,649],{},"job"," concerné et observer la sortie du terminal. En général, après quelques itérations, on obtient une intégration continue fonctionnelle !",[20,652,654],{"id":653},"aller-plus-loin-avec-les-environnements","Aller plus loin avec les environnements",[11,656,657,658,664,665,668,669,671],{},"Tout ceci est chouette, mais il est fréquent d'avoir plusieurs branches et plusieurs destinations où déployer son code. ",[42,659,660,661],{},"Par exemple, un environnement de test \u002F pré-prod \u002F staging ne devrait se mettre à jour qu'avec le travail de la branche ",[15,662,663],{},"dev",", là où l'environnement de production ne devrait se mettre à jour qu'avec le code de la branche ",[15,666,667],{},"main"," ou ",[15,670,344],{},". Eh bien, c'est possible !",[11,673,674,675,678,679,681],{},"Dans Gitlab, on se rend dans ",[109,676,677],{},"Opération > Environnement"," et on crée deux environnements : dev et prod. Ensuite, dans la configuration des variables (",[109,680,387],{},"), on va pouvoir définir une valeur différente pour chacun des environnements.",[11,683,684],{},[395,685],{"alt":686,"src":687,"title":686},"Les variables selon un environnement","img\u002Farticles\u002Fgitlab\u002Fgitlab-variables-env.png",[50,689,690],{},[11,691,692,693,695],{},"Dans mon cas, j'ai défini un ",[109,694,426],{}," différent pour mes deux environnements, parce que mon environnement de développement et mon environnement de production sont sur la même machine. Rien ne vous empêche de configurer des utilisateurs, mots de passe et hôtes différents !",[11,697,698,699,701],{},"On peut ensuite adapter notre fichier ",[42,700,96],{}," pour tenir compte de ces environnements :",[102,703,705],{"className":104,"code":704,"language":106,"meta":107,"style":107},"stages:\n    - build\n    - dev\n    - prod\n\nbuild:\n    stage: build\n    image: node:22\n    script:\n        - npm ci --cache .npm --prefer-offline\n        - npm run generate\n    artifacts:\n        paths:\n            - .output\u002Fpublic\n\ndev:\n    stage: dev\n    environment: Dev\n    timeout: 10 minutes\n    script:\n    - apt-get update -qq && apt-get install -y -qq lftp\n    - lftp -e \"set sftp:auto-confirm yes; mirror -R .\u002F.output\u002Fpublic\u002F $DEPLOY_PATH; quit\" -u $DEPLOY_USER,$DEPLOY_PASSWORD sftp:\u002F\u002F$DEPLOY_HOST\n    except: [ master ]\n\nprod:\n    stage: prod\n    environment: Prod\n    timeout: 10 minutes\n    script:\n    - apt-get update -qq && apt-get install -y -qq lftp\n    - lftp -e \"set sftp:auto-confirm yes; mirror -R .\u002F.output\u002Fpublic\u002F $DEPLOY_PATH; quit\" -u $DEPLOY_USER,$DEPLOY_PASSWORD sftp:\u002F\u002F$DEPLOY_HOST\n    only: [ master ]\n",[109,706,707,713,719,726,733,737,743,751,759,765,771,777,783,789,795,799,805,813,823,831,837,843,850,862,867,875,884,894,903,910,917,924],{"__ignoreMap":107},[112,708,709,711],{"class":114,"line":115},[112,710,119],{"class":118},[112,712,123],{"class":122},[112,714,715,717],{"class":114,"line":126},[112,716,129],{"class":122},[112,718,133],{"class":132},[112,720,721,723],{"class":114,"line":136},[112,722,129],{"class":122},[112,724,725],{"class":132},"dev\n",[112,727,728,730],{"class":114,"line":182},[112,729,129],{"class":122},[112,731,732],{"class":132},"prod\n",[112,734,735],{"class":114,"line":190},[112,736,474],{"emptyLinePlaceholder":473},[112,738,739,741],{"class":114,"line":199},[112,740,147],{"class":118},[112,742,123],{"class":122},[112,744,745,747,749],{"class":114,"line":207},[112,746,164],{"class":118},[112,748,167],{"class":122},[112,750,133],{"class":132},[112,752,753,755,757],{"class":114,"line":215},[112,754,174],{"class":118},[112,756,167],{"class":122},[112,758,179],{"class":132},[112,760,761,763],{"class":114,"line":223},[112,762,185],{"class":118},[112,764,123],{"class":122},[112,766,767,769],{"class":114,"line":511},[112,768,193],{"class":122},[112,770,196],{"class":132},[112,772,773,775],{"class":114,"line":518},[112,774,193],{"class":122},[112,776,204],{"class":132},[112,778,779,781],{"class":114,"line":525},[112,780,210],{"class":118},[112,782,123],{"class":122},[112,784,785,787],{"class":114,"line":532},[112,786,218],{"class":118},[112,788,123],{"class":122},[112,790,791,793],{"class":114,"line":539},[112,792,226],{"class":122},[112,794,229],{"class":132},[112,796,797],{"class":114,"line":544},[112,798,474],{"emptyLinePlaceholder":473},[112,800,801,803],{"class":114,"line":551},[112,802,663],{"class":118},[112,804,123],{"class":122},[112,806,807,809,811],{"class":114,"line":560},[112,808,164],{"class":118},[112,810,167],{"class":122},[112,812,725],{"class":132},[112,814,815,818,820],{"class":114,"line":569},[112,816,817],{"class":118},"    environment",[112,819,167],{"class":122},[112,821,822],{"class":132},"Dev\n",[112,824,825,827,829],{"class":114,"line":576},[112,826,308],{"class":118},[112,828,167],{"class":122},[112,830,313],{"class":132},[112,832,833,835],{"class":114,"line":583},[112,834,185],{"class":118},[112,836,123],{"class":122},[112,838,839,841],{"class":114,"line":591},[112,840,129],{"class":122},[112,842,326],{"class":132},[112,844,846,848],{"class":114,"line":845},22,[112,847,129],{"class":122},[112,849,588],{"class":132},[112,851,853,856,858,860],{"class":114,"line":852},23,[112,854,855],{"class":118},"    except",[112,857,341],{"class":122},[112,859,344],{"class":132},[112,861,347],{"class":122},[112,863,865],{"class":114,"line":864},24,[112,866,474],{"emptyLinePlaceholder":473},[112,868,870,873],{"class":114,"line":869},25,[112,871,872],{"class":118},"prod",[112,874,123],{"class":122},[112,876,878,880,882],{"class":114,"line":877},26,[112,879,164],{"class":118},[112,881,167],{"class":122},[112,883,732],{"class":132},[112,885,887,889,891],{"class":114,"line":886},27,[112,888,817],{"class":118},[112,890,167],{"class":122},[112,892,893],{"class":132},"Prod\n",[112,895,897,899,901],{"class":114,"line":896},28,[112,898,308],{"class":118},[112,900,167],{"class":122},[112,902,313],{"class":132},[112,904,906,908],{"class":114,"line":905},29,[112,907,185],{"class":118},[112,909,123],{"class":122},[112,911,913,915],{"class":114,"line":912},30,[112,914,129],{"class":122},[112,916,326],{"class":132},[112,918,920,922],{"class":114,"line":919},31,[112,921,129],{"class":122},[112,923,588],{"class":132},[112,925,927,929,931,933],{"class":114,"line":926},32,[112,928,338],{"class":118},[112,930,341],{"class":122},[112,932,344],{"class":132},[112,934,347],{"class":122},[11,936,937,938,148],{},"On a donc maintenant trois ",[15,939,623],{},[234,941,942,947,959],{},[237,943,944,946],{},[109,945,147],{},", qui se charge de compiler le site ;",[237,948,949,951,952,955,956,958],{},[109,950,663],{},", qui utilise l'environnement ",[15,953,954],{},"« Dev »"," pour les variables et qui sera lancé sur toutes les branches sauf ",[15,957,344],{}," ;",[237,960,961,951,963,966,967,969,970,45],{},[109,962,872],{},[15,964,965],{},"« Prod »"," et qui ne se déclenchera que pour les ",[15,968,359],{}," sur la branche ",[15,971,344],{},[11,973,974,975,977],{},"De cette façon, lorsque nous faisons un ",[15,976,17],{},", c'est automatiquement déployé sur un environnement ou l'autre.",[20,979,981],{"id":980},"ce-que-ça-change-au-quotidien","Ce que ça change au quotidien",[11,983,984,985,990,991,993],{},"Si je prends l'exemple du site sur lequel vous lisez cet article, une bonne partie du contenu est rédigée en Markdown et affichée à l'aide du ",[27,986,989],{"href":987,":target":30,"rel":988},"https:\u002F\u002Fcontent.nuxt.com\u002F",[32],"module Nuxt Content","\n. Pour le mettre à jour, j'ai simplement besoin d'un éditeur de texte et de réaliser un ",[15,992,17],{},". Le reste se fait automatiquement, sans que j'aie à y penser.",[50,995,996],{},[11,997,998],{},"Bonus : il y a directement dans Gitlab un éditeur de code, je peux donc éditer mon contenu même en déplacement tant que j'ai accès à mon compte.Z",[11,1000,1001],{},"Si l'on travaille seul, mais que l'on travaille sur de multiples projets, avec des technos différentes et surtout des versions de Node différentes, cela simplifie grandement le travail : toute la procédure de déploiement est consignée dans un fichier et est exécutée automatiquement.",[11,1003,1004,1005],{},"Si l'on travaille à plusieurs, c'est aussi un avantage : on n'a pas à expliquer comment mettre à jour le site et encore moins à partager les informations de connexion. ",[42,1006,1007,1008,1011],{},"C'est aussi l'endroit parfait pour ajouter les tests unitaires, du ",[15,1009,1010],{},"linting"," et d'autres automatismes !",[1013,1014,1016,1019],"cta-card",{"title":1015},"Vous avez besoin d'accompagnement ?",[11,1017,1018],{},"Je peux vous assister dans la mise en place d'une pipeline d'intégration et de déploiement continu pour votre projet.",[11,1020,1021],{},"N'hésitez pas à me contacter !",[20,1023,1025],{"id":1024},"ressources-utiles","Ressources utiles",[234,1027,1028,1036,1043],{},[237,1029,1030,1035],{},[27,1031,1034],{"href":1032,":target":30,"rel":1033},"https:\u002F\u002Fdocs.gitlab.com\u002Fee\u002Fci\u002F",[32],"Documentation officielle de GitLab CI\u002FCD","\n(en)",[237,1037,1038,1035],{},[27,1039,1042],{"href":1040,":target":30,"rel":1041},"https:\u002F\u002Fdocs.gitlab.com\u002Fee\u002Fci\u002Fvariables\u002F",[32],"Guide GitLab sur les variables de pipeline",[237,1044,1045,1035],{},[27,1046,1049],{"href":1047,":target":30,"rel":1048},"https:\u002F\u002Fnuxt.com\u002Fdocs\u002Fgetting-started\u002Fdeployment",[32],"Documentation Nuxt sur le déploiement statique",[1051,1052,1053],"style",{},"html pre.shiki code .shJU0, html code.shiki .shJU0{--shiki-default:#22863A}html pre.shiki code .sgsFI, html code.shiki .sgsFI{--shiki-default:#24292E}html pre.shiki code .sYBdl, html code.shiki .sYBdl{--shiki-default:#032F62}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);}",{"title":107,"searchDepth":126,"depth":126,"links":1055},[1056,1057,1058,1059,1060,1061,1062,1063],{"id":22,"depth":126,"text":23},{"id":61,"depth":126,"text":62},{"id":79,"depth":126,"text":80},{"id":380,"depth":126,"text":381},{"id":602,"depth":126,"text":603},{"id":653,"depth":126,"text":654},{"id":980,"depth":126,"text":981},{"id":1024,"depth":126,"text":1025},"2025-10-15","Automatisez le déploiement de votre site Nuxt grâce à GitLab CI\u002FCD. Découvrez pas à pas comment configurer une pipeline et déployer votre site à chaque commit",false,"md",{},"\u002Farticles\u002Fdeploiement-site-nuxt-avec-gitlab",{"title":6,"description":1065},"gitlab-deployer-automatiquement-un-site-nuxt","articles\u002FDéploiement site Nuxt avec Gitlab",[76,1074,1075],"Nuxt","CI-CD","\u002Fimg\u002Farticles\u002Fgitlab\u002Fnuxt-gitlab.png","2Rhph8l2S_nacnmG9CQvdj9rfV6z7gk23ecZWZuekxE",1777297034120]