Zephyrnet-logo

Automatisering van elk aspect van uw Python-project

Datum:

Automatisering van elk aspect van uw Python-project

Elk Python-project kan profiteren van automatisering met Makefile, geoptimaliseerde Docker-images, goed geconfigureerde CI / CD, Code Quality Tools en meer ...


By Martin Heinz, DevOps Engineer bij IBM

Afbeelding voor bericht

Elk project - of u nu werkt aan een webapp, wat datawetenschap of AI - kan profiteren van goed geconfigureerde CI / CD-, Docker-images die zowel debugbaar zijn tijdens de ontwikkeling als geoptimaliseerd zijn voor een productieomgeving of een paar extra tools voor codekwaliteit, zoals CodeKlimaat or SonarCloud. Dit zijn allemaal dingen die we in dit artikel zullen bespreken en we zullen zien hoe deze kunnen worden toegevoegd aan uw Python projecten!

Dit is een vervolg op het vorige artikel over het maken van "Ultieme" Python Project Setup, dus misschien wil je dat eens bekijken voordat je deze leest.

TL; DR: Hier is mijn repository met volledige broncode en documenten: https://github.com/MartinHeinz/python-project-blueprint

Debugbare Docker-containers voor ontwikkeling

 
Sommige mensen houden niet van havenarbeider omdat containers moeilijk te debuggen zijn of omdat het lang duurt om hun images te bouwen. Dus laten we hier beginnen door images te bouwen die ideaal zijn voor ontwikkeling - snel te bouwen en gemakkelijk te debuggen.

Om de afbeelding gemakkelijk te debuggen, hebben we een basisimage nodig met allen de tools die we ooit nodig zouden kunnen hebben bij het debuggen, zoals bash, vim, netcat, wget, cat, find, grep enz. python:3.8.1-buster lijkt een ideale kandidaat voor de taak. Het bevat standaard veel tools en we kunnen vrij gemakkelijk alles installeren wat ontbreekt. Deze basisafbeelding is mooi dik, maar dat maakt hier niet uit, want het wordt alleen voor ontwikkeling gebruikt. Zoals je waarschijnlijk al hebt opgemerkt, heb ik een heel specifieke afbeelding gekozen - beide versies van Python net zoals Debian - dat is opzettelijk, daar we de kans op willen verkleinen "Breuk" veroorzaakt door nieuwere, mogelijk incompatibele versie van beide Python or Debian.

Als alternatief zou je kunnen gebruiken Alpine gebaseerd beeld. Dat kan echter enkele problemen veroorzaken, zoals het gebruikt musl libc in plaats van glibc welke Python vertrouwt op. Houd daar dus rekening mee als u besluit deze route te kiezen.

Wat betreft de snelheid van builds, zullen we meertraps builds gebruiken om ons in staat te stellen zoveel mogelijk lagen te cachen. Op deze manier kunnen we het downloaden van afhankelijkheden en tools zoals gcc evenals alle bibliotheken die vereist zijn voor onze applicatie (van requirements.txt).

Om de zaken verder te versnellen, zullen we een aangepaste basisafbeelding maken van eerder genoemd python:3.8.1-buster, dat alle tools bevat die we nodig hebben, aangezien we de stappen die nodig zijn voor het downloaden en installeren van deze tools niet in de cache kunnen opslaan in de uiteindelijke runner-afbeelding.

Genoeg gepraat, laten we eens kijken Dockerfile:

Hierboven kun je zien dat we door 3 tussenliggende afbeeldingen gaan voordat we de finale maken loper beeld. De eerste wordt genoemd builder. Het downloadt alle benodigde bibliotheken die nodig zijn om onze uiteindelijke applicatie te bouwen, inclusief gcc en Python virtuele omgeving. Na installatie creëert het ook een daadwerkelijke virtuele omgeving die vervolgens wordt gebruikt door de volgende afbeeldingen.

Vervolgens komt de builder-venv afbeelding die de lijst met onze afhankelijkheden kopieert (requirements.txt) in de afbeelding en installeert deze vervolgens. Deze tussenimage is nodig voor caching, omdat we alleen bibliotheken willen installeren als requirements.txt wijzigingen, anders gebruiken we alleen cache.

Voordat we onze definitieve afbeelding maken, willen we eerst tests uitvoeren met onze applicatie. Dat is wat er gebeurt in de tester beeld. We kopiëren onze broncode naar een afbeelding en voeren tests uit. Als ze slagen, gaan we verder met de runner.

Voor de afbeelding van de runner gebruiken we een aangepaste afbeelding die enkele extra's bevat, zoals vim or netcat die niet aanwezig zijn in normaal Debian beeld. Je vindt deze afbeelding op Docker-hub hier en je kunt ook het heel simpele Dockerfile in base.Dockerfile hier. Dus wat we doen in deze laatste afbeelding - eerst kopiëren we de virtuele omgeving die al onze geïnstalleerde afhankelijkheden bevat tester afbeelding, vervolgens kopiëren we onze geteste applicatie. Nu we alle bronnen in de afbeelding hebben, gaan we naar de map waar de toepassing is en vervolgens instellen ENTRYPOINT zodat het onze applicatie uitvoert wanneer de afbeelding wordt gestart. Om veiligheidsredenen hebben we ook ingesteld USER naar 1001, aangezien best practices ons vertellen dat u nooit containers onder root gebruiker. Laatste 2 regels set labels van de afbeelding. Deze worden vervangen / gevuld wanneer build wordt uitgevoerd met make target dat we later zullen zien.

Geoptimaliseerde Docker-containers voor productie

 
Als het gaat om afbeeldingen van productiekwaliteit, willen we ervoor zorgen dat ze klein, veilig en snel zijn. Mijn persoonlijke favoriet voor deze taak is Python afbeelding van Distroloos project. Wat is Distroloos, maar?

Laat ik het zo zeggen: in een ideale wereld zou iedereen zijn imago opbouwen met FROM scratch als hun basisafbeelding (dat wil zeggen - lege afbeelding). Dat is echter niet wat de meesten van ons zouden willen doen, aangezien het vereist dat u uw binaire bestanden statisch koppelt, enz. Dat is waar Distroloos komt in het spel - het is FROM scratch For allemaal.

Oké, om nu echt te beschrijven wat Distroloos is. Het is een reeks afbeeldingen gemaakt door Kopen Google Reviews die het absolute minimum bevatten dat nodig is voor uw app, wat betekent dat er geen shells, pakketbeheerders of andere tools zijn die de afbeelding kunnen opzwellen en signaalruis veroorzaken voor beveiligingsscanners (zoals CVE) waardoor het moeilijker wordt om naleving vast te stellen.

Nu we weten waar we mee te maken hebben, laten we eens kijken naar het productie Dockerfile... Nou eigenlijk gaan we hier niet zoveel veranderen, het zijn maar 2 regels:

Het enige dat we moesten veranderen, zijn onze basisafbeeldingen voor het bouwen en uitvoeren van de applicatie! Maar het verschil is behoorlijk groot - ons ontwikkelingsbeeld was 1.03 GB en deze is slechts 103 MB, dat is heel een verschil! Ik weet het, ik kan je al horen - "Maar Alpine kan nog kleiner zijn!" - Ja, dat klopt, maar de maat doet er niet toe zoveel. U zult de afbeeldingsgrootte alleen opmerken wanneer u deze download / upload, wat niet zo vaak is. Wanneer de afbeelding wordt uitgevoerd, doet de grootte er helemaal niet toe. Wat belangrijker is dan de grootte, is de veiligheid en in dat opzicht Distroloos is zeker superieur, zoals Alpine (wat een geweldig alternatief is) heeft veel extra pakketten die het aanvalsoppervlak vergroten.

Het laatste dat het vermelden waard is als we erover praten Distroloos zijn debug afbeeldingen. Gezien dat Distroloos bevat niet elke shell (zelfs niet sh), wordt het behoorlijk lastig als je moet debuggen en rondneuzen. Daarvoor zijn er debug versies van alle Distroloos afbeeldingen. Dus wanneer poep de fan raakt, kun je je productieafbeelding bouwen met debug tag en implementeer het naast je normale image, voer het uit en doe - bijvoorbeeld - threaddump. U kunt de foutopsporingsversie van python3 afbeelding zoals zo:

Eén commando voor alles

 
Met alle Dockerfiles klaar, laten we het in godsnaam automatiseren met Makefile! Het eerste dat we willen doen, is onze applicatie bouwen havenarbeider. Dus om een ​​dev-imago op te bouwen, kunnen we doen make build-dev die het volgende doel uitvoert:

Dit doel bouwt de afbeelding op door eerst labels onderaan te vervangen dev.Dockerfile met afbeeldingsnaam en tag die wordt gemaakt door uit te voeren git describe en dan rennen docker build.

Next up - bouwen voor productie met make build-prod VERSION=1.0.0:

Deze lijkt erg op het vorige doel, maar in plaats van te gebruiken git tag als versie, gebruiken we versie die als argument is doorgegeven, in het bovenstaande voorbeeld 1.0.0.

Als je alles naar binnen voert havenarbeider, dan zul je het op een gegeven moment ook moeten debuggen havenarbeider, daarvoor is er het volgende doel:

Uit het bovenstaande kunnen we zien dat het toegangspunt wordt overschreven door bash en container commando wordt overschreven door argument. Op deze manier kunnen we ofwel gewoon de container invoeren en rondneuzen of een eenmalige opdracht uitvoeren, zoals in het bovenstaande voorbeeld.

Als we klaar zijn met coderen en de afbeelding willen pushen naar havenarbeider registry, dan kunnen we make push VERSION=0.0.2. Laten we eens kijken wat het doel doet:

Het loopt eerst build-prod doel waar we eerder naar keken en dan gewoon rent docker push. Dit veronderstelt dat u bent ingelogd havenarbeider registry, dus voordat u dit uitvoert, moet u docker login.

Het laatste doel is om op te ruimen havenarbeider artefacten. Het gebruikt name label dat is vervangen door Dockerfiles om artefacten te filteren en te vinden die moeten worden verwijderd:

Hiervoor vindt u de volledige codelijst Makefile in mijn repository hier: https://github.com/MartinHeinz/python-project-blueprint/blob/master/Makefile

CI / CD met GitHub-acties

 
Laten we nu al deze handige dingen gebruiken make doelen om onze CI / CD op te zetten. We zullen gebruiken GitHub-acties en GitHub-pakketregister om onze pijpleidingen (banen) aan te leggen en om onze afbeeldingen op te slaan. Dus, wat zijn dat precies?

  • GitHub-acties zijn banen / pijpleidingen waarmee u uw ontwikkelingsworkflows kunt automatiseren. U kunt ze gebruiken om individuele taken te maken en ze vervolgens te combineren in aangepaste workflows, die vervolgens worden uitgevoerd - bijvoorbeeld - bij elke push naar de repository of wanneer de release wordt gemaakt.
  • GitHub-pakketregister is een pakket-hostingservice, volledig geïntegreerd met GitHub. Hiermee kunt u verschillende soorten pakketten opslaan, bijvoorbeeld Ruby edelstenen or NPM pakketjes. We zullen het gebruiken om onze havenarbeider afbeeldingen. Als u niet bekend bent met GitHub-pakketregister en wil je er meer informatie over, dan kun je mijn blogpost bekijken hier.

Nu te gebruiken GitHub-acties, we moeten creëren workflows die worden uitgevoerd op basis van triggers (bijv. push to repository) die we kiezen. Deze workflows zijn Yamla bestanden die in .github/workflows directory in onze repository:

Daar zullen we 2 bestanden maken build-test.yml en push.yml. Ten eerste build-test.yml bevat 2 taken die bij elke push naar de repository worden geactiveerd, laten we deze eens bekijken:

Eerste baan gebeld build verifieert dat onze applicatie kan worden gebouwd door onze make build-dev doelwit. Voordat het het echter uitvoert, controleert het eerst onze repository door de actie genaamd checkout die is gepubliceerd op GitHub.

De tweede baan is iets ingewikkelder. Het voert tests uit tegen onze applicatie, evenals 3 linters (code kwaliteitscontrole). Hetzelfde als voor de vorige baan, we gebruiken checkout@v1 actie om onze broncode te krijgen. Daarna voeren we een andere gepubliceerde actie uit, genaamd setup-python@v1 die een python-omgeving voor ons instelt (u kunt er details over vinden hier). Nu we een python-omgeving hebben, hebben we ook toepassingsafhankelijkheden nodig van requirements.txt waarmee we installeren pip. Op dit punt kunnen we doorgaan met rennen make test target, wat ons triggert Pytest suite. Als onze testsuite slaagt, gaan we door met het installeren van eerder genoemde linters - pylint, flake8 en bandiet. Eindelijk rennen we make lint target, dat elk van deze linters activeert.

Dat is alles voor het bouwen / testen, maar hoe zit het met het pushen? Laten we dat ook bespreken:

De eerste 4 regels bepalen wanneer we willen dat deze taak wordt geactiveerd. We specificeren dat deze taak alleen mag starten als tags naar de repository worden gepusht (* specificeert patroon van tagnaam - in dit geval - iets). Dit is zodat we onze Docker-image niet naar GitHub-pakketregister elke keer dat we naar de repository pushen, maar alleen als we een tag pushen die een nieuwe versie van onze applicatie specificeert.

Nu voor de body van deze taak - het begint met het uitchecken van de broncode en het instellen van de omgevingsvariabele van RELEASE_VERSION naar git tag die we hebben gepusht. Dit wordt gedaan met behulp van ingebouwde ::setenv kenmerk van GitHub-acties (meer informatie hier). Vervolgens logt het in op het Docker-register met REGISTRY_TOKEN geheim opgeslagen in repository en login van gebruiker die de workflow heeft gestart ( github.actor). Eindelijk, op de laatste regel loopt het push target, dat een prodimage bouwt en deze in het register pusht met eerder gepushte git tag als afbeeldingstag.

U kunt de volledige codelijst bekijken in de bestanden in mijn repository hier.

Codekwaliteitscontroles met CodeClimate

 
Last but not least zullen we ook codekwaliteitscontroles toevoegen met behulp van CodeKlimaat en SonarCloud. Deze worden samen met ons geactiveerd proef baan hierboven weergegeven. Dus laten we er een paar regels aan toevoegen:

We beginnen met CodeKlimaat waarvoor we eerst exporteren GIT_BRANCH variabele die we ophalen met GITHUB_REF omgevingsvariabele. Vervolgens downloaden we CodeKlimaat test reporter en maak het uitvoerbaar. Vervolgens gebruiken we het om het dekkingsrapport op te maken dat is gegenereerd door onze testsuite, en op de laatste regel waarnaar we het sturen CodeKlimaat met testverslaggever-ID die we opslaan in repositorygeheimen.

Wat de SonarCloud, we moeten creëren sonar-project.properties bestand in onze repository dat er zo uitziet (waarden voor dit bestand zijn te vinden op SonarCloud dashboard rechtsonder):

Anders dan dat, kunnen we gewoon gebruik maken van bestaande sonarcloud-github-action, die al het werk voor ons doet. Het enige wat we hoeven te doen is 2 tokens leveren - GitHub een die standaard in de repository staat en SonarCloud token waarvan we kunnen krijgen SonarCloud website.

Opmerking: stappen voor het ophalen en instellen van alle eerder genoemde tokens en geheimen staan ​​in de README-opslagplaats hier.

Conclusie

 
Dat is het! Met tools, configuraties en code van boven bent u klaar om alle aspecten van uw volgende te bouwen en te automatiseren Python project! Als je meer informatie nodig hebt over onderwerpen die in dit artikel worden getoond / besproken, ga je gang en bekijk je de documenten en code in mijn repository hier: https://github.com/MartinHeinz/python-project-blueprint en als je suggesties / problemen hebt, dien het probleem dan in de repository in of geef het gewoon een ster als je dit kleine project van mij leuk vindt. 🙂

 
Resources

 
Bio: Martin Heinz is een DevOps Engineer bij IBM. Als softwareontwikkelaar is Martin gepassioneerd door computerbeveiliging, privacy en cryptografie, gefocust op cloud- en serverloos computergebruik en staat hij altijd klaar om een ​​nieuwe uitdaging aan te gaan.

ORIGINELE. Met toestemming opnieuw gepost.

Zie ook:

Bron: https://www.kdnuggets.com/2020/09/automating-every-aspect-python-project.html

spot_img

Laatste intelligentie

spot_img

Chat met ons

Hallo daar! Hoe kan ik u helpen?