Docker
Docker raccoglie codice, librerie e pesi dei modelli in immagini container che funzionano allo stesso modo su laptop, server GPU, runner CI e dispositivi edge.
Docker è una piattaforma open source per creare, condividere ed eseguire applicazioni in container: processi isolati che includono il proprio filesystem con codice, librerie e pacchetti di sistema, pur condividendo il kernel del sistema operativo host. dotCloud, l'azienda che in seguito ha cambiato nome in Docker, Inc., ne ha rilasciato il codice sorgente nel marzo 2013; il suo strumento a riga di comando, il formato di immagini a livelli e il registro pubblico hanno reso i container Linux uno strumento di uso quotidiano per gli sviluppatori. Nel machine learning, un'immagine Docker fissa la versione esatta di Python, le librerie CUDA, la build di PyTorch e i pesi del modello, così un modello si comporta allo stesso modo su un laptop, un server GPU, un runner di integrazione continua e un dispositivo edge.
Come funziona Docker#
Un Dockerfile elenca i passaggi per creare un'immagine: un'immagine di base da cui partire, i comandi per installare i pacchetti, i file da copiare e il comando da eseguire all'avvio. Ogni istruzione RUN, COPY o ADD aggiunge un livello di sola lettura; nelle build successive, i livelli memorizzati nella cache vengono riutilizzati finché un'istruzione o uno dei suoi file di input non cambia, quindi le dipendenze installate all'inizio restano in cache mentre il codice dell'applicazione viene ricompilato in pochi secondi. Un'immagine è l'insieme di questi livelli e dei relativi metadati. Un container è un'istanza in esecuzione di un'immagine con un sottile livello scrivibile in cima, che viene eliminato insieme al container a meno che i dati non siano salvati in un volume montato.
Il comando docker comunica con Docker Engine, un daemon in background che affida ogni container a containerd e al runtime di basso livello runc. Questi usano i namespace Linux per isolare i processi, la rete e il filesystem di un container, e i cgroups per limitarne CPU e memoria. Le immagini vengono condivise tramite registri come Docker Hub, GitHub Container Registry, NVIDIA NGC e il registro di ciascun provider cloud. Seguono il formato per le immagini della Open Container Initiative, quindi Podman, containerd e Kubernetes le eseguono senza modifiche.
Ultralytics pubblica immagini Docker ufficiali per ogni destinazione hardware, tra cui GPU CUDA, CPU, schede ARM64, dispositivi NVIDIA Jetson e GPU AMD, ciascuna contrassegnata anche con il numero di versione di Ultralytics per garantire build riproducibili. La leggera immagine latest-python usata di seguito contiene già Python, PyTorch, il pacchetto ultralytics e i pesi nano di YOLO26, quindi il Dockerfile di un progetto deve aggiungere solo il codice specifico:
# Official Ultralytics CPU image with Python, PyTorch, ultralytics, and yolo26n.pt
FROM ultralytics/ultralytics:latest-python
# Install extra dependencies in their own layer, cached until requirements.txt changes
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Copy the application last, so code edits rebuild only this layer
COPY app.py .
# Command every container runs when it starts
CMD ["python", "app.py"]docker build -t yolo-app . trasforma questo file e i file che si trovano accanto in un'immagine, mentre docker run --rm yolo-app avvia un container basato su di essa. Pubblicando l'immagine su un registro, qualsiasi altro computer può scaricare ed eseguire lo stesso identico ambiente, ad esempio come API di distribuzione di modelli o come job notturno di inferenza.
Docker per il machine learning#
I container accedono alle GPU tramite NVIDIA Container Toolkit. Il driver NVIDIA rimane sull'host e l'immagine contiene solo le librerie CUDA dello spazio utente, che devono essere supportate dal driver. Su Linux, Docker 28.2 e versioni successive abilitano CDI per impostazione predefinita, quindi --device nvidia.com/gpu=all richiede le GPU come dispositivi CDI e mantiene l'accesso alle GPU nei container a esecuzione prolungata, accesso che il flag precedente --gpus all può perdere quando l'host ricarica systemd.
Per l'addestramento sono importanti anche altre due impostazioni. I worker del data loader di PyTorch passano i batch al processo di training tramite la memoria condivisa in /dev/shm, che Docker limita a 64 MB per impostazione predefinita; per questo, i container di training vengono eseguiti con --ipc=host o con un valore --shm-size più alto. I dataset e gli output vanno salvati in volumi montati, perché un'esecuzione di training che scrive i checkpoint all'interno del container li perde quando il container viene rimosso. Fissare un tag di versione o il digest dell'immagine invece di latest mantiene un job di addestramento distribuito o una distribuzione del modello sulla stessa immagine su tutti i computer; sia i server di inferenza come NVIDIA Triton Inference Server sia i servizi gestiti come Vertex AI eseguono i modelli come immagini container.
Docker a confronto con macchine virtuali e Kubernetes#
- Macchine virtuali: Un hypervisor emula l'hardware e ogni VM avvia il proprio kernel guest, isolando i workload in modo più rigoroso e consentendo l'uso di qualsiasi sistema operativo guest, a costo di un'immagine completa del sistema operativo per ogni VM e di un avvio più lento. Poiché i container condividono il kernel Linux dell'host, Docker Desktop su macOS e Windows li esegue all'interno di una VM Linux leggera.
- Docker Compose: Definisce più container da eseguire insieme su un host, ad esempio un'API di inferenza, una cache e un raccoglitore di metriche.
- Kubernetes: Pianifica i container su un cluster, riavvia quelli che si arrestano in modo anomalo e adatta il numero di repliche al traffico. Kubernetes 1.24 ha rimosso dockershim, il suo adattatore integrato per Docker Engine, quindi i cluster eseguono i container tramite containerd o CRI-O; le immagini create con Docker continuano comunque a funzionare perché sono immagini OCI standard.










