Introduzione
Un'immagine Docker è il progetto dei contenitori Docker che contiene l'applicazione e tutto il necessario per eseguire l'applicazione. Un contenitore è un'istanza di runtime di un'immagine.
In questo tutorial, spiegheremo cos'è Dockerfile, come crearne uno e come costruire/creare un'immagine Docker con Dockerfile.
Cos'è Dockerfile
Un file Docker è un file di testo che contiene tutti i comandi che un utente potrebbe eseguire sulla riga di comando per creare un'immagine. Include tutte le istruzioni necessarie a Docker per creare l'immagine.
Le immagini Docker sono costituite da una serie di livelli di filesystem che rappresentano le istruzioni nel file Docker dell'immagine che costituisce un'applicazione software eseguibile.
Il file Docker ha la forma seguente:
# Comment
INSTRUCTION arguments
INSTRUCTION
non fa distinzione tra maiuscole e minuscole, ma la convenzione prevede l'uso di MAIUSCOLO per i suoi nomi.
Di seguito è riportato un elenco con una breve descrizione di alcune delle istruzioni Dockerfile più utilizzate:
- ARG : Questa istruzione consente di definire variabili che possono essere passate in fase di compilazione. Puoi anche impostare un valore predefinito.
- FROM - L'immagine di base per la creazione di una nuova immagine. Questa istruzione deve essere la prima istruzione senza commenti nel file Docker. L'unica eccezione a questa regola è quando si desidera utilizzare una variabile
FROM
nell'argomento. In questo caso,FROM
può essere preceduto da una o più istruzioniARG
. - LABEL: Utilizzata per aggiungere metadati a un'immagine, ad esempio descrizione, versione, autore ..etc. Puoi specificare più di uno
LABEL
e ogni istruzioneLABEL
è una coppia chiave-valore (key-value). - RUN - I comandi specificati in questa istruzione verranno eseguiti durante il processo di compilazione. Ogni istruzione
RUN
crea un nuovo livello sopra l'immagine corrente. - ADD: utilizzato per copiare file e directory dalla sorgente specificata alla destinazione specificata sull'immagine Docker. La fonte può essere file o directory locali o un URL. Se l'origine è un archivio tar locale, viene automaticamente decompresso nell'immagine Docker.
- COPY- Simile a
ADD
ma l'origine può essere solo un file o una directory locale. - ENV : Questa istruzione consente di definire una variabile di ambiente.
- CMD : Utilizzato per specificare un comando che verrà eseguito quando si esegue un contenitore. È possibile utilizzare solo un'istruzione
CMD
nel Dockerfile. - ENTRYPOINT - Simile a
CMD
, questa istruzione definisce quale comando verrà eseguito quando si esegue un contenitore. - WORKDIR - Questa direttiva imposta la directory di lavoro corrente per le istruzioni
RUN
,CMD
,ENTRYPOINT
,COPY
, eADD
. - USER - Impostare il nome utente o
UID
per l'uso durante l'esecuzione di eventuali le istruzioni seguentiRUN
,CMD
,ENTRYPOINT
,COPY
, eADD
. - VOLUME : Consente di montare una directory del computer host sul contenitore.
- ESPOSIZIONE : utilizzato per specificare la porta su cui il contenitore è in ascolto in fase di esecuzione.
Per, escludere file e directory dall'aggiunta all'immagine, creare un file .dockerignore
nella directory di contesto (context). La sintassi di .dockerignore
è simile a quella del file Git .gitignore
.
Per un riferimento completo e una spiegazione dettagliata delle istruzioni Dockerfile, consultare la pagina di riferimento ufficiale Dockerfile.
Creare un file Docker
Lo scenario più comune durante la creazione di immagini Docker è estrarre un'immagine esistente da un registro (in genere dall'hub Docker) e specificare le modifiche che si desidera apportare sull'immagine di base. L'immagine di base più comunemente usata durante la creazione di immagini Docker è Alpine perché è piccola e ottimizzata per essere eseguita nella RAM.
Docker Hub è un servizio di registro basato su cloud che, tra le altre funzionalità, viene utilizzato per conservare le immagini Docker in un repository pubblico o privato.
In questo esempio, creeremo un'immagine Docker per il server Redis. Useremo l'ultimo Ubuntu 18.04 come immagine di base.
Innanzitutto, crea una directory che conterrà il file Docker e tutti i file necessari:
mkdir ~/redis_docker
Cambiare directory e creare il seguente Dockerfile:
cd ~/redis_docker
nano Dockerfile
FROM ubuntu:18.04
RUN apt-get update && \
apt-get install -y redis-server && \
apt-get clean
EXPOSE 6379
CMD ["redis-server", "--protected-mode no"]
Spieghiamo il significato di ciascuna delle linee nel Dockerfile:
- In linea
1
stiamo definendo l'immagine di base. - Le istruzioni
RUN
che iniziano in linea3
e aggiorneranno l'indice apt, installeranno il pacchetto "redis-server" e puliranno la cache apt. I comandi usati nelle istruzioni sono gli stessi dei comandi che useresti per installare redis sul server Ubuntu. - L'istruzione
EXPOSE
definisce la porta su cui il server redis è in ascolto. - Nell'ultima riga, stiamo usando le istruzioni
CMD
per impostare il comando predefinito che verrà eseguito quando il contenitore viene eseguito.
Salvare e chiudere il file premendo CTRL+X, seguito da Y per salvare le modifiche e quindi ENTER se stai utilizzando nano.
Costruire (build) l'immagine
Il prossimo passo è costruire l'immagine. Per fare ciò, eseguire il comando seguente dalla directory in cui si trova Dockerfile:
docker build -t noviello/redis .
L'opzione -t
specifica il nome dell'immagine e, facoltativamente, un nome utente e un tag nel formato "nome utente/imagename: tag".
L'output del processo di compilazione sarà simile al seguente:
Sending build context to Docker daemon 3.584kB
Step 1/4 : FROM ubuntu:18.04
---> 7698f282e524
Step 2/4 : RUN apt-get update && apt-get install -y gosu redis-server && apt-get clean
---> Running in e80d4dd69263
...
Removing intermediate container e80d4dd69263
---> e19fb7653fca
Step 3/4 : EXPOSE 6379
---> Running in 8b2a45f457cc
Removing intermediate container 8b2a45f457cc
---> 13b92565c201
Step 4/4 : CMD ["redis-server", "--protected-mode no"]
---> Running in a67ec50c7048
Removing intermediate container a67ec50c7048
---> d8acc14d9b6b
Successfully built d8acc14d9b6b
Successfully tagged noviello/redis:latest
Una volta completato il processo di compilazione, la nuova immagine verrà elencata nell'elenco delle immagini:
docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
noviello/redis latest d8acc14d9b6b 4 minutes ago 100MB
ubuntu 18.04 7698f282e524 5 days ago 69.9MB
Se si desidera inviare l'immagine all'hub Docker, consultare Pushing a Docker container image to Docker Hub.
Eseguire un contenitore
Ora che l'immagine è stata creata, esegui un contenitore eseguendo:
docker run -d -p 6379:6379 --name redis noviello/redis
L'opzione -d
indica a Docker di eseguire il contenitore in modalità separata, l'opzione -p 6379:6379
pubblicherà l'immagine sulla porta 6379 del computer host e l'opzione --name redis
specifica il nome del contenitore. L'ultimo argomento noviello/redis
è il nome dell'immagine che viene utilizzato per eseguire il contenitore.
All'avvio del contenitore, utilizzare il comando seguente per elencare tutti i contenitori in esecuzione:
docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6b7d424cd915 noviello/redis:v0.0.1 "redis-server '--pro…" 5 minutes ago Up 5 minutes 0.0.0.0:6379->6379/tcp redis
Per verificare che tutto funzioni come dovrebbe utilizzare redis-cli
per connettersi al contenitore docker:
redis-cli ping
Il server redis dovrebbe rispondere con PONG
.
Conclusione
Questo tutorial ha trattato solo le basi dell'utilizzo dei Dockerfile per creare immagini. Per ulteriori informazioni su come scrivere Dockerfile e le best practice consigliate, consultare Best practice per la scrittura di Dockerfile.