Ciao, e benvenuto nell'ottava puntata della dodicesima stagione. Abbiamo detto che ogni container è una bolla isolata, un mondo separato che non vede il resto. Questa è una delle sue qualità migliori. Ma solleva subito un problema pratico: se ogni container è isolato, come fanno due container a parlarsi tra loro? Come fa il container del mio programma a comunicare con il container del mio database, se sono due bolle separate? Oggi rispondiamo, e capiamo come i container comunicano tra loro e con il mondo esterno: la rete di Docker.
Partiamo dal problema, che è la conseguenza diretta dell'isolamento. Un'applicazione reale, come abbiamo visto nelle stagioni precedenti, è quasi sempre fatta di più pezzi che collaborano: il programma principale, il database, magari altri servizi. In Docker, tipicamente, ogni pezzo vive nel proprio container separato. Ma se questi container sono bolle isolate, che di default non si vedono, allora il container del programma non può raggiungere il container del database per chiedergli i dati. L'isolamento, che era una virtù, diventa un ostacolo alla collaborazione. Serve un modo per aprire canali di comunicazione controllati tra i container che devono parlarsi.
La soluzione di Docker è elegante e riprende un concetto della stagione sul backend: le reti virtuali. Docker permette di creare delle reti, cioè degli spazi di comunicazione, e di collegare a esse i container che devono parlarsi. I container collegati alla stessa rete si vedono e possono comunicare tra loro, mentre restano isolati da tutto ciò che non è su quella rete. È come dare a un gruppo di container una stanza comune in cui possono parlarsi liberamente, tenendo la porta chiusa verso l'esterno. Metti il container del programma e quello del database sulla stessa rete, ed ecco che possono dialogare, restando comunque protetti dal resto del mondo.
C'è un dettaglio bellissimo di questo sistema che merita di essere raccontato, perché è molto comodo: i container si trovano per nome. Quando due container sono sulla stessa rete, uno può raggiungere l'altro semplicemente chiamandolo con il suo nome, come se fosse un indirizzo. Il container del programma non deve conoscere numeri complicati o indirizzi che cambiano: gli basta dire voglio parlare con il container chiamato database, e Docker si occupa di recapitare il messaggio al container giusto. È come chiamare una persona per nome in una stanza, invece di doverne conoscere le coordinate esatte. Questo rende collegare i pezzi di un'applicazione semplice e leggibile.
Voglio soffermarmi su perché questo isolamento con canali controllati sia una buona cosa. Il fatto che i container siano isolati di default, e comunichino solo attraverso reti che definisci esplicitamente, è un vantaggio di sicurezza. Tu decidi con precisione chi può parlare con chi: il database può essere raggiungibile solo dal programma, e non dal mondo esterno. Questo limita i danni: se qualcosa andasse storto, un container esposto non dà automaticamente accesso a tutti gli altri. È una forma di buona igiene, che riprende i temi di sicurezza del backend.
Ora affrontiamo l'altra metà del problema: come fa il mondo esterno, cioè tu con il tuo browser, a raggiungere un container? Perché finora abbiamo parlato di container che si parlano tra loro, ma a un certo punto un utente vero, da fuori, deve poter raggiungere il programma. E qui c'è un altro meccanismo, quello dell'esposizione delle porte. Di default, un container è chiuso anche verso l'esterno: nessuno da fuori può entrare. Ma tu puoi decidere di aprire esplicitamente una porta, creando un passaggio controllato tra il mondo esterno e un container specifico. È come aprire una finestra precisa in un edificio altrimenti sigillato, attraverso cui il pubblico può entrare per raggiungere un servizio.
Fermiamoci su questa idea di porta. Ricordi dalla stagione tecnica che i programmi in rete ascoltano su delle porte, come sportelli numerati? Esporre una porta significa collegare uno sportello del tuo computer a uno sportello interno del container, così che chi bussa fuori venga fatto entrare fino al programma. Apri solo le porte che servono, e tieni chiuso il resto. Il database, di solito, non espone porte verso l'esterno: deve essere raggiungibile solo dal programma, non dal pubblico.
Mettiamo insieme il quadro completo, perché ora si vede l'eleganza del sistema. In una tipica applicazione, hai il container del programma e il container del database, entrambi collegati a una rete privata comune, su cui si parlano per nome, al riparo dal mondo. Poi apri una sola porta verso l'esterno, quella del programma, così che gli utenti possano raggiungerlo dal loro browser. Il database resta invisibile dall'esterno, protetto, raggiungibile solo dal programma attraverso la rete privata. È un'architettura pulita, sicura e ordinata: comunicazione libera all'interno, accesso controllato dall'esterno, ciascun pezzo esposto solo quanto necessario.
Per oggi ci fermiamo qui. Siccome i container sono bolle isolate, per farli comunicare Docker usa le reti virtuali: i container sulla stessa rete si parlano, trovandosi comodamente per nome, restando isolati dal resto. Questo isolamento con canali espliciti è anche un vantaggio di sicurezza, perché decidi tu chi parla con chi. Per far entrare il mondo esterno, invece, si espongono esplicitamente delle porte, aprendo passaggi controllati solo verso i container che devono essere raggiungibili. Il risultato è un'architettura ordinata e sicura. Nella prossima puntata mettiamo tutto insieme e orchestriamo più container con Docker Compose. Nelle note trovi qualche spunto. Se ti è utile, condividila. Grazie per l'ascolto, e ci sentiamo alla prossima.