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
Creare una libreria CSS universale: Immagini
Applicare un filtro per recuperare alcune issue di GitHub
Ottenere un token di accesso per una GitHub App
Gestire gli accessi con Token su Azure Container Registry
Selettore CSS :has() e i suoi casi d'uso avanzati
Eseguire script pre e post esecuzione di un workflow di GitHub
Disabilitare le run concorrenti di una pipeline di Azure DevOps
Utilizzare Azure AI Studio per testare i modelli AI
Migliorare i tempi di risposta di GPT tramite lo streaming endpoint in ASP.NET Core
Evitare (o ridurre) il repo-jacking sulle GitHub Actions