Déployez le code directement dans le conteneur Docker. Ou comment ne pas tergiverser après chaque commit

La tâche est venue WEB-12982
Créer une branche web-12982 dans le référentiel
Pendant le trajet, lisez tz et buvez du café
Procéder directement au développement

git commit, git push
Pendant que la branche se rassemble
git commit, git push
Pendant que la succursale est reconstruite, retourner Twitter
git commit, git push
...
Vous remettez une branche d'avis avec 50 commits

Vous comprenez que 50 commits sont exactement 50 minutes de temps pur, qui sont collectées par à-coups, car les intervalles de 1 minute sont trop petits pour faire autre chose que la procrastination et les besoins de base.


La situation est-elle familière? Dans mon entreprise, l'infrastructure de développement est organisée comme suit:


  • Hitlab dispose de nombreux rĂ©fĂ©rentiels de projets
  • Pour garantir la facilitĂ© de dĂ©veloppement lors de la crĂ©ation d'une nouvelle branche, les dockers crĂ©ent automatiquement leur propre sandbox Ă  une adresse unique, une copie complète de la branche parente avec tout l'environnement nĂ©cessaire.
  • Tout ce dont vous avez besoin est prĂŞt - il suffit d'Ă©crire le code et de tester-voir-Ă©valuer le rĂ©sultat après chaque commit, c'est très pratique!

Mais, lentement ... Si cette situation est proche de vous, bienvenue sous cat.



L'essence du problème


tldr: les modifications apportées au code nécessitent de réassembler les conteneurs et de passer du temps (plus d'une minute, cela dépend du projet, surtout si CI \ CD est configuré), ce qui en fait ne peut pas être utilisé utilement, mais qui prend totalement une partie décente du temps de travail du programmeur.

Des problèmes similaires apparaissent périodiquement dans tous

Par exemple, le même liveReload pour le frontend a été clairement inventé pour une raison


J'ai déjà publié un article sur un sujet connexe , mais lié au processus de débogage (Au fait, merci pour les commentaires informatifs et les retours positifs). Cependant, le problème de la coupe n'a pratiquement pas disparu, nous continuons également à attendre le remontage de la branche.


Même si vous sautez les étapes supplémentaires et ne laissez que build-dev et deploy-dev, le temps d'attente est insignifiant pour toutes les actions utiles, mais considérablement dans le temps total passé, en particulier en ce qui concerne CI \ CD, par exemple, depuis Gitlab.


Bien sûr, vous pouvez accélérer le processus en assemblant le projet localement, à condition que le programmeur dispose d'un ordinateur relativement puissant, que gitlab-runner soit configuré, que le même environnement soit configuré que sur le serveur distant et que les balises correspondantes soient ajoutées à gitlab-ci.yml, mais je doute que la vitesse de construction sera la même que le déploiement automatique du code FTP après les touches ctrl + s.


Surtout brûle exaspère c'est épuisant quand, pendant le processus de développement, vous faites des fautes de frappe / erreurs qui n'affectent généralement pas le fonctionnement de l'application, mais qui ne peuvent pas être laissées comme ça et que vous ne les remarquez que lorsque vous regardez le résultat après l'assemblage.


Ce qui est requis et les options de solution


tldr: trouvez un moyen de voir le résultat de vos modifications aussi simplement et rapidement que possible. Afin de ne pas s'engager à chaque fois et de ne pas attendre la reconstruction de la branche. J'ai sélectionné rsync de l'ordinateur local vers le dossier du serveur distant monté avec le dossier du conteneur.

Je n'ai pas trouvé de solution complète sur Internet, mais en fait il y a plusieurs options:


  • Configurer ftp \ ssh directement dans le conteneur avec la base de code, l'inclure dans l'image, se connecter via FTP directement au conteneur lui-mĂŞme
    • Personnellement, cette option me semblait un peu compliquĂ©e, et trop «bĂ©quille», bien qu'ici toutes les options soient des bĂ©quilles
  • (pour une utilisation locale) utilisez docker cp pour charger le code directement dans le conteneur
    • L'option ne convient pas pour travailler avec un serveur distant.
    • docker cp a des fonctionnalitĂ©s extrĂŞmement limitĂ©es, Ă©tant donnĂ© les dossiers des fournisseurs qui ne devraient pas ĂŞtre copiĂ©s Ă  chaque fois, et l'algorithme de copie lui-mĂŞme, ce sera plutĂ´t lent.
  • (pour une utilisation Ă  distance \ locale) Montez le dossier conteneur souhaitĂ© dans le dossier hĂ´te externe. TĂ©lĂ©chargez les fichiers locaux directement dans le dossier hĂ´te montĂ©. Il existe dĂ©jĂ  de nombreuses options de mise en Ĺ“uvre:
    • Utiliser docker-machine et spĂ©cifiquement docker-machine scp
      • Encore une fois, vous devez configurer l'environnement, configurer docker-machine, peut-ĂŞtre que cela a du sens lorsque vous travaillez constamment avec diffĂ©rents serveurs
    • Dans l'EDI, configurez une connexion FTP avec le dossier hĂ´te souhaitĂ©
      • Chaque nouvelle branche nĂ©cessite la crĂ©ation d'une nouvelle connexion ou la modification des mappages
    • Utilisez scp ou rsync pour tĂ©lĂ©charger des fichiers dans le dossier hĂ´te souhaitĂ©, pour cela utilisez un petit script bash et accrochez-le sur les touches de raccourci
      • Au dĂ©but, cela semble inutilement compliquĂ©, mais en fait ce n'est pas le cas. Le script lui-mĂŞme est aussi simple que possible et nĂ©cessaire pour automatiser le processus afin que vous n'ayez pas Ă  reconfigurer les mappages Ă  chaque fois

Solution elle-mĂŞme: volumes rsync +


tldr:
  • Besoin d'un accès ssh Ă  un serveur distant et rsync sur la machine locale
  • Le serveur distant doit avoir un dossier accessible en Ă©criture
  • Montez le dossier du projet dans le conteneur sur le dossier hĂ´te externe
  • Ajoutez un petit script bash Ă  la racine du projet pour synchroniser les fichiers avec le serveur distant
  • Configurer un raccourci clavier pour l'exĂ©cution du script de synchronisation

Il convient de noter que la solution fournie est exclue pour le développement et l'environnement de test


Dans ce cas, je vais regarder les environnements docker-compose et gitlab-ci, avec docker-compose en utilisant les variables d'environnement de gitlab-ci.


Nous formons le chemin vers le dossier de destination dans gitlab-ci et exportons ce chemin vers docker-compose.yml:


before_script: - export SHARED_DIR_BASE='/var/www/builds' #    ,      - export SHARED_BRANCH_DIR=${SHARED_DIR_BASE}/${PROJECT_GROUP}/${PROJECT_NAME}/${CI_COMMIT_REF_NAME} #     web-123   my_group/my_project,      /var/shared/my_group/my_project/web-123 Deploy dev: stage: deploy_dev script: #   ,         - mkdir -p ${SHARED_BRANCH_DIR} - rsync -r --exclude-from=.gitignore --exclude-from=.dockerignore . ${SHARED_BRANCH_DIR} - find ${SHARED_BRANCH_DIR} -type d -exec setfacl -d -mo:rwx {} \; - find ${SHARED_BRANCH_DIR} -type d -exec setfacl -mo:rwx {} \; - find ${SHARED_BRANCH_DIR} -type f -exec setfacl -mo:rwx {} \; - envsubst < docker-compose.tmpl > docker-compose.yml #     gitlab-ci.yml  docker-compose.yml,   docker-compose.tmpl - docker-compose up -d 

Ensuite, nous devons monter les dossiers du projet dans le dossier hôte externe dans docker-compose, puisque nous utilisons les variables dans docker-compose, nous avons besoin du modèle docker-compose.tmpl dans lequel nous utiliserons ces variables.


 version: '2.3' services: web: ... volumes: - ${SHARED_BRANCH_DIR}:/app/:rw #             #        .    ,      ,           .              ,     ,        - /app/protected/vendor/ 

La configuration actuelle est suffisante, maintenant lorsque vous créez la branche sur le serveur hôte, le dossier / var / www / builds / GROUP_NAME / PROJECT_NAME / BRANCH_NAME sera créé et le projet y sera transféré à l'exception des fichiers et dossiers spécifiés dans .gitignore et .dockerignore, puis vous pouvez simplement configurer les mappages FTP, mais nous irons un peu plus loin et rendrons le processus un peu plus automatisé.


En fait, pour synchroniser les fichiers, nous devons exécuter quelque chose comme ceci:


 rsync -r -u \ --delete-after \ --exclude-from=.gitignore \ --exclude-from=.dockerignore \ . $sshUserName@$sshHost:$sharedBaseDir 

En fait, sur les projets de petite à moyenne taille, cette commande s'exécutera plus rapidement que vous n'avez le temps de valider et de pousser les modifications dans le référentiel. Il reste à apporter à ce script un aspect plus complet et à lier son exécution aux touches de raccourci.


Code de script complet: deploy.sh
 #!/usr/bin/env bash #    while [ -n "$1" ] do case "$1" in --sshUserName=*) sshUserName=${1#*=} ;; --sshHost=*) sshHost=${1#*=} ;; esac shift done #  shared    gitBranch=$(git branch | grep \* | cut -d ' ' -f2) gitProject=$(git config --local remote.origin.url|sed -n 's#.*/\([^.]*\)\.git#\1#p') gitGroup=$(git config --local remote.origin.url|sed -n 's#.*/\([^.]*\)/.*\.git#\1#p') sharedBaseDir=/var/www/builds/$gitGroup/$gitProject/$gitBranch #         rsync -r -u \ --delete-after \ --exclude-from=.gitignore \ --exclude-from=.dockerignore \ . $sshUserName@$sshHost:$sharedBaseDir echo "done" 

Il convient de noter que le script doit être situé à la racine du dossier de projet du référentiel ou indiquer dans quel répertoire il doit fonctionner.


Il ne reste plus qu'à fixer l'exécution de ce script à des raccourcis clavier spécifiques et à définir les paramètres sshUserName et sshHost (il est entendu qu'il existe déjà un accès au serveur distant via ssh). Comment faire cela, je vais donner un exemple de PHPstorm.


  • Allez dans Fichier -> Paramètres
  • Dans la fenĂŞtre des paramètres du menu de gauche, dĂ©veloppez Outils , sĂ©lectionnez Outils externes
  • Nous Ă©crivons le chemin d'accès au script et spĂ©cifions le vrai sshUserName et sshHost dans les arguments

  • Ensuite, allez dans Keymap et recherchez le nom de nos outils externes, dĂ©finissez la combinaison nĂ©cessaire


C’est tout. À présent, lorsque vous cliquez sur la combinaison souhaitée, tous les fichiers de projet sont synchronisés avec le dossier distant, qui est monté avec le dossier de projet à l'intérieur du conteneur. Autrement dit, tous les changements seront visibles presque immédiatement.


Je ne prétends pas être "idéal" de cette solution, il y a probablement de meilleures options, je serai content si je les découvre dans les commentaires. Je vous remercie!

Source: https://habr.com/ru/post/fr439262/


All Articles