#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
ADDeCOPYè che il primo ha funzionalità maggiori tra cui il poter copiare file remoti all’interno del container tramiteURLoppure estrarre un file compresso all’interno del container mentreCOPYcopia solo i file locali dall’host al container.COPYè stato introdotto per problemi di funzionalità del comandoADDche 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:
-tper 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
-ted 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:3Specifico di utilizzare l’immagine di python3COPY ./app.py /Specifico di copiare il fileapp.pynellarootdel containerCMD ["python", "./app.py"]Specifico di eseguire il comandopython app.pyquando il container viene eseguito (senza ilWORKDIRCMDesegue 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:3Specifico di utilizzare l’immagine di python3RUN mkdir /webserverEsegue il comandomkdirche crea una sottocartella dellarootdenominatawebserverWORKDIR /webserverSposta la directory di lavoro del container in/webserverCOPY ./requirements.txt /webserver/Copia il filerequirements.txtnella cartella/webserverRUN pip install -r requirements.txtEsegue il comandopip install -rche crea installa tutte le librerie specificate nelrequirements.txtCOPY ./app.py /webserver/Copiaapp.pydall’host e lo salva nella cartella/webserverdel containerCMD ["flask", "run", "--host=0.0.0.0"]Esegue il comandoflask run --host=0.0.0.0che esegueapp.pye 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.