Inleiding: Het begrijpen van het totale plaatje is belangrijk

Hallo! In deel 1 hebben we gekeken naar de redenen en de benodigde voorbereiding om een automatisch deploysysteem te bouwen met GitHub Webhook. In dit tweede deel gaan we, voordat we echt aan de code-implementatie beginnen, de totale architectuur en processen van ons automatische deploysysteem ontwerpen.

Iedereen heeft mogelijk een iets andere ontwikkelomgeving. Sommigen gebruiken een Raspberry Pi, terwijl anderen misschien een cloud VPS gebruiken, en de structuur van het project dat we willen deployen kan ook verschillen. Om in een dergelijke diverse omgeving een flexibel systeem op te zetten en zelf problemen op te lossen als ze zich voordoen, is het belangrijker om de algehele flow en context te begrijpen dan de detailcode.

Laten we in dit deel een duidelijk beeld vormen van het grote geheel van het systeem dat we gaan bouwen en de rol van elke component verduidelijken.

Automatisch deploysysteem flowdiagram

Automatisch deploy workflow: Een overzicht van de gehele flow

Ons automatische deploysysteem werkt via de volgende reeks stappen.

  1. Codewijzigingen en Git push vanaf de lokale werkmachine: De ontwikkelaar wijzigt de code in de lokale omgeving en pusht de wijzigingen naar een specifieke branch van de GitHub repository (bijvoorbeeld main of develop).

  2. Webhook-event in de GitHub-repository: De GitHub-repository stuurt een HTTP POST-verzoek naar de vooraf ingestelde URL via de webhook wanneer een push event wordt gedetecteerd.

  3. Verzoek doorgeven aan de webhook-endpoint van de stagingserver: Het webhook-verzoek dat door GitHub wordt verzonden, wijst naar een specifieke URL van onze stagingserver (bijvoorbeeld https://deployer.example.com/webhook). Dit verzoek bevat verschillende payloads zoals informatie over de gepushte commits en gewijzigde bestanden.

  4. Webhook ontvangen door FastAPI-service op de stagingserver: Onze FastAPI-applicatie die draait op de stagingserver ontvangt dit webhook verzoek. Hier begint de rol van de FastAPI-service.

Belangrijke rollen van de FastAPI Webhook-service

De webhook-service die we met FastAPI implementeren, zal verder gaan dan alleen verzoeken ontvangen; het zal ook de volgende belangrijke rollen vervullen.

Webhook ontvangst en initiële verwerking

De FastAPI-applicatie biedt een endpoint (bijvoorbeeld /webhook) dat HTTP POST-verzoeken van GitHub kan ontvangen. Dit endpoint parseert de HTTP-headers en body (payload) van het verzoek om de nodige informatie te extraheren.

Secret-validatie

Beveiliging is van het grootste belang in een automatisch deploysysteem. GitHub Webhook biedt een Secret waarde via de header X-Hub-Signature-256 voor het verifiëren van de integriteit van het verzoek. Onze FastAPI-service moet logica bevatten die deze Secret waarde gebruikt om te verifiëren of het verzoek van GitHub komt en niet onderweg is gemanipuleerd. Als deze verificatie faalt, wordt het verzoek onmiddellijk geweigerd om ongeautoriseerde toegang te blokkeren.

Onmiddellijke respons en achtergrondtaken

GitHub Webhook beschouwt een verzoek als een timeout als er binnen een bepaalde tijd (standaard 10 seconden) geen respons wordt ontvangen, en zal dan het opnieuw proberen of het als mislukt registreren. Echter, het werkelijke deployproces (Git Pull, Docker-build/herstart, etc.) kan langer duren.

Daarom zal onze FastAPI-service zodra het webhook-verzoek wordt ontvangen, Secret validatie en andere initiële verwerkingen afronden en Het eigenlijke deploylogica zal worden uitgevoerd asynchroon op de achtergrond met behulp van de BackgroundTasks functie van FastAPI. Op deze manier kunnen we het timeoutprobleem van GitHub omzeilen en betrouwbaar het deployproces uitvoeren.

Gedetailleerde logica van de deployhandler

De deployhandler die op de achtergrond draait, zal de volgende essentiële taken uitvoeren.

M ulti-projectbeheer: repository pad lezen

We zullen het zo ontwerpen dat we met één FastAPI webhook-service automatische deploys voor meerdere GitHub repositories (projecten) kunnen beheren. Hiervoor beheren we de repositorypaden van elk project en hun lokale paden op de server door deze te koppelen via omgevingsvariabelen of configuratiebestanden. We bevestigen vanuit de webhook-payload van welke repository het evenement komt, en verplaatsen ons naar het pad van het project om de deploytaken uit te voeren.

Project-specifieke aangepaste instellingen: .env bestand parseren (optioneel)

Elk project kan unieke omgevingsvariabelen of instellingen hebben die nodig zijn voor build of deploy. Bijvoorbeeld, verschillende Docker image tags, build opties en commando’s voor het herstarten van services kunnen variëren. Om dit efficiënt te beheren, implementeren we een parser in het .env bestand van het lokale repositorypad van elk project, zodat we de benodigde waarden kunnen gebruiken in de deploylogica. Dit helpt ons om flexibele en op maat gemaakte deploylogica te implementeren.

Code-update: git pull uitvoeren

De meest basale stap. Met behulp van de subprocess module kan de git pull origin <branch_name> commando worden uitgevoerd in het lokale repository om de nieuwste code van de GitHub repository te verkrijgen.

Beslissen over het opnieuw bouwen van de Docker-image: gebruik maken van git diff

In het geval van Docker-gebaseerde projecten is het vaak voldoende om alleen docker compose up -d uit te voeren wanneer er alleen codewijzigingen zijn. Maar als er bestanden gewijzigd zijn die de Docker-image-build beïnvloeden, zoals Dockerfile of requirements.txt (in het geval van Python-projecten), moet de image opnieuw worden gebouwd.

We gebruiken het git diff commando om te bepalen of er wijzigingen zijn in de Dockerfile of andere build-gerelateerde bestanden tussen de recent gepushte commit en de voorafgaande commit. Als er wijzigingen zijn gedetecteerd, wordt docker compose up -d --build uitgevoerd; als dit niet het geval is, wordt alleen docker compose up -d uitgevoerd om onnodige image-rebuilds te voorkomen en de deploytijd te verkorten.

Docker Compose uitvoeren: gebruik maken van de subprocess module

Nadat we de laatste code hebben opgehaald en hebben bepaald of de image opnieuw opgebouwd moet worden, gebruiken we de subprocess module om docker compose up -d of docker compose up -d --build uit te voeren om de Docker-containers bij te werken en de service opnieuw te starten.

Logging: Registratie van alle processen

Het hele deployproces (ontvangst van de webhook, validatie, resultaten van Git Pull, logs van Docker build/herstart, etc.) moet gedetailleerd worden vastgelegd. Dit is essentieel voor het identificeren van oorzaken en het debuggen bij het optreden van problemen. We zullen de Python logging module gebruiken om logs in een bestand te schrijven.

Deploy- en operationele strategie van de FastAPI-service

De FastAPI webhook-service die we implementeren, moet continu en betrouwbaar draaien op de staging server.

Belang van het gebruik van Systemd Service

In plaats van de FastAPI-applicatie als een Docker-container op te zetten, aanbevelen wij ten zeerste om deze als een Systemd Service te draaien. De redenen hiervoor zijn als volgt.

  • Hulpmiddelen efficiëntie: De kans is groot dat de staging server al tools voor deploy, zoals git, docker, docker compose, heeft geïnstalleerd. Het maken van de FastAPI webhook-service als een Docker-container en het installeren van git of docker binnen die container om de docker daemon van het systeem te besturen, verhoogt onnodig de grootte van de container en kan leiden tot complexe configuraties en beveiligingsproblemen zoals docker-in-docker of docker-out-of-docker.

  • Eenvoudig beheer: Systemd is de standaard voor het beheren van services in Linux-systemen. Door de FastAPI-app als Systemd-service te registreren, kan deze automatisch starten bij het opstarten van de server, kan de status van de service gecontroleerd worden en kan deze eenvoudig worden herstart of gestopt, wat zorgt voor een integrale en eenvoudige methode van beheer op OS-niveau.

  • Systeembronnen benutten: Door de FastAPI-app via Systemd te draaien, kan de app direct de git en docker commando’s van het systeem aanroepen om de deploytaken uit te voeren, waardoor de bestaande systeembronnen op de meest efficiënte manier worden benut.

In het volgende deel zullen we gedetailleerd uitleggen hoe we de FastAPI-applicatie registreren als een Systemd-service en deze beheren.

Gebruik van Nginx/Apache2 voor reverse proxy en HTTPS

Zoals benadrukt in deel 1, is het zeer riskant om de FastAPI-applicatie direct aan het internet bloot te stellen. Daarom zullen we een webserver zoals Nginx of Apache2 gebruiken als reverse proxy om de webhook-verzoeken veilig naar de FastAPI-applicatie door te sturen.

Bovendien beveelt GitHub Webhook sterk aan om HTTPS-communicatie te gebruiken, dus we moeten een specifiek subdomein zoals deployer.example.com voorbereiden en een HTTPS-certificaat aanvragen via Let’s Encrypt en dit toepassen op de webserver. Hierdoor kunnen alle communicatie van buitenaf worden versleuteld, wat de beveiliging versterkt.

Monitoring en debugging

We zullen de volgende twee methoden gebruiken om ervoor te zorgen dat het automatische deploysysteem goed functioneert en om de redenen voor problemen te identificeren als die zich voordoen.

  • Logbestanden van de FastAPI-service: De FastAPI-service die we implementeren zal alle stappen van het deployproces in zijn eigen logbestanden registreren. Door deze bestanden te controleren, kunnen we de succes van de deploy en eventuele foutmeldingen bepalen.

  • Systemd journalctl: Aangezien we de FastAPI-service met Systemd beheren, kunnen we met het commando journalctl -u your-fastapi-service.service de standaarduitvoer en errorlogs van de service in real-time controleren en analyseren.

Afsluitend: Vooruitblik op het volgende deel

In dit tweede deel hebben we de algehele architectuur van het automatisch deploysysteem met GitHub Webhook, de kernrollen van de FastAPI-service, en de deploy- en operationele strategie uitvoerig besproken. Hopelijk heb je nu een duidelijk beeld van het grote geheel.

In het volgende derde deel zullen we, op basis van de ontwerpen die we vandaag hebben gemaakt, de daadwerkelijke code voor de FastAPI-webhook-service schrijven, de GitHub Webhook instellen en het registreren als een Systemd-service. Blijf kijken!


De serie rond het opbouwen van mijn eigen automatische deploysysteem met GitHub Webhook

Deel 1 - Waarom zelf implementeren?