L'ingegneria frontend moderna non somiglia affatto a come era un decennio fa. Non stai solo scrivendo HTML e CSS. Un tipico progetto oggi viene rilasciato con un runtime Node.js specifico, una versione bloccata del package manager, un groviglio di strumenti di build e pipeline di deployment che si aspettano che tutto sia perfettamente allineato. Qualche volta, tra il primo npm install e la build finale per la produzione, si insinuano piccole differenze. Un collega usa Node 20. Tu usi Node 18. Uno strumento CLI globale sulla tua macchina maschera una dipendenza mancante sulla sua. Poi arriva la frase che nessuno vuole sentire: "Funziona sulla mia macchina."
Docker si guadagna il suo posto nel tuo toolkit frontend perché elimina quell'incertezza. Impacchetta la tua applicazione con il runtime esatto, le librerie di sistema e le dipendenze di cui ha bisogno. Che tu stia programmando su Windows, rilasciando da macOS o distribuendo su un'istanza cloud Linux, il comportamento rimane identico.
Perché gli sviluppatori frontend dovrebbero interessarsene
I punti critici che Docker risolve non sono astratti. Si presentano in ogni sprint.
I conflitti di versione fanno perdere tempo. Un vecchio progetto per un cliente richiede Node 18, il tuo progetto personale richiede Node 20 e il nuovo lavoro per una startup richiede Node 22. Senza i container, gestisci tutto questo tramite version manager. Funziona, finché non smette di farlo. Una piccola discrepanza nella versione di npm può cambiare il modo in cui vengono risolte le peer dependencies, lasciandoti con una build interrotta che funziona perfettamente per qualcun altro. Quando un framework annuncia una nuova release, il ciclo di feedback non dovrebbe essere di due ore di reinstallazioni. Dovrebbe essere la modifica di un singolo file e il riavvio di un container.
I pacchetti globali sono un'altra fonte di attrito silenzioso. Potresti avere Angular CLI, Expo o Prisma installati globalmente da sei mesi. Un nuovo sviluppatore installa lo stesso strumento da zero e ottiene una versione diversa. Improvvisamente, i tuoi script di build restituiscono avvisi che non compaiono altrove. Docker risolve questo problema mantenendo tutto locale al progetto. Definisci la versione di Node nel tuo Dockerfile. Le dipendenze vengono installate all'interno del container, isolate dal tuo sistema operativo host. Il tuo laptop potrebbe essere macOS, Windows o Ubuntu; l'applicazione vede esattamente lo stesso ambiente ogni volta.
I vantaggi per l'onboarding sono difficili da ignorare. Le nuove assunzioni non hanno bisogno di un readme di tre pagine che copre installazioni Homebrew, alias nvm e correzioni dei permessi globali. Installano Docker, clonano il repository ed eseguono un comando. Un setup che prima richiedeva un intero pomeriggio si riduce a pochi minuti. E quando passano a un altro progetto, nulla rimane in sospeso. Nessun tool globale orfano. Nessun version manager in lotta per la precedenza nel PATH. La loro macchina locale rimane pulita.
Immagini e Container: le basi
Se Docker è nuovo per te, la terminologia è più semplice di quanto sembri. Un'immagine Docker è un blueprint. Contiene il tuo codice sorgente, il runtime Node.js, il tuo lockfile e ogni dipendenza necessaria per eseguire l'app. Un container è un'istanza attiva creata da quell'immagine. Pensa all'immagine come a una ricetta e al container come al piatto reale. Puoi preparare lo stesso dolce cento volte partendo da una ricetta. Puoi avviare container identici da un'unica immagine senza preoccuparti di cosa sia installato sul computer host.
Un Dockerfile pratico
Vediamo un punto di partenza concreto. Se stai
