#howto - Creare un Dockerfile
Docker è un software open source, multipiattaforma che permette di virtualizzare singole applicazioni in dei container isolati dal sistema host principale.
Abbiamo già parlato di Docker in un precedente articolo a cui vi rimando per approfondire l’argomento.
In questa guida vediamo come realizzare un Dockerfile, ossia una immagine Docker personalizzata, su misura delle nostre necessità.
Prerequisiti
Prima di procedere con questa lettura sarebbe bene visionare l’articolo precedente:
Obiettivi
In questo articolo verrà:
- Spiegato cos’è un Dockerfile, i principali comandi e l’utilità di esso
- Spiegato come eseguire un Dockerfile e creare un container da esso
- Fatti due esempi di Dockerfile
Cos’è un Dockerfile
Un Dockerfile è un file di testo contenente alcuni comandi comprensibili a Docker da cui è possibile, da un’immagine di partenza, creare una nostra immagine personalizzata.
Per essere riconosciuto da Docker, il Docker file dovrà chiamarsi proprio Dockerfile
senza estensioni e senza modificare maiuscole e minuscole.
Alcuni dei comandi del Dockerfile che andremo ad utilizzare sono:
FROM <nome-immagine>
specifica l’immagine di partenza (viene prima verificato se si trova nei repo locali altrimenti la scarica dal Dockerhub)RUN <comando>
esegue uno o più comandi prima della creazione del containerADD <file/dir> <path>
copia un file dell’host o remoto all’interno di una cartella del containerCOPY <file/dir> <path>
copia un file dell’host all’interno di una cartella del containerCMD ["<comando>", ...]
specifica uno o più comandi da eseguire all’interno del container quando viene richiamatoWORKDIR <path>
specifica la directory nel quale i comandi settati su CMD devono essere eseguiti
Nota:
La differenza tra
ADD
eCOPY
è che il primo ha funzionalità maggiori tra cui il poter copiare file remoti all’interno del container tramiteURL
oppure estrarre un file compresso all’interno del container mentreCOPY
copia solo i file locali dall’host al container.COPY
è stato introdotto per problemi di funzionalità del comandoADD
che per via delle sue troppe funzionalità può avere comportamenti inaspettati quando si cerca di copiaere un file su un container.
Come eseguire un Dockerfile
Per eseguire un Dockerfile dobbiamo usare un comando di Docker, build
.
Il comando build interpreta i comandi del dockerfile e li esegue in ordine. Crea e da un nome all’immagine personalizzata che abbiamo creato e la salva all’interno del nostro repository locale di Docker.
Per eseguire il comando dobbiamo specificare la directory nel quale abbiamo creato il nostro Dockerfile e quindi eseguire:
docker build -t <nome-immagine> <path>
dove:
-t
per aggiungere un tag all’immagine<nome-immagine>
il nome che vogliamo dare alla nostra immagine<path>
è la directory nel quale si trova il Dockerfile
Nota:
Possiamo anche escludere il
-t
ed il<nome-immagine>
ma in questo il nome dell’immagine sarà un codice assegnato da Docker che risulta molto scomodo da ricordare e da cercare perciò per comodità è sempre meglio assegnare sempre un nome manualmente.
Quindi poi eseguire:
docker run <nome-immagine>
Per creare il container ed eseguirlo.
Perchè utilizzare un Dockerfile
Ci sono due motivi per utilizzare un Dockerfile e quindi creare una nostra immagine personalizzata.
Il primo motivo è che nonostante sul Dockerhub (il repository di Docker) vi siano migliaia di immagini per Docker magari non esiste quella specifica per le nostre esigenze perciò siamo costretti a crearela noi manualmente.
Il secondo motivo è che magari vogliamo poter avere un container basato sulla nostra immagine su diverse macchine ed utilizzare un Dockerfile è perfetto per questo scopo grazie al suo alto livello di portabilità, infatti sarà necessario solamente avere Docker installato ed eseguire docker build
e docker run
per avere quello che ci serve.
Creazione di un Dockerfile
Adesso andremo a vedere come creare un Dockerfile, caricare l’immagine e eseguire il container. Prima di ciò eseguiamo:
docker pull python:3
docker pull node
Per avere gia scaricate le immagini che andremo ad utilizzare negli esempi.
Esempio 1
Nel primo esempio andremo a creare un semplice file in python che stampa a schermo un “hello world” e lo faremo eseguire da un container.
Quindi creiamo un semplice file python che stampa “hello world”:
print('Hello, world')
E salviamiamolo come app.py
Dopodichè andiamo a creare il Dockerfile
nella stessa directory di app.py
che sarà composto in questo modo:
FROM python:3
COPY ./app.py /
CMD ["python", "./app.py"]
prima di eseguire il build
commentiamo il codice:
FROM python:3
Specifico di utilizzare l’immagine di python3COPY ./app.py /
Specifico di copiare il fileapp.py
nellaroot
del containerCMD ["python", "./app.py"]
Specifico di eseguire il comandopython app.py
quando il container viene eseguito (senza ilWORKDIR
CMD
esegue nellaroot
)
Quindi ora creiamo l’immagine:
docker build -t hello-python .
e successivamente eseguiamo il container:
docker run hello-python
E se tutto è andato a buon fine stamperà un “Hello, world”.
Esempio 2
In questo esempio creeremo un semplice webserver in python tramite Flask
eseguito dentro un container.
Per prima cosa creiamo il file app.py
:
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello():
return "Hello, World!"
Questo codice creerà un semplice webserver.
Nella stessa cartella di app.py
creaiamo il requirements.txt
contenente i nomi delle librerie utilizzate da python (in questo caso solo Flask):
Flask==2.0.0
Infine andiamo a definire il nostro Dockerfile
:
FROM python:3
RUN mkdir /webserver
WORKDIR /webserver
COPY requirements.txt /webserver/
RUN pip install -r requirements.txt
COPY ./app.py /webserver/
CMD ["flask", "run", "--host=0.0.0.0"]
e adesso andiamo a commentarlo:
FROM python:3
Specifico di utilizzare l’immagine di python3RUN mkdir /webserver
Esegue il comandomkdir
che crea una sottocartella dellaroot
denominatawebserver
WORKDIR /webserver
Sposta la directory di lavoro del container in/webserver
COPY ./requirements.txt /webserver/
Copia il filerequirements.txt
nella cartella/webserver
RUN pip install -r requirements.txt
Esegue il comandopip install -r
che crea installa tutte le librerie specificate nelrequirements.txt
COPY ./app.py /webserver/
Copiaapp.py
dall’host e lo salva nella cartella/webserver
del containerCMD ["flask", "run", "--host=0.0.0.0"]
Esegue il comandoflask run --host=0.0.0.0
che esegueapp.py
e crea il webserver sullocalhost
(che in questo caso è il localhost del container 172.17.0.x)
Eseguiamo quindi:
docker build -t flask-webserver
ed infine:
docker run flask-webserver
che dovrebbe stampare un messaggio simile:
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: off
* Running on all addresses.
WARNING: This is a development server. Do not use it in a production deployment.
* Running on http://172.17.0.2:5000/ (Press CTRL+C to quit)
Se quindi proviamo andare in http://172.17.0.2:5000
potrevo vedere stampato il messaggio “Hello, world”, mentre se premiamo CTRL+C
chiuderemo il webserver e di conseguenza anche il container.