Introduzione a Docker

Fondamentali sulla containerizzazione degli applicativi software

Nicolò Gasparini
4 min readAug 30, 2019

Quando si parla di containers in ambito informatico, ci si riferisce a un’istanza virtualizzata che contiene ed esegue un’applicazione e tutte le sue dipendenze. L’ambiente dell’applicazione, anche detto environment, parte dal sistema operativo, passando per binaries, dipendenze e librerie esterne, in generale tutto ciò che è necessario al funzionamento dell’applicazione.

Questa definizione non suona nuova, ricorda molto le virtual machine.
A differenza delle macchine virtuali, però, ogni applicazione può condividere molti dei livelli comuni alle altre applicazioni, come il sistema operativo, e non necessita di un hypervisor, come potevano essere VMWare o VirtualBox.

Sulla destra si vede come le macchine virtuali rappresentino un’intera astrazione di un server fisico, in cui ogni applicazione necessita del sistema operativo replicato, mentre sulla sinistra vediamo diverse applicazioni che si appoggiano su Docker.

I container si basano sulle immagini, le images non sono altro che un template che descrive e contiene tutte le necessità della nostra applicazione. Uno dei punti forti delle immagini viene dal fatto che esse si possano basare su altre immagini, perciò potremo trovare online una parte della nostra applicazione già pronta e aggiungere solamente il necessario.

attraverso il comando `docker build` viene generata l’immagine

Le immagini vengono generate dal dockerfile, un file testuale che contiene i comandi necessari alla loro creazione.

Ad ogni comando scritto nel dockerfile corrisponde un layer dell’immagine, questi livelli vengono salvati su cache e possono essere condivisi, perciò è buona norma costruire le immagini con un approccio bottom-up, partendo dalle istruzioni più comuni e arrivando a quelle specifiche della nostra applicazione.

Un’immagine può avere multipli container in esecuzione

L’ultimo comando che verrà eseguito sarà quello che mette in esecuzione l’applicazione, e genererà l’ultimo layer, quello che viene chiamato container.

Il container difatti non è altro che un’immagine in esecuzione.

Mentre i primi livelli vengono generati in modalità di sola lettura, il container sarà l’unico livello ad essere anche in modalità di scrittura, perchè sarà quello sul quale lavoreremo.

Docker

Docker Inc. è un’azienda nata nel 2010. La tecnologia che ha sviluppato è diventata così comune che ad oggi il nome identifica il loro software di orchestrazione e tutti i servizi che offrono.

La diffusione di Docker è globale, e i vantaggi per uno sviluppatore sono evidenti, sia in termini di rapidità di deploy e portabilità di applicazioni fatte e finite, che in modalità di sviluppo, in particolare permettendo di sviluppare agilmente sullo stesso ambiente rispetto a quello di produzione.

Un quarto dei clienti di Datadog aveva adottato Docker al 2018

Esempio

Nulla è meglio della pratica per imparare, poniamo ad esempio di avere un applicativo web basato sul framework python Flask.
Immaginiamo di essere all’interno della cartella della nostra repository git, cosi strutturata:

application
├── module1
│ ├── __init__.py
│ └── cool_functions.py
├── frontend
│ ├── homepage.html
│ └── images
│ └── logo.png
├── requirements.txt
├── .gitignore
└── app.py

Il nostro obiettivo è quello di portare l’intera applicazione in un container, perciò il primo passo da compiere è quello di creare un dockerfile.

# partiamo da un'immagine ufficiale linux con python 3.7 già installato
FROM python:3.7
# ci spostiamo all'interno del file system
WORKDIR /usr/src/app
# copiamo il file dei requirements locale nella cartella attuale del container
COPY requirements.txt .
# installiamo i requirements all'interno del sistema, non servono virtual environment
RUN pip install -r requirements.txt
# copiamo gli altri file della nostra app
COPY . .
# settiamo la variabile di ambiente per specificare il file dell'app flask
ENV FLASK_APP=app.py
# esponiamo la porta standard di flask in modo che sia raggiungibile dall'esterno
EXPOSE 5000
CMD ["python", "-m", "flask", "run", "--host=0.0.0.0"]

Una volta che il dockerfile è stato creato e salvato, per costruire l’immagine è necessario eseguire il seguente comando:

docker build -t flask-application .

Il parametro -t indica un tag che applicheremo all’immagine per poterla riconoscere, altrimenti gli verrebbe assegnato un hash da Docker. Il punto alla fine del comando specifica l’entrypoint della build, ovvero la cartella che contiene il dockerfile.
È importante sottolineare che solamente i file contenuti nelle sottocartelle dell’entrypoint potranno essere utilizzati per la procedura di build, perchè corrispondono al contesto della build.

Una volta che l’immagine è stata generata possiamo eseguire il container con questo comando:

docker run flask-application

All’interno di questo container verrà automaticamente eseguito l’ultimo comando specificato nel dockerfile, ovvero quello che eseguirà l’applicazione flask.
Possiamo controllare i container in esecuzione attraverso il comando docker ps -a e verificare il funzionamento della nostra app richiamandola, aprendo il browser o con il comando curl 127.0.0.1:5000

Oltre a questi elementi di base Docker mette a disposizione anche volumi, network e molti altri strumenti utili, fra cui docker-compose.

Grazie a queste informazioni di base sarete in grado di costruire e far funzionare una prima applicazione all’interno di un container!

--

--

Nicolò Gasparini

Software Engineer and full stack developer 💻 based in Italy — /in/nicologasparini/