Docker
Table of Contents
1. Premessa
Introduzione all'utilizzo di docker. La lezione e' tenuta da Alessandro De Filippo.
2. Dizionario
2.1. Docker file
2.1.1. Cos'e'
È il "libretto di istruzioni" che Docker usa per creare immagini riproducibili e portabili si tratta di un file di testo che contiene una serie di istruzioni per costruire un'immagine Docker personalizzata. Definisce:
- L'ambiente di runtime (es. Ubuntu, Python, Node.js).
- I file da copiare nell'immagine.
- I comandi da eseguire durante la costruzione.
- La configurazione del container (es. porte esposte, comando di avvio).
# 1. Scegli l'immagine base FROM python:3.9-slim # 2. Imposta la directory di lavoro WORKDIR /app # 3. Copia i file locali nell'immagine COPY requirements.txt . COPY app.py . # 4. Installa le dipendenze RUN pip install --no-cache-dir -r requirements.txt # 5. Definisci la porta esposta EXPOSE 5000 # 6. Comando di avvio del container CMD ["python", "app.py"]
2.1.2. Relazione istruzione <—> layer
Alcune istruzioni creano dei layer, livelli logici, che possono essere messe in relazioni con path fisici.
---- docker file -------- FROM alpine:3.14 # Layer 1 (Base) RUN apk add --no-cache python3 # Layer 2 COPY script.py /app/ # Layer 3 CMD ["python3", "/app/script.py"] # Metadata ---- EOF ---- Struttura fisica su host (/var/lib/docker/overlay2/): diff/ ├── layer1/ # Contenuto di alpine:3.14 (bin/, etc/, ...) ├── layer2/ # Solo /usr/bin/python3 e dipendenze ├── layer3/ # Solo /app/script.py merged/ # Vista unificata per i container
2.1.3. Comandi piu' comuni
Istruzione Dockerfile | Cosa fa | Crea un layer? | Note |
---|---|---|---|
`FROM` | Specifica l'immagine base | ✅ Sì | È il primo layer dell'immagine. |
`RUN` | Esegue comandi nella shell (es: installazioni) | ✅ Sì | Ogni comando `RUN` crea un layer separato. |
`COPY` / `ADD` | Copia file all'interno dell'immagine | ✅ Sì | Ogni copia è un nuovo layer. |
`CMD` / `ENTRYPOINT` | Imposta il comando predefinito da eseguire nel container | ✅ Sì | Ma è spesso un layer molto leggero. |
`ENV` | Imposta variabili d’ambiente | ✅ Sì | Cambia l’ambiente e quindi crea un nuovo layer. |
`EXPOSE` | Documenta le porte utilizzate | ✅ Sì | Informativo; non ha effetto sulle porte effettivamente aperte. |
`WORKDIR` | Imposta la directory di lavoro | ✅ Sì | Cambia il contesto del layer successivo. |
`USER` | Imposta l’utente per i comandi successivi | ✅ Sì | Utile per sicurezza. |
`LABEL` | Aggiunge metadata all’immagine | ✅ Sì | Utile per tracciabilità. |
2.2. Layer
2.2.1. Cosa sono
I layer di Docker sono un concetto fondamentale nel funzionamento dei container. A livello fisico, corrispondono a file system sovrapposti (overlay) memorizzati sul disco rigido del tuo host. Ecco come funzionano:
FROM ubuntu:22.04 # Layer 1 (Base) COPY app.py /app/ # Layer 2 RUN pip install requests # Layer 3
[LAYER 1] FROM ubuntu:22.04 /var/lib/docker/overlay2/<ID1>/diff/bin/ls /var/lib/docker/overlay2/<ID1>/diff/usr/bin/python3.10 /var/lib/docker/overlay2/<ID1>/diff/usr/lib/python3.10/ /var/lib/docker/overlay2/<ID1>/diff/etc/os-release /var/lib/docker/overlay2/<ID1>/diff/var/lib/dpkg/status [LAYER 2] COPY app.py /app/ /var/lib/docker/overlay2/<ID2>/diff/app/app.py [LAYER 3] RUN pip install requests /var/lib/docker/overlay2/<ID3>/diff/usr/local/lib/python3.10/dist-packages/requests/ /var/lib/docker/overlay2/<ID3>/diff/usr/local/lib/python3.10/dist-packages/requests-*.dist-info/ /var/lib/docker/overlay2/<ID3>/diff/root/.cache/pip/
2.2.2. Merged view
Docker usa un filesystem a livelli (come OverlayFS). Ogni RUN, COPY, ecc. crea un nuovo layer in sola lettura. Quando il container parte, Docker:
- Unisce tutti i layer precedenti in un’unica struttura.
- Aggiunge un layer scrivibile (writable layer) in cima.
- Espone questa combinazione come il file system visibile nel container.
Questa è la cosiddetta "vista merged", che il processo dentro il container vede come un normale file system. Il container non vede i layer separati in quanto
- tutti i diff/ dei layer precedenti (in sola lettura),
- un layer finale scrivibile (dove finiscono le modifiche del container).
Quando avvio un container docker crea un nome fittizzio per il top-layer usando, ad esempio, sia hash SHA256 che nel nostro caso e' ghi789
file system finale merged /var/lib/docker/overlay2/<top-layer>/merged/ per cui se digito, ad esempio il comando: ls /var/lib/docker/overlay2/ghi789/merged/ / ├── app/ │ └── app.py ├── usr/ │ ├── bin/ │ │ └── python3.10 │ └── local/ │ └── lib/ │ └── python3.10/ │ └── dist-packages/ │ └── requests/ └── ...
2.3. Docker Image
Contiene tutto il necessario per eseguire un applicazione. Una volta creata, non cambia. Se serve un aggiornamento, si crea una nuova immagine.
2.3.1. Dove si trovano le immagini?
- Locale: Sul tuo host Docker (docker images)
- Remoto: Su registry come:
- Docker Hub (pubblico)
- Google Container Registry (GCR)
- Amazon ECR
- Azure Container Registry (ACR)
2.3.2. Cosa contiene un'immagine?
Esempio per python:3.11-slim-bookworm:
- OS Debian Bookworm minimale
- Interprete Python 3.11 preinstallato
- Librerie essenziali (es. libc6, SSL)
- Percorsi standard (/usr/lib, /bin, /app)
2.3.3. Comandi utili
docker run -it ubuntu bash # se non installata scarica e avvia in modo interattivo (-it ) la bash di ubuntu docker images # Lista immagini locali docker inspect nginx:alpine # Mostra dettagli tecnici docker history nginx:alpine # Mostra i layer dell'immagine docker rmi mia-immagine # Elimina un'immagine locale docker pull nginx:alpine # Immagine web server (solo 40MB) docker pull python:3.11-slim-bookworm # Immagine Python ottimizzata docker ps -a # elenca gli id dei container
Esempio di file di output
"GraphDriver": { "Data": { "UpperDir": "/var/lib/docker/overlay2/3e3a4ff99e5c1c35bfffb21ea8d3b8768450983a7d119a159db4732e0f59d1bc/diff", "MergedDir": "/var/lib/docker/overlay2/3e3a4ff99e5c1c35bfffb21ea8d3b8768450983a7d119a159db4732e0f59d1bc/merged", ... }, "Name": "overlay2" }
2.4. Docker Compose
Uno degli orchestratori possibili di vari container, ad esempio puo' impostare una tabela di routing per far comunicare alcuni container.