2025: anno di cambiamenti infrastrutturali

A circa un anno e mezzo dalla pubblicazione del nostro precedente post (https://dvisionlab.it/8-persone-una-infrastruttura/), in cui descrivevamo l’infrastruttura aziendale e accennavamo all’uso di Ansible per l’automazione dei deploy, si rende opportuno un aggiornamento. L’evoluzione tecnologica e l’esigenza di ottimizzare ulteriormente i nostri flussi di lavoro ci hanno spinti a intraprendere un percorso di trasformazione significativo.

La transizione da Ansible a NixOS

Sebbene Ansible si sia dimostrato uno strumento efficace per la gestione della nostra infrastruttura, l’esperienza maturata ha evidenziato l’opportunità di migrare verso un sistema che offrisse un controllo maggiore, maggiore manutenibilità e migliore riproducibilità. La scelta è ricaduta su NixOS, un sistema operativo basato su Linux e sul gestore di pacchetti Nix.

Il concetto fondamentale di Nix(OS) risiede nel suo approccio con cui si strutturano i pacchetti all’interno del filesystem. A differenza delle distribuzioni tradizionali, in cui le librerie e i pacchetti sono distribuiti in directory standard come /usr/lib o /usr/bin (e in cui i nomi dei file in queste directory sono risorse contese da più pacchetti, che quindi possono collidere e rompersi a vicenda), NixOS utilizza una struttura non convenzionale: ogni pacchetto e le sue dipendenze risiedono in una directory separata, collegata ai binari tramite un sistema di path del linker. Questo approccio, che ricorda alcuni principi della programmazione funzionale pura, elimina la sezione critica dovuta a un filesystem unico e mutevole, riducendo le difficoltà di gestione e l’effort richiesto per i maintainer delle distrubuzioni.

Adottare di NixOS in azienda

L’adozione di NixOS ha avuto luogo in diverse fasi. Inizialmente, è stato adottato come daily driver da un membro del team per la propria workstation, permettendoci di studiarlo e capirne i fondamenti lungo un periodo di tempo relativamente esteso. Altri membri del team sono poi stati coinvolti in questa fase di esplorazione e valutazione: inizialmente come attività di R&D interna all’azienda e successivamente adottandolo per alcuni casi individuali. Soddisfatti e convinti della scelta, abbiamo poi migrato, un servizio alla volta in modo non distruttivo, i vari server su cui ci appoggiamo.

La gestione delle configurazioni avviene tramite un unico repository flake, il quale centralizza la definizione dei vari server NixOS. Tramite l’adozione di pipeline CI, possiamo quindi testare e distribuire i cambiamenti e gli aggiornamenti in maniera automatizzata ad ogni push, mantenendo il repository sempre sincronizzato con lo stato dei server. Tale metodologia facilita la sperimentazione e lo sviluppo, permettendo al contempo un rollback rapido in caso di problemi. È importante notare, tuttavia, che tale approccio non si estende intrinsecamente alla gestione dei database, che mantengono la loro natura di stato e richiedono un’attenzione specifica.

Il processo di aggiornamento dei sistemi è stato quindi notevolmente semplificato, potendo essere eseguito sia manualmente, sia in modo automatico. Per la gestione sicura dei segreti, abbiamo adottato agenix, che ci permette di salvare i segreti come parte della configurazione.

NixOS si è rivelato particolarmente utile anche per il deploy delle applicazioni che sviluppiamo, internamente o per i nostri clienti. L’installazione di NixOS su un nuovo server in cloud è resa efficiente da strumenti come nixos-infect o nixos-anywhere, che permettono di replicare le configurazioni delle macchine di test direttamente dal repository. Nel caso in cui il cliente preferisca non adottare NixOS, possiamo comunque utilizzare approcci più tradizionali.

La possibilità di creare facilmente container da una derivazione Nix è un ulteriore vantaggio, poiché agevola il deploy delle applicazioni su sistemi che non utilizzano NixOS.

Sempre legato al mondo nix, ma orientato allo sviluppo anziché al deploy, è devenv.sh, uno strumento che abbiamo iniziato ad usare con profitto. Esso permette di creare ambienti di sviluppo multi-linguaggio che siano facilmente riproducibili: in poche righe è possibile configurare le toolchain per i linguaggi che usiamo (typescript, rust, python, elm…), strumenti di supporto allo sviluppo (git, pre-commit…), editor (incluso il comodissimo nixvim) nonché i servizi e i container usati nello sviluppo (postgresql, caddy, nginx…). In aggiunta, velocizza molto l’onboarding di nuovi sviluppatori, codificando molta conoscenza che permette di iniziare a lavorare velocemente sul progetto – quasi senza dover leggere il README per fare il set-up dell’ambiente di sviluppo. Tutto sommato, è uno strumento molto comodo e ben curato, nato dal mondo nix e che non richiede agli utenti di conoscere nix in profondità.

Criticità e sfide

Nonostante i numerosi vantaggi, l’adozione di NixOS ha presentato alcune sfide.

  • Ambienti di sviluppo: L’uso di devenv.sh permette di creare ambienti di sviluppo multi-linguaggio riproducibili, tuttavia esiste una limitazione tecnica dovuta all’impossibilità di sincronizzare il lockfile di devenv.nix con quello del flake.nix, il che implica che la build di un pacchetto in un ambiente devenv non è garantita essere identica a quella generata dal flake (vedasi questa issue).
  • Gestione dei runner di GitHub Actions: La gestione dei runner richiede una certa attenzione a causa di alcune problematiche relative ai token e agli aggiornamenti automatici. Questo richiede un impegno aggiuntivo, specialmente per chi transita da un’architettura basata su container a un uso più intensivo di systemd.
  • Curva di apprendimento: È richiesta una certa dedizione per apprendere il linguaggio Nix e comprendere il codice esistente, in particolare per la scrittura di derivazioni personalizzate. Questo implica l’esistenza di una fase transitoria abbastanza lunga in cui pochi membri del team forniscono supporto ai nuovi utenti. Tuttavia, il ritorno in termini di efficienza e controllo è generalmente elevato.
  • Comunità e futuro del progetto: Si percepisce una certa incertezza all’interno della comunità, dovuta a visioni divergenti tra i membri e a una frammentazione dell’ecosistema. Questo fattore può rappresentare una preoccupazione per realtà più grandi della nostra che richiedono maggiori garanzie a lungo termine prima di un’adozione su larga scala. Noi siamo comunque confidenti che l’idea di base sia solida e che, indipendentemente dai dettagli e dalle piccole differenze tecniche che avverranno in futuro, esisteranno uno o più filoni di sviluppo su cui potremo fare affidamento.

Valutazione complessiva

In sintesi, Nix e NixOS si sono rivelati strumenti di grande valore che hanno apportato notevoli miglioramenti alla nostra gestione dell’infrastruttura. Sebbene richiedano un cambio di paradigma rispetto alle distribuzioni Linux tradizionali, la filosofia di Nix, una volta compresa, semplifica notevolmente processi che prima erano complessi. Il bilancio complessivo è decisamente positivo, nonostante le sfide e le criticità incontrate. Continueremo quindi ad usare questi strumenti, cercando di integrare ancora di più i nostri processi di sviluppo con le potenzialità date da questo strumento, come la possibilità di lanciare le configurazioni dentro a delle VM o di poter facilmente creare dei container con le derivazioni che sviluppiamo.

Ultimi articoli

Rendere i metadata DICOM leggibili per gli sviluppatori
Agents and code
Agentic Coding
Deep machine learning
Deep machine learning: cos’è, differenze con il machine learning e applicazioni pratiche

area contatti

Per informazioni, progetti, idee, scrivici