Quando utilizziamo un workflow in GitHub, ci dobbiamo preoccupare di specificare il runner (o l'agent) all'interno del quale verrà eseguito il processo. Questo si divide principalmente in due scelte: quella on-prem e quella hosted, gestita da GitHub stessa. Nel primo caso, ci dobbiamo gestire noi hardware e software. Nel secondo, invece, abbiamo una VM già pre-configurata con una serie di software già presenti. Tra le altre differenze che troviamo, nel caso dell'on-prem, siamo più esposti a rischi di sicurezza, poiché, di fatto, non c'è il riciclo dell'hardware che, infatti, potrebbe essere utilizzato da più workflow all'interno della nostra istanza di GitHub (per esempio fra più repository), mentre condividono lo stesso storage. Allo stesso modo, la gestione delle dipendenze è un po' più complessa, in quanto se vengono richieste, per esempio, molte versioni di SDK, librerie e quant'altro necessario allo sviluppo, diventa più complicato manutenere tutta l'infrastruttura.
Proprio per gestire questi casi più complessi, dove magari si vuole il meglio di un ambiente e dell'altro, si può far riferimento ad una terza opzione: il Docker container. Infatti, è possibile creare una immagine di Docker e utilizzarla per eseguire il nostro workflow. Vediamo un esempio:
name: CI on: push: branches: [ main ] jobs: container-test-job: runs-on: ubuntu-latest container: image: node:18 env: NODE_ENV: development ports: - 80 volumes: - my_docker_volume:/volume_mount options: --cpus 1 steps: - name: Check for dockerenv file run: (ls /.dockerenv && echo Found dockerenv) || (echo No dockerenv)
In questo caso, il runner è una macchina hosted basata su Ubuntu, ma l'esecuzione del workflow viene "demandata" al container che viene messo in esecuzione, ovvero una distribuzione di NodeJS. Stessa cosa potrebbe avvenire nel sistema on-prem. Per ridurre al minimo il rischio che un workflow "contamini" un altro che condivide lo stesso storage, artifact, librerie o altro, è fondamentale fare in modo che il flusso giri su un sistema che può essere eliminato alla fine del workflow e riutilizzato. In questo caso Docker è l'ideale, poiché di fatto il container è stateless.
Come si può vedere dall'esempio, poi, è anche possibile andare a customizzare l'immagine base. Di fatto, quindi, può essere utile costruire una immagine base per tutta la mia organizzazione aziendale, in cui vado ad installare le dipendenze necessarie ad eseguire i miei processi. Eventualmente, per ciascun workflow, vado poi ad impostare la porta di esecuzione, variabili d'ambiente e altri setting secondo le mie esigenze.
Nota di chiusura riguarda invece il tema consumi: è chiaro che più piccola sarà l'immagine Docker, prima il workflow potrà metterlo in esecuzione e più tempo (e costi) risparmieremo per l'esecuzione della stessa, che ci verranno comunque conteggiati nella fattura a fine mese.
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
Approfondimenti
Escludere alcuni file da GitHub Secret Scanning
Gestione degli stili CSS con le regole @layer
Rinnovare il token di una GitHub App durante l'esecuzione di un workflow
Recuperare automaticamente un utente e aggiungerlo ad un gruppo di Azure DevOps
Eseguire script pre e post esecuzione di un workflow di GitHub
Ottimizzare le pull con Artifact Cache di Azure Container Registry
Gestire gli accessi con Token su Azure Container Registry
Conoscere il rendering Server o WebAssembly a runtime in Blazor
Configurare lo startup di applicazioni server e client con .NET Aspire
Ottenere un token di accesso per una GitHub App
Miglioramenti nelle performance di Angular 16
Eseguire query per recuperare il padre di un record che sfrutta il tipo HierarchyID in Entity Framework