Docker

Se sei uno sviluppatore ti sarà sicuramente capitato nella fase finale di deploy dell’applicazione che stai sviluppando di notare che sull’ ambiente di produzione, quello finale che darai in mano al cliente, questa non risponda esattamente come nell’ambiente di testing.

Certo è normale che ciò accada ed è anche comprensibile: ognuno dei due ambienti carica risorse, linguaggi, librerie o addirittura sistemi operativi diversi.

Immagina invece di poter replicare un ambiente di test / produzione da locale a remoto o viceversa, astraendo completamente l’hardware sottostante. Non ti sembra di sognare?

Apri gli occhi perché esiste una soluzione comoda ed opensource e si chiama Docker.

E no, non sto parlando di virtualizzazione

Chi non hai mai sentito parlare di Docker penserà che stia parlando dell’ennesimo sistema di virtualizzazione, si sbaglia: d’ora in poi almeno in questo contesto abituiamoci a parlare di containers.

Cosa è un container?

In modo molto approssimativo possiamo definire la virtualizzazione tradizionale come la possibilità da parte di un sistema operativo dotato di Hypervisor di emulare l’hardware sottostante della macchina sui cui è installato al fine di mettere a disposizione di una o più macchine, che chiamiamo virtuali, un set completo di applicazioni, librerie oltre che un sistema operativo. Ogni macchina virtuale creata è completamente slegata e condivide solamente l’hardware virtuale messo a disposizione dall’Hypervisor.

Ma perché virtualizzare un intero sistema operativo quando ci si può limitare a un singolo componente, applicazione o servizio?

Beh questa è la domanda che già da parecchi anni diverse aziende (quali Google in primis) si sono poste.

La risposta rivoluzionaria è stata: al posto che utilizzare un sottostrato hardware virtualizzato partiamo dal kernel (Linux) della macchina di partenza ed agganciamo solamente quello che ci serve creando specifici contesti applicativi totalmente isolati, da qui il nome container.

Docker a sua volta ha preso quest’idea e l’ ha concretizzata diventando un sistema efficiente di distribuzione di applicazioni attraverso un formato di containerizzazione universale chiamato DockerFile.

Quindi quali sono i vantaggi effettivi di utilizzare Docker?

Per noi sviluppatori e per i nostri più vicini colleghi sistemisti Docker è una vera e propria manna del cielo: possiamo letteralmente pacchettizzare un’applicazione.

Prendiamo la nostra applicazione, le assegniamo solamente le risorse necessarie per l’esecuzione e la impacchettiamo effettuando felicemente il deploy su qualunque macchina indipendentemente dal sistema operativo utilizzato.

Di seguito alcuni dei vantaggi che abbiamo utilizzando Docker.

1.  Provisioning

Stiamo eliminando come già visto la pesantezza di un sottostrato hardware emulato che può rallentare (e di molto) l’assegnazione delle risorse e l’esecuzione dei nostri servizi.
Per questo motivo, a differenza delle macchine virtuali, possiamo avere tantissimi container anche in locale senza impattare (più di tanto) sulle prestazioni.

2.  Testing

Come diretta conseguenza della prima voce se utilizziamo questo strumento ai fini di testing frazioniamo i costi computazionali che altrimenti sarebbero proporzionali al numero di test effettuati, se utilizzassimo per esempio un cloud server.
Il container utilizza sempre le stesse risorse di calcolo assegnato, possiamo quindi fare tutti i test che vogliamo mantenendo costante il costo.

3.  Amministrazione

Prendiamo in esempio il ciclo di sviluppo della nostra applicazione, un sistema come Docker ci permette di avere un rilascio veloce di nuove release con pochi e semplici comandi.

4. Distribuzione

Al posto che distribuire la singola applicazione possiamo anche decidere di distribuire il container che contiene già l’ambiente di sviluppo adatto, il DBMS, librerie opzionali che servono esclusivamente per la nostra applicazione.

Questo ci permette di evitare aggiornamenti che possano minare l’utilizzo di altre applicazioni, malfunzionamenti per librerie diverse, coesistenza di diverse versioni di linguaggi, facilità di l’installazione del prodotto al nostro cliente finale.

5. Modularità e riusabilità

Al posto di re-installare su ogni container i servizi che sono comuni a molteplici istanze applicative, possiamo semplicemente creare dei container che contengano i servizi stessi e collegarli ad ogni istanza.

Installazione di Docker

Docker è multi-piattaforma, potremo installarlo su Linux, Mac e su Windows semplicemente seguendo i semplici passi illustrati sul sito ufficiale.

Va detto che ogni container eredita il kernel Linux del sistema operativo sulla macchina host sottostante, ma ovviamente il discorso cambia leggermente nel caso di sistemi Mac e Windows.

In questo caso l’installazione necessiterà anche di un’emulazione base del kernel Linux chiamata Docker Engine; per fare in modo che questa vada a buon fine assicuratevi che il vostro processore supporti Hyper-V.

Pacchettizziamo un’ambiente LAMP su Docker

Visto che siamo smanettoni e ci piace vedere terminali e codici vi illustro un esempio di come installare un ambiente LAMP (webserver Apache con PHP e MySQL) sfruttando i vantaggi di Docker, questo sarà anche un buon modo per familiarizzare con alcuni dei comandi più frequenti.

In questa parte darò per scontato che Docker sia già stato installato e che il suo servizio sia attivo.

Creiamo un container per MySQL

Partiamo da un’immagine relativa al sistema, applicazione o servizio su cui si baserà il nostro container. Possiamo considerarla come un set di comandi bash che installano servizi, dipendenze, o un sistema operativo minimale (qualora sia necessario).

Questa immagine è stand-alone e totalmente indipendente dal nostro container, pertanto potremo riutilizzarla successivamente in diversi altri contesti applicativi.

Possiamo creare noi stessi queste immagini di partenza: qui andremo a vedere come scaricarle direttamente da Docker Hub, un repository ufficiale che contiene centinaia di migliaia di immagini tra quelle più utilizzate ed è in costante aggiornamento.

Scarichiamo l’immagine attraverso il comando docker pull.

Spostiamoci sul terminale nel sistema in cui abbiamo installato Docker, e digitiamo:

sudo docker pull mysql

Con questo comando scarichiamo l’immagine relativa all’applicazione MySQL direttamente dall’Hub.

Ogni immagine contiene un tag che indica la versione della build che stiamo installando; nel caso questo tag non sia indicato verrà scaricata la build con tag latest, cioè la più recente.

Nel caso di MySQL la versione più recente sull’Hub attualmente è la 8, alternativamente usando per esempio il comando di seguito possiamo scaricare la versione 5.6:

sudo docker pull mysql:5.6

Come vedere una lista delle immagini scaricate tramite Docker

Per vedere le immagini scaricate con Docker possiamo utilizzare il seguente comando:

sudo docker images

Lista immagini Docker
Ogni immagine ha un nome REPOSITORY, un TAG, un ID, una data di creazione CREATED e una dimensione SIZE.

Creiamo e lanciamo il container MySQL a partire dall’immagine scaricata.

A partire dall’immagine scaricata creiamo il nostro container, per fare ciò utilizziamo il comando:

sudo docker run –d \
--name=mysql_container \
--env="MYSQL_ROOT_PASSWORD=password" \
-p=3900:3306 \
mysql_container:latest

Creazione container su Docker

Con questo comando creiamo la prima volta il container e lo lanciamo. Nello specifico:

  • l’argomento -d (detach) serve per mantenere il processo del container attivo
  • l’argomento –name permette di specificare il nome del container
  • l’argomento –env ci permette di specificare variabili d’ambiente (in questo caso la password dell’utente root MySQL)
  • l’argomento –p indica il forwarding della porta del container, il servizio MySQL nel nostro caso.
    -p=3900:3306 significa che la porta 3306 locale nel container verrà inoltrata sulla porta 3900 della macchina host
  • mysql:latest indica immagine di riferimento e tag specifico

Sul terminale comparirà l’ID del container appena creato a dimostrazione che l’operazione è andata a buon fine.

Alcune operazioni applicabili sui container

Il container è ora creato, possiamo controllarlo come fosse un servizio:

  • docker start mysql_container mette in esecuzione il container
  • docker stop mysql_container interrompe l’esecuzione del container
  • docker restart mysql_container riavvia l’esecuzione del container
  • docker rm mysql_container rimuove il container (a patto che questo non sia in esecuzione)
  • docker ps consente di vedere i containers in esecuzione

Non dimenticatevi di inserire il sudo davanti qualora eseguiste le operazioni da un utente non amministratore.

Creiamo un container per Apache e PHP

Potremmo adesso creare due container diversi per Apache e PHP, oppure utilizzarne uno unico a partire da un’immagine che contenga entrambi.
A seconda del contesto applicativo e della riusabilità dei containers sceglieremo la strategia che più ci aggrada.

In questo caso partiamo da un’ immagine che contiene già Apache e PHP; vediamo a partire dai comandi visti precedentemente come legandoli in un solo comando possiamo: creare l’immagine, il relativo container e mandarlo in esecuzione collegandosi direttamente al container mysql_container appena creato.

sudo docker run -d \
-p=8080:80 \
--link mysql_container:mysql \
-v /var/www/html:/var/www/html \
--name=apache_php_container \ 
tutum/apache-php

Download immagine, creazione container ed esecuzione su Docker
Alcune considerazioni su questo comando:

  • l’argomento –link permette di agganciare al container un altro container nel nostro caso quello MySQL precedentemente creato
  • l’argomento –v permette di far corrispondere una cartella locale nella macchina host (/var/www/html) ad una cartella del container (/var/www/html)

La nostra LAMP è pronta su Docker

L’ultimo comando ha già messo in esecuzione un container contenente Apache e PHP e collegato al container MySQL.

Non solo! Abbiamo specificato una cartella risiedente sulla macchina host che conterrà la Document Root del nostro Webserver e ci permetterà di accedere facilmente inserendo i nostri contenuti.

Non ci resta che provare, digitiamo sul nostro browser: http://localhost:8080 .
Se è tutto andato a buon fine dovrebbe apparirci Apache. Facile no?

In conclusione

Abbiamo visto solo una minima parte di quello che si può fare con Docker ma questo dovrebbe già bastare per vedere quanto uno strumento simile possa semplificare il nostro lavoro di tutti i giorni.

Una documentazione completa è comunque raggiungibile sul sito ufficiale ed è un ottimo punto di partenza per conoscere bene le fondamenta di questo servizio.

Anche voi utilizzate Docker? Come vi trovate? Fatemi sapere!

Andrea Debernardi

Andrea Debernardi

Cofondatore di dueclic, sviluppatore e appassionato di tecnologia. Pur essendo fortemente orientato al web la mia curiosità continua e attrazione riguardo le novità non mi precludono nulla nella programmazione. Non mi piace avere limiti perciò tendo a colmarli continuamente.