portaldacalheta.pt
  • Principal
  • La Technologie
  • Personnes Et Équipes
  • Gestion De Projet
  • Équipes Distribuées
Back-End

Comment créer un pipeline de déploiement initial efficace



J'adore construire des choses - ce que le développeur n'aime pas? J'adore trouver des solutions à des problèmes intéressants, écrire des implémentations et créer du beau code. Cependant, ce que je n'aime pas, c'est les opérations . Les opérations sont tout ne pas impliquée dans la création de logiciels performants, de la configuration des serveurs à la livraison de votre code à la production.

Ceci est intéressant, car en tant que développeur Ruby on Rails indépendant, je dois souvent créer de nouvelles applications Web et répéter le processus de détermination du DevOps côté des choses. Heureusement, après avoir créé des dizaines d’applications, j’ai finalement choisi une solution parfaite initiale pipeline de déploiement. Malheureusement, tout le monde n’a pas compris comme moi. Finalement, ces connaissances m’ont amené à franchir le pas et à documenter mon processus.



Dans cet article, je vais vous expliquer mon pipeline idéal à utiliser au début de votre projet. Avec mon pipeline, chaque push est testé, la branche principale est déployée en préparation avec une nouvelle sauvegarde de la base de données de la production et les balises versionnées sont déployées en production avec des sauvegardes et des migrations se déroulant automatiquement.



la différence entre s corp et c corp

Remarque, puisque c'est mon pipeline, il est également avisé et adapté à mes besoins; Cependant, vous pouvez échanger tout ce que vous n'aimez pas et le remplacer par ce qui vous plaît. Pour mon pipeline, nous utiliserons:



  • GitLab pour héberger le code.
    • Pourquoi: Mes clients préfèrent que leur code reste secret, et l'offre gratuite de GitLab est formidable. De plus, le CI gratuit intégré est génial. Merci GitLab!
    • Alternatives: GitHub, BitBucket, AWS CodeCommit et bien d'autres.
  • GitLab CI pour créer, tester et déployer notre code.
    • Pourquoi: Il s'intègre à GitLab et est gratuit!
    • Alternatives: TravisCI, Codeship, CircleCI, DIY avec Fabric8 et bien d'autres.
  • Heroku pour héberger notre application.
    • Pourquoi: Cela fonctionne dès la sortie de la boîte et constitue la plate-forme idéale pour commencer. Vous pouvez changer cela à l'avenir, mais toutes les nouvelles applications ne doivent pas nécessairement s'exécuter sur un cluster Kubernetes spécialement conçu. Même Coinbase a commencé sur Heroku .
    • Alternatives: AWS, DigitalOcean, Vultr, DIY avec Kubernetes et bien d'autres.

Old-school: créez une application de base et déployez-la sur Heroku

Tout d'abord, recréons une application typique pour quelqu'un qui n'utilise pas de pipelines CI / CD sophistiqués et qui souhaite simplement déployer son application.

Schéma de l



Le type d'application que vous créez n'a pas d'importance, mais vous aurez besoin de Yarn ou de npm. Pour mon exemple, je crée une application Ruby on Rails car elle est fournie avec des migrations et une CLI, et j'ai déjà la configuration écrite pour elle. Vous pouvez utiliser n'importe quel framework ou langage que vous préférez, mais vous aurez besoin de Yarn pour faire le contrôle de version que je ferai plus tard. Je crée une application CRUD simple en utilisant seulement quelques commandes et aucune authentification.

Et testons si notre application fonctionne comme prévu. Je suis allé de l'avant et j'ai créé quelques articles, juste pour m'en assurer.



L

Et déployons-le sur Heroku en poussant notre code et en exécutant des migrations



$ heroku create toptal-pipeline Creating ⬢ toptal-pipeline... done https://toptal-pipeline.herokuapp.com/ | https://git.heroku.com/toptal-pipeline.git $ git push heroku master Counting objects: 132, done. ... To https://git.heroku.com/toptal-pipeline.git * [new branch] master -> master $ heroku run rails db:migrate Running rails db:migrate on ⬢ toptal-pipeline... up, run.9653 (Free) ...

Enfin, testons-le en production

L



Et c'est tout! En règle générale, c'est là que la plupart des développeurs abandonnent leurs opérations. À l'avenir, si vous apportez des modifications, vous devrez répéter les étapes de déploiement et de migration ci-dessus. Vous pouvez même exécuter des tests si vous n’êtes pas en retard pour le dîner. C'est un excellent point de départ, mais réfléchissons un peu plus à cette méthode.

Avantages



  • Mise en place rapide.
  • Les déploiements sont faciles.

Les inconvénients

  • Not DRY: nécessite de répéter les mêmes étapes à chaque changement.
  • Pas de version: 'Je rétablis le déploiement d'hier sur celui de la semaine dernière' n'est pas très précis dans trois semaines.
  • Pas mal à l'épreuve du code: vous savez que vous êtes censé exécuter des tests, mais personne ne le regarde, vous pouvez donc le pousser malgré les tests parfois interrompus.
  • Pas mal à l'épreuve des acteurs: que se passe-t-il si un développeur mécontent décide de casser votre application en envoyant du code avec un message indiquant que vous ne commandez pas assez de pizzas pour votre équipe?
  • Ne s'adapte pas: autoriser chaque développeur à se déployer lui donnerait un accès de niveau production à l'application, ce qui enfreindrait le Principe du moindre privilège .
  • Pas d'environnement de préparation: les erreurs spécifiques à l'environnement de production n'apparaîtront pas avant la production.

Le pipeline de déploiement initial parfait

Je vais essayer quelque chose de différent aujourd'hui: ayons une conversation hypothétique. Je vais donner une voix à «vous» et nous parlerons de la manière dont nous pouvons améliorer ce flux actuel. Allez-y, dites quelque chose.

Tu peux répéter s'il te plait? Attends, je peux parler?

Oui, c’est ce que je voulais dire en vous donnant une voix. Comment vas-tu?

Je vais bien. C'est bizarre

Je comprends, mais continuez avec. Parlons maintenant de notre pipeline. Quelle est la partie la plus ennuyeuse de l'exécution de déploiements?

Oh, c’est facile. Le temps que je perds. Avez-vous déjà essayé de pousser vers Heroku?

Ouais, regardez le téléchargement de vos dépendances et l'application en cours de construction dans le cadre de git push c'est horrible!

N'est-ce pas? C'est fou. J'aurais aimé ne pas avoir à faire ça. Il y a aussi le fait que je dois exécuter des migrations * après * le déploiement, je dois donc regarder l'émission et vérifier que mon déploiement se déroule bien

D'accord, vous pouvez en fait résoudre ce dernier problème en enchaînant les deux commandes avec &&, comme git push heroku master && heroku run rails db:migrate, ou simplement en créant un script bash et en le mettant dans votre code, mais quand même, bonne réponse, l'heure et la répétition est une vraie douleur.

Ouais, ça craint vraiment

Et si je vous disais que vous pouvez résoudre ce problème immédiatement avec un pipeline CI / CD?

Un quoi maintenant? Qu'est-ce que c'est?

CI / CD signifie intégration continue (CI) et livraison / déploiement continu (CD). Il était assez difficile pour moi de comprendre exactement ce que c'était quand je commençais parce que tout le monde utilisait des termes vagues comme «fusion du développement et des opérations», mais en d'autres termes:

  • Intégration continue: Assurez-vous que tout votre code est fusionné en un seul endroit. Demandez à votre équipe d'utiliser Git et vous utiliserez CI.
  • Livraison continue: Assurez-vous que votre code est continuellement prêt à être expédié. Cela signifie produire rapidement une version de lecture-distribution de votre produit.
  • Déploiement continu: Transférer le produit de manière transparente de la livraison continue et simplement le déployer sur vos serveurs.

Oh, je comprends maintenant. Il s’agit de faire en sorte que mon application se déploie comme par magie dans le monde!

Mon article préféré expliquant CI / CD est par Atlassian Ici . Cela devrait éclaircir toutes vos questions. Quoi qu'il en soit, revenons au problème.

Ouais, revenons à ça. Comment éviter les déploiements manuels?

Configuration d'un pipeline CI / CD à déployer sur Push to master

Et si je vous disais que vous pouvez réparer ce bit immédiatement avec un CI / CD? Vous pouvez pousser sur votre télécommande GitLab (origin) et un ordinateur sera généré pour pousser directement votre code vers Heroku.

En aucune façon!

Ouais façon! Revenons au code.

Schéma d

Créez un .gitlab-ci.yml avec le contenu suivant, échange toptal-pipeline pour le nom de votre application Heroku:

image: ruby:2.4 before_script: - > : '${HEROKU_EMAIL:?Please set HEROKU_EMAIL in your CI/CD config vars}' - > : '${HEROKU_AUTH_TOKEN:?Please set HEROKU_AUTH_TOKEN in your CI/CD config vars}' - curl https://cli-assets.heroku.com/install-standalone.sh | sh - | cat >~/.netrc <[email protected] ' - git config --global user.name 'CI/CD' variables: APPNAME_PRODUCTION: toptal-pipeline deploy_to_production: stage: deploy environment: name: production url: https://$APPNAME_PRODUCTION.herokuapp.com/ script: - git remote add heroku https://git.heroku.com/$APPNAME_PRODUCTION.git - git push heroku master - heroku pg:backups:capture --app $APPNAME_PRODUCTION - heroku run rails db:migrate --app $APPNAME_PRODUCTION only: - master

Poussez ceci et observez son échec sur la page Pipelines de votre projet. C'est parce qu'il manque les clés d'authentification de votre compte Heroku. La correction est assez simple, cependant. Vous aurez d'abord besoin de votre Heroku Clé API . Obtenez-le du Gérer la page de compte , puis ajoutez ce qui suit variables secrètes dans les paramètres CI / CD de votre dépôt GitLab:

  • HEROKU_EMAIL: L'adresse e-mail que vous utilisez pour vous connecter à Heroku
  • HEROKU_AUTH_KEY: La clé que vous avez obtenue d'Heroku

Image des variables secrètes dans la page des paramètres GitLab CI / CD

Cela devrait aboutir à un déploiement de GitLab vers Heroku à chaque poussée. Quant à ce qui se passe:

  • En poussant à maîtriser
    • La CLI Heroku est installée et authentifiée dans un conteneur.
    • Votre code est transmis à Heroku.
    • Une sauvegarde de votre base de données est capturée dans Heroku.
    • Les migrations sont exécutées.

Déjà, vous pouvez voir que non seulement vous gagnez du temps en automatisant tout en un git push, mais vous créez également une sauvegarde de votre base de données à chaque déploiement! Si quelque chose ne va pas, vous aurez une copie de votre base de données sur laquelle revenir.

Création d'un environnement de préparation

Mais attendez, question rapide, qu'advient-il de vos problèmes spécifiques à la production? Que faire si vous rencontrez un bug étrange parce que votre environnement de développement est trop différent de celui de production? Une fois, j'ai rencontré des problèmes étranges avec SQLite 3 et PostgreSQL lorsque j'ai effectué une migration. Les détails m'échappent, mais c'est tout à fait possible.

J'utilise strictement PostgreSQL dans le développement, je ne mésadapte jamais aux moteurs de base de données comme ça, et je surveille attentivement ma pile pour d'éventuelles incompatibilités.

Eh bien, c’est un travail fastidieux et je salue votre discipline. Personnellement, je suis beaucoup trop paresseux pour faire ça. Cependant, pouvez-vous garantir ce niveau de diligence à tous les futurs développeurs, collaborateurs ou contributeurs potentiels?

Euh, non. Vous m'avez bien eu. D'autres personnes vont tout gâcher. Quel est votre point de vue, cependant?

Mon point est que vous avez besoin d'un environnement de mise en scène. C’est comme la production, mais ce n’est pas le cas. Un environnement de préparation est l'endroit où vous répétez le déploiement en production et détectez toutes vos erreurs tôt. Mes environnements de préparation reflètent généralement la production et je vide une copie de la base de données de production lors du déploiement intermédiaire pour m'assurer qu'aucun cas compliqué ne perturbe mes migrations. Avec un environnement de mise en scène, vous pouvez arrêter de traiter vos utilisateurs comme des cobayes.

C'est logique! Alors comment faire ça?

Voici où cela devient intéressant. J'aime déployer master directement à la mise en scène.

Attendez, n'est-ce pas là que nous déployons actuellement la production?

Oui, mais maintenant, nous allons déployer à la place.

Mais si master déploie en staging, comment déployer en production?

En utilisant quelque chose que vous auriez dû faire il y a des années: le versionnage de notre code et l'envoi de balises Git.

Balises Git? Qui utilise les balises Git?! Cela commence à sembler beaucoup de travail.

C'était bien sûr, mais heureusement, j'ai déjà fait tout ce travail et vous pouvez simplement vider mon code et cela fonctionnera.

Vue d

Tout d'abord, ajoutez un bloc sur le déploiement intermédiaire à votre .gitlab-ci.yml fichier, j'ai créé une nouvelle application Heroku appelée toptal-pipeline-staging:

… variables: APPNAME_PRODUCTION: toptal-pipeline APPNAME_STAGING: toptal-pipeline-staging deploy_to_staging: stage: deploy environment: name: staging url: https://$APPNAME_STAGING.herokuapp.com/ script: - git remote add heroku https://git.heroku.com/$APPNAME_STAGING.git - git push heroku master - heroku pg:backups:capture --app $APPNAME_PRODUCTION - heroku pg:backups:restore `heroku pg:backups:url --app $APPNAME_PRODUCTION` --app $APPNAME_STAGING --confirm $APPNAME_STAGING - heroku run rails db:migrate --app $APPNAME_STAGING only: - master - tags ...

Modifiez ensuite la dernière ligne de votre bloc de production pour qu'elle s'exécute sur des balises Git versionnées sémantiquement au lieu de la branche principale:

deploy_to_production: ... only: - /^v(?'MAJOR'(?:0|(?:[1-9]d*))).(?'MINOR'(?:0|(?:[1-9]d*))).(?'PATCH'(?:0|(?:[1-9]d*)))(?:-(?'prerelease'[0-9A-Za-z-]+(.[0-9A-Za-z-]+)*))?(?:+(?'build'[0-9A-Za-z-]+(.[0-9A-Za-z-]+)*))?$/ # semver pattern above is adapted from https://github.com/semver/semver.org/issues/59#issuecomment-57884619

L'exécuter maintenant échouera car GitLab est suffisamment intelligent pour n'autoriser que les branches «protégées» à accéder à nos variables secrètes. Pour ajouter des balises de version, accédez à la page des paramètres du référentiel de votre projet GitLab et ajoutez v* aux balises protégées.

Image de la balise de version ajoutée aux balises protégées dans la page des paramètres du référentiel

Récapitulons ce qui se passe actuellement:

  • En poussant vers master ou en poussant un commit balisé
    • La CLI Heroku est installée et authentifiée dans un conteneur.
    • Votre code est transmis à Heroku.
    • Une sauvegarde de la production de votre base de données est capturée dans Heroku.
    • La sauvegarde est sauvegardée dans votre environnement intermédiaire.
    • Les migrations sont exécutées sur la base de données intermédiaire.
  • En poussant un commit sémantiquement balisé de version
    • La CLI Heroku est installée et authentifiée dans un conteneur.
    • Votre code est transmis à Heroku.
    • Une sauvegarde de la production de votre base de données est capturée dans Heroku.
    • Les migrations sont exécutées sur la base de données de production.

Vous sentez-vous puissant maintenant? Je me sens puissant. Je me souviens que la première fois que je suis arrivé aussi loin, j'ai appelé ma femme et lui ai expliqué tout ce pipeline avec des détails atroces. Et elle n’est même pas technique. J'ai été très impressionné par moi-même et vous devriez l'être aussi! Excellent travail à venir jusqu'ici!

Tester chaque poussée

Mais il y a plus, puisqu'un ordinateur fait des choses pour vous de toute façon, il peut également exécuter toutes les choses que vous êtes trop paresseux pour faire: des tests, des erreurs de peluchage, à peu près tout ce que vous voulez faire, et si l'un de ces échouent, ils ont gagné ne passe pas au déploiement.

J'adore avoir cela dans mon pipeline, cela rend mes révisions de code amusantes. Si une demande de fusion réussit toutes mes vérifications de code, elle mérite d'être examinée.

Image de test à chaque poussée

Ajouter un test bloquer:

test: stage: test variables: POSTGRES_USER: test POSTGRES_PASSSWORD: test-password POSTGRES_DB: test DATABASE_URL: postgres://${POSTGRES_USER}:${POSTGRES_PASSSWORD}@postgres/${POSTGRES_DB} RAILS_ENV: test services: - postgres:alpine before_script: - curl -sL https://deb.nodesource.com/setup_8.x | bash - apt-get update -qq && apt-get install -yqq nodejs libpq-dev - curl -o- -L https://yarnpkg.com/install.sh | bash - source ~/.bashrc - yarn - gem install bundler --no-ri --no-rdoc - bundle install -j $(nproc) --path vendor - bundle exec rake db:setup RAILS_ENV=test script: - bundle exec rake spec - bundle exec rubocop

Récapitulons ce qui se passe actuellement:

  • À chaque demande de poussée ou de fusion
    • Ruby et Node sont installés dans un conteneur.
    • Les dépendances sont installées.
    • L'application est testée.
  • En poussant vers master ou en poussant un commit balisé, et seulement si tous les tests réussissent
    • La CLI Heroku est installée et authentifiée dans un conteneur.
    • Votre code est transmis à Heroku.
    • Une sauvegarde de la production de votre base de données est capturée dans Heroku.
    • La sauvegarde est sauvegardée dans votre environnement intermédiaire.
    • Les migrations sont exécutées sur la base de données intermédiaire.
  • En poussant un commit sémantiquement balisé de version, et seulement si tous les tests réussissent
    • La CLI Heroku est installée et authentifiée dans un conteneur.
    • Votre code est transmis à Heroku.
    • Une sauvegarde de la production de votre base de données est capturée dans Heroku.
    • Les migrations sont exécutées sur la base de données de production.

Prenez du recul et émerveillez-vous devant le niveau d’automatisation que vous avez accompli. À partir de maintenant, il ne vous reste plus qu'à écrire du code et à pousser. Testez votre application manuellement lors de la mise en scène si vous en avez envie, et lorsque vous vous sentez suffisamment en confiance pour la diffuser dans le monde, marquez-la avec le versionnage sémantique!

Versionnage sémantique automatique

Ouais, c’est parfait, mais il manque quelque chose. Je n'aime pas rechercher la dernière version de l'application et la baliser explicitement. Cela prend plusieurs commandes et me distrait pendant quelques secondes.

Ok, mec, arrête! C'est assez. Vous êtes juste en train de sur-concevoir maintenant. Cela fonctionne, c'est génial, ne gâchez pas une bonne chose en exagérant.

D'accord, j'ai une bonne raison de faire ce que je vais faire.

Priez, éclairez-moi.

J'étais comme toi. J'étais content de cette configuration, mais ensuite j'ai raté. git tag répertorie les balises par ordre alphabétique, v0.0.11 est au-dessus de v0.0.2. Une fois, j'ai accidentellement tagué une version et j'ai continué à le faire pendant environ une demi-douzaine de versions jusqu'à ce que je voie mon erreur. C’est là que j’ai décidé d’automatiser cela aussi.

On y va encore une fois

D'accord, donc, heureusement, nous avons la puissance de npm à notre disposition, alors j'ai trouvé un package approprié: Run yarn add --dev standard-version et ajoutez ce qui suit à votre package.json fichier:

'scripts': { 'release': 'standard-version', 'major': 'yarn release --release-as major', 'minor': 'yarn release --release-as minor', 'patch': 'yarn release --release-as patch' },

Maintenant, vous devez faire une dernière chose, configurer Git pour pousser les balises par défaut. Pour le moment, vous devez exécuter git push --tags pousser une balise vers le haut, mais le faire automatiquement régulièrement git push est aussi simple que d'exécuter git config --global push.followTags true.

Pour utiliser votre nouveau pipeline, chaque fois que vous souhaitez créer une version exécutée:

  • yarn patch pour les versions de correctifs
  • yarn minor pour les versions mineures
  • yarn major pour les versions majeures

Si vous n'êtes pas sûr de la signification des mots 'majeur', 'mineur' et 'correctif', lisez-en plus à ce sujet sur le site de versionnage sémantique .

Maintenant que vous avez enfin terminé votre pipeline, récapitulons comment l'utiliser!

  • Écrivez le code.
  • Validez-le et poussez-le pour le tester et le déployer en préparation.
  • Utilisez yarn patch pour marquer une version de correctif.
  • git push pour le pousser en production.

Résumé et étapes supplémentaires

Je viens d’effleurer la surface de ce qui est possible avec les pipelines CI / CD. C'est un exemple assez simpliste. Vous pouvez faire beaucoup plus en remplaçant Heroku par Kubernetes. Si vous décidez d'utiliser GitLab CI, lisez le documentation yaml car vous pouvez faire beaucoup plus en mettant des fichiers en cache entre les déploiements ou en enregistrant des artefacts!

Un autre énorme changement que vous pourriez apporter à ce pipeline est d'introduire des déclencheurs externes pour exécuter le versionnage et la publication sémantiques. Actuellement, ChatOps fait partie de leur forfait payant, et j'espère qu'ils le publieront dans des forfaits gratuits. Mais imaginez pouvoir déclencher l'image suivante via une seule commande Slack!

Schéma d

Finalement, lorsque votre application commence à devenir complexe et nécessite des dépendances au niveau du système, vous devrez peut-être utiliser un conteneur. Lorsque cela se produit, consultez notre guide: Premiers pas avec Docker: simplifier Devops .

Cet exemple d'application est vraiment en ligne et vous pouvez trouver le code source correspondant Ici .

Comprendre les bases

Qu'est-ce qu'un pipeline de développement?

Un pipeline de développement est la chaîne de tâches et de processus que vous suivez dans votre processus de développement.

Qu'est-ce qu'un pipeline de déploiement?

Un pipeline de déploiement est la chaîne de tâches et de processus que vous exécutez dans votre processus de déploiement.

Que signifie CI / CD?

CI / CD est l'abréviation de l'intégration continue (intégrant votre code en un seul endroit en continu), de la livraison continue (création de votre produit prêt à être expédié en continu) et du déploiement continu (déploiement de votre produit en production en continu).

Qu'est-ce que GitOps?

GitOps est un DevOps entièrement géré via Git.

Principes de conception Mobile UX

Conception Mobile

Principes de conception Mobile UX
UI vs UX - Explorez les principales différences (infographie)

UI vs UX - Explorez les principales différences (infographie)

Conception De L'interface Utilisateur

Articles Populaires
Ingénieur Senior Ruby on Rails
Ingénieur Senior Ruby on Rails
Repenser l'interface utilisateur de la plate-forme TV
Repenser l'interface utilisateur de la plate-forme TV
Soutenir l'offre technologique grâce à l'éducation STEM
Soutenir l'offre technologique grâce à l'éducation STEM
UX personnalisé et puissance du design et de l'émotion
UX personnalisé et puissance du design et de l'émotion
Explication du flux Git amélioré
Explication du flux Git amélioré
 
Un guide sur les moteurs Rails dans la nature: Exemples concrets de moteurs Rails en action
Un guide sur les moteurs Rails dans la nature: Exemples concrets de moteurs Rails en action
Conception d'une VUI - Interface utilisateur vocale
Conception d'une VUI - Interface utilisateur vocale
Huit raisons pour lesquelles Microsoft Stack est toujours un choix viable
Huit raisons pour lesquelles Microsoft Stack est toujours un choix viable
Tirer le meilleur parti des actions - Leçons d'un ancien analyste de recherche
Tirer le meilleur parti des actions - Leçons d'un ancien analyste de recherche
Addiction au rachat d'actions: études de cas de succès
Addiction au rachat d'actions: études de cas de succès
Articles Populaires
  • consultant vs calculateur de salaire à temps plein
  • c corp contre s corp
  • tutoriel d'application Web node js
  • kubernetes est conçu pour fonctionner avec n'importe quel produit de conteneurisation
  • comment rédiger une spécification de conception
Catégories
  • La Technologie
  • Personnes Et Équipes
  • Gestion De Projet
  • Équipes Distribuées
  • © 2022 | Tous Les Droits Sont Réservés

    portaldacalheta.pt