1. Inleiding: De deployment-logica op de achtergrond uitvoeren
Hallo! In deel 3 hebben we de staging server omgeving ingesteld en samen de basisstructuur van de FastAPI webhook server gemaakt, die GitHub Webhook verzoeken ontvangt en de Secret verifieert. Tijdens dit proces hebben we al de handle_deploy
en should_rebuild
functies in het main.py
bestand opgenomen, waardoor we een voorproefje kregen van de kernideeën van de daadwerkelijke deployment logica.
In dit vierde deel zullen we eens kijken naar de werking van de deployhandler logica die kort werd besproken in deel 3, en we zullen ons richten op de registratie van deze FastAPI webhook server als een Systemd-service, zodat deze automatisch wordt uitgevoerd en betrouwbaar kan draaien, zelfs na een serverherstart. Jullie automatiseringssysteem is klaar om nog robuuster te worden!
Voor degenen die de vorige artikelen hebben gemist, raad ik aan om die eerst te bekijken.
② Algemeen architectuur en procesontwerp
③ Staging server omgeving inrichten en basis van FastAPI webhook server opzetten
2. Kijken naar de deployhandler (handle_deploy
) logica
De handle_deploy
functie in het main.py
dat we in deel 3 hebben geschreven, is verantwoordelijk voor de daadwerkelijke deployment taak die op de achtergrond wordt uitgevoerd wanneer er een GitHub webhook verzoek binnenkomt. Deze functie vervult de volgende kernrollen.
Ik raad aan om de voorbeeldcode uit deel 3 erbij te pakken terwijl je de onderstaande gids bekijkt.
2.1. Meerdere projecten beheren en omgevingsvariabelen instellen
Als je meerdere GitHub-repositories (projecten) met één webhook server wilt beheren, moet je aangeven waar elke repository binnen de server is geplaatst. De handle_deploy
functie gebruikt hiervoor de repo_paths
dictionary, en deze waarden zijn ontworpen om gelezen te worden vanuit de omgevingsvariabelen van de server.
In de voorbeeldcode worden omgevingsvariabelen zoals SAMPLE_PROJECT_1_PATH
vermeld. Je moet de werkelijke paden van elk project in de .env
file van de staging server instellen (dit bestand moet zich in dezelfde directory bevinden als main.py
) of in het systemd
service bestand zoals hieronder.
Codefragment
# ~/projects/webhook_server/.env
# GitHub Webhook Secret (instelling in deel 3)
GITHUB_WEBHOOK_SECRET="your_github_webhook_secret_value"
# Werkelijke paden van de projecten op de server
SAMPLE_PROJECT_1_PATH="/var/www/my-project1"
SAMPLE_PROJECT_2_PATH="/home/user/another-project"
SAMPLE_PROJECT_3_PATH="/opt/third-project"
De handle_deploy
functie zoekt naar het pad van het betreffende project in de repo_paths
dictionary met de naam van de repository die via de webhook payload is ontvangen. Als er geen gemapt pad is, laat het een Unknown repository
waarschuwing achter en stopt het.
Bovendien leest het ook extra configuraties zoals DEBUG
of COLOR
uit de .env
bestanden voor elk project (bijvoorbeeld /var/www/my-project1/.env
) en maakt gebruik van die waarden voor het kiezen van het Docker Compose bestand (docker-compose.dev.yml
of docker-compose.prod.yml
) of voor het instellen van de naam van het Docker-project. Dit maakt het mogelijk om de deploymethoden aan te passen aan de kenmerken van het project.
2.2. Bepalen of Docker afbeeldingen opnieuw gebouwd moeten worden (should_rebuild
)
Het elke keer opnieuw bouwen van Docker afbeeldingen bij een deployment is tijdrovend en inefficiënt. De should_rebuild
functie gebruikt de diff
opdracht van Git om te detecteren of er wijzigingen zijn aangebracht in de Dockerfile
, requirements.txt
of .env
bestanden, die van invloed zijn op de opbouw van de Docker afbeelding.
Deze functie checkt de wijzigingen ten opzichte van de vorige commit via het commando git diff --name-only HEAD~1
, en als de lijst met gewijzigde bestanden een van de vooraf gedefinieerde trigger_files
bevat (bijvoorbeeld Dockerfile
, requirements.txt
, .env
, REBUILD_TRIGGER
), dan retourneert het True
om de afbeelding opnieuw te bouwen.
Bijzonder is dat het REBUILD_TRIGGER
bestand, zelfs als het leeg is, nog steeds een nuttige truc is om de bouw geforceerd uit te voeren. Dit bestand kan handmatig op de server worden aangemaakt en kan worden gebruikt wanneer er een nieuwe image build vereist is om redenen anders dan git pull
. Als de should_rebuild
functie dit bestand detecteert, verwijdert het dit automatisch om ervoor te zorgen dat er tijdens de volgende deployment geen onnodige nieuwe build plaatsvindt.
2.3. Uitvoeren van Git en Docker Compose commando's
De handle_deploy
functie gebruikt de subprocess
module van Python om de git
en docker compose
commando's op de server uit te voeren.
-
subprocess.run(["git", "-C", repo_path, "pull"], check=True)
: Decheck=True
optie zorgt ervoor dat als er een fout optreedt tijdens het uitvoeren van het Git commando, desubprocess.CalledProcessError
wordt opgegooid, zodat de Python code dit kan detecteren en de fout kan registreren. De-C
optie voert de Git opdracht uit in de opgegeven directory. -
subprocess.run(["docker", "compose", "-p", project_name, "-f", compose_file, "up", "-d", "--build"], check=True)
: Afhankelijk van de uitkomst van deshould_rebuild
functie kan dit commando alleenup -d
uitvoeren of de--build
optie toevoegen voor de constructie van de afbeelding. De-p
optie stelt de naam van het Docker Compose-project in om te voorkomen dat meerdere projecten met elkaar in conflict komen.
Met deze logica kan een enkel webhook verzoek de nieuwste code van een project ophalen en alleen bij nodig de afbeelding opnieuw bouwen, zodat de service efficiënt kan worden bijgewerkt.
3. FastAPI webhook server beheer als een Systemd service
Tot nu toe hebben we de webhook server handmatig uitgevoerd met het commando uvicorn main:app --reload
. Maar als de server opnieuw opstart, verdwijnt dit proces en als de terminalsessie verbroken wordt, stopt de service. Om dit te voorkomen en voor betrouwbare werking, moeten we de FastAPI webhook server registreren als een Systemd service.
3.1. Waarom Systemd gebruiken?
-
Automatische start: De webhook service start automatisch bij een serverherstart.
-
Voortdurende uitvoering: Het draait altijd op de achtergrond, onafhankelijk van de terminalsessies.
-
Eenvoudig beheer: Met de
systemctl
opdracht kun je de service gemakkelijk starten, stoppen, opnieuw starten, de status controleren, en logs bekijken. -
Hulpmiddel voor efficiëntie: Zoals uitgelegd in deel 2, is de webhook server zelf een lichte Python-app die via Systemd wordt uitgevoerd, terwijl zware tools zoals Git en Docker vanuit het systeem gebruikmaken om onnodige Docker-in-Docker configuraties of een toename in container-grootte te vermijden.
3.2. Schrijven van een Systemd service bestand (*.service
)
Systemd services worden gedefinieerd door een .service
bestand. Dit bestand moet worden geplaatst in de /etc/systemd/system/
directory. Laten we een bestand maken met de naam github-webhook-deployer.service
. Ik heb gekozen voor een lange naam om het gemakkelijk te maken om uit te leggen, maar jullie kunnen een naam kiezen die korter en duidelijker is.
# Bestandscreatie (sudo rechten vereist)
sudo nano /etc/systemd/system/github-webhook-deployer.service
Inhoud van het bestand:
# /etc/systemd/system/github-webhook-deployer.service
[Unit]
Description=GitHub Webhook Deployer Service
After=network.target # Start deze service na activatie van het netwerk.
[Service]
User=your_username # Het gebruikersaccount dat deze service uitvoert (bijv. ubuntu, your_user)
Group=your_username # De groep waaronder deze service draait (bijv. ubuntu, your_user)
WorkingDirectory=/home/your_username/projects/webhook_server # Directory waar de FastAPI app zich bevindt.
# Omgevingsvariabelen instellen:
# 1. Omdat de FastAPI app de .env file zelf laadt, is het niet noodzakelijk om variabelen zoals GITHUB_WEBHOOK_SECRET via de EnvironmentFile in te laden, maar als je systemd-niveau consistentie wil hebben,
# kun je het pad voor EnvironmentFile behouden.
# EnvironmentFile=/home/your_username/projects/webhook_server/.env
# 2. Om de systeemcommando's zoals git, docker, docker compose vanuit subprocess.run() te kunnen aanroepen, moet je de paden naar deze commando's expliciet toevoegen aan
# de PATH omgevingsvariabele.
# Het onderstaande voorbeeld bevat de typische Linux systeem paden en de bin map van een Python virtuele omgeving.
# Pas 'your_username' en 'venv' aan op basis van de echte omgeving.
# Controleer de juiste PATH in de .bashrc file van de server of met het commando 'echo $PATH' en voeg de benodigde paden toe.
Environment="PATH=/home/your_username/projects/webhook_server/venv/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
ExecStart=/home/your_username/projects/webhook_server/venv/bin/uvicorn main:app --host 0.0.0.0 --port 8000 # Gebruik het pad voor uvicorn in de virtuele omgeving.
Restart=always # Herstart de service altijd als deze stopt.
StandardOutput=journal # Standaarduitvoer naar de Systemd journal.
StandardError=journal # Standaardfout naar de Systemd journal.
[Install]
WantedBy=multi-user.target # Zorg ervoor dat de service start in de multi-user modus (de gebruikelijke serverbootstatus).
Uitleg:
-
[Unit]
sectie: Bevat algemene informatie over de service (beschrijving, afhankelijkheden).After=network.target
zorgt ervoor dat deze service start nadat de netwerksdienst is opgestart. -
[Service]
sectie: Definieert hoe de service zal worden uitgevoerd.-
User
,Group
: De gebruiker en groep waaronder de service zal draaien. Het moet beslist een gebruiker zijn met Docker-rechten (bijv.sudo usermod -aG docker your_username
voor de ingestelde gebruiker). -
WorkingDirectory
: De directory waarin hetmain.py
bestand van de FastAPI app zich bevindt. -
Environment="PATH=..."
: Dit gedeelte is essentieel. Wanneer jesubprocess.run()
aanroept metgit
,docker
,docker compose
en andere externe commando's, kan dePATH
omgeving vansystemd
anders zijn dan die in.bashrc
is ingesteld. Het is dus essentieel om het pad voor de uitvoering vanuvicorn
in de virtuele omgeving (/home/your_username/projects/webhook_server/venv/bin
) en de gebruikelijke systeem uitvoer paden (/usr/local/bin
,/usr/bin
, etc.) expliciet te specificeren. -
EnvironmentFile
(optioneel): Omdat de FastAPI app zelf de.env
file laadt metpython-dotenv
, is het niet nodig om omgevingsvariabelen zoalsGITHUB_WEBHOOK_SECRET
enSAMPLE_PROJECT_N_PATH
met deze instelling te laden. Je kunt echter ook deEnvironmentFile
instellen als je een consistente omgeving wilt begeleiden voor deExecStart
commando datuvicorn
uitvoert. Afhankelijk van jouw omgeving en voorkeuren kun je dit gedeelte incommentariëren of laten staan. -
ExecStart
: Dit is het daadwerkelijke commando dat de service start. Je moet het pad naar hetuvicorn
uitvoerbare bestand in de virtuele omgeving exact opgeven.--host 0.0.0.0 --port 8000
zorgt ervoor dat alle IP's verbinding kunnen maken met poort 8000. -
Restart=always
: Als de service om welke reden dan ook stopt, probeert Systemd deze automatisch opnieuw te starten. -
StandardOutput=journal
,StandardError=journal
: Dit stuurt alle uitvoer en fouten van de service naar het geïntegreerde loggingsysteem van Systemd,journalctl
.
-
-
[Install]
sectie: Definieert hoe de service geactiveerd zal worden door een target.WantedBy=multi-user.target
zorgt ervoor dat deze service automatisch start wanneer de server opstart in een typische multi-user status.
3.3. Registreren en starten van de Systemd service
Na het creëren van het servicebestand moet je Systemd informeren over het nieuwe bestand en de service starten.
# Systemd informeren over het nieuwe servicebestand.
sudo systemctl daemon-reload
# Zorg ervoor dat de service automatisch start bij opstarten.
sudo systemctl enable github-webhook-deployer.service
# Start de service.
sudo systemctl start github-webhook-deployer.service
# Controleer de status van de service. Het moet 'active (running)' weergeven.
sudo systemctl status github-webhook-deployer.service
Nu is je FastAPI webhook server zo ingesteld dat deze automatisch wordt uitgevoerd, zelfs na een serverherstart, en betrouwbaar op de achtergrond de webhook verzoeken zal afwachten.
4. Monitoring en debugging van de FastAPI webhook service
Met een Systemd service is het veel eenvoudiger om logs te controleren en problemen te diagnosticeren.
- Controle van de service status:
sudo systemctl status github-webhook-deployer.service
Dit commando laat de huidige status van de service, de laatste uitvoertijd en de proces-ID zien.
- Live log controleren:
sudo journalctl -u github-webhook-deployer.service -f
De -u
optie toont de logs voor een specifieke service, en de -f
optie blijft nieuwe logs in real-time weergeven. Elke keer wanneer er een webhook verzoek binnenkomt, zullen de logging berichten van main.py
hier verschijnen.
Als de service niet start of niet naar verwachting functioneert, moet je als eerste de journalctl
logs controleren om foutmeldingen te vinden.
5. Conclusie: Vooruitblik op deel 5
In dit vierde deel hebben we de werking van de deployment handler logica die in deel 3 is geïmplementeerd opnieuw gekarakteriseerd, en we hebben geleerd hoe deze FastAPI webhook server als een Systemd service geregistreerd kan worden voor betrouwbare werking. Nu zal je webhook server ononderbroken functioneren, zelfs na een serverherstart.
In het volgende deel 5 zullen we de laatste puzzelstukjes in elkaar zetten en het systeem afronden. We zullen Nginx instellen als reverse proxy om de webhook server veilig bloot te stellen aan het externe netwerk, HTTPS toepassen om de beveiliging te versterken, en tenslotte de webhook van de GitHub repository koppelen om de automatische deployment daadwerkelijk te testen. Blijf op de hoogte!
댓글이 없습니다.